OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [mingw-hdep.c] - Blame information for rev 280

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Host support routines for MinGW, for GDB, the GNU debugger.
2
 
3
   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "serial.h"
22
#include "event-loop.h"
23
 
24
#include "gdb_assert.h"
25
#include "gdb_select.h"
26
#include "gdb_string.h"
27
#include "readline/readline.h"
28
 
29
#include <windows.h>
30
 
31
/* This event is signalled whenever an asynchronous SIGINT handler
32
   needs to perform an action in the main thread.  */
33
static HANDLE sigint_event;
34
 
35
/* When SIGINT_EVENT is signalled, gdb_select will call this
36
   function.  */
37
struct async_signal_handler *sigint_handler;
38
 
39
/* The strerror() function can return NULL for errno values that are
40
   out of range.  Provide a "safe" version that always returns a
41
   printable string.
42
 
43
   The Windows runtime implementation of strerror never returns NULL,
44
   but does return a useless string for anything above sys_nerr;
45
   unfortunately this includes all socket-related error codes.
46
   This replacement tries to find a system-provided error message.  */
47
 
48
char *
49
safe_strerror (int errnum)
50
{
51
  static char *buffer;
52
  int len;
53
 
54
  if (errnum >= 0 && errnum < sys_nerr)
55
    return strerror (errnum);
56
 
57
  if (buffer)
58
    {
59
      LocalFree (buffer);
60
      buffer = NULL;
61
    }
62
 
63
  if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
64
                     | FORMAT_MESSAGE_FROM_SYSTEM,
65
                     NULL, errnum,
66
                     MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
67
                     (LPTSTR) &buffer, 0, NULL) == 0)
68
    {
69
      static char buf[32];
70
      xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
71
      return buf;
72
    }
73
 
74
  /* Windows error messages end with a period and a CR-LF; strip that
75
     out.  */
76
  len = strlen (buffer);
77
  if (len > 3 && strcmp (buffer + len - 3, ".\r\n") == 0)
78
    buffer[len - 3] = '\0';
79
 
80
  return buffer;
81
}
82
 
83
/* Wrapper for select.  On Windows systems, where the select interface
84
   only works for sockets, this uses the GDB serial abstraction to
85
   handle sockets, consoles, pipes, and serial ports.
86
 
87
   The arguments to this function are the same as the traditional
88
   arguments to select on POSIX platforms.  */
89
 
90
int
91
gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
92
            struct timeval *timeout)
93
{
94
  static HANDLE never_handle;
95
  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
96
  HANDLE h;
97
  DWORD event;
98
  DWORD num_handles;
99
  /* SCBS contains serial control objects corresponding to file
100
     descriptors in READFDS and WRITEFDS.  */
101
  struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
102
  /* The number of valid entries in SCBS.  */
103
  size_t num_scbs;
104
  int fd;
105
  int num_ready;
106
  size_t indx;
107
 
108
  num_ready = 0;
109
  num_handles = 0;
110
  num_scbs = 0;
111
  for (fd = 0; fd < n; ++fd)
112
    {
113
      HANDLE read = NULL, except = NULL;
114
      struct serial *scb;
115
 
116
      /* There is no support yet for WRITEFDS.  At present, this isn't
117
         used by GDB -- but we do not want to silently ignore WRITEFDS
118
         if something starts using it.  */
119
      gdb_assert (!writefds || !FD_ISSET (fd, writefds));
120
 
121
      if ((!readfds || !FD_ISSET (fd, readfds))
122
          && (!exceptfds || !FD_ISSET (fd, exceptfds)))
123
        continue;
124
 
125
      scb = serial_for_fd (fd);
126
      if (scb)
127
        {
128
          serial_wait_handle (scb, &read, &except);
129
          scbs[num_scbs++] = scb;
130
        }
131
 
132
      if (read == NULL)
133
        read = (HANDLE) _get_osfhandle (fd);
134
      if (except == NULL)
135
        {
136
          if (!never_handle)
137
            never_handle = CreateEvent (0, FALSE, FALSE, 0);
138
 
139
          except = never_handle;
140
        }
141
 
142
      if (readfds && FD_ISSET (fd, readfds))
143
        {
144
          gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
145
          handles[num_handles++] = read;
146
        }
147
 
148
      if (exceptfds && FD_ISSET (fd, exceptfds))
149
        {
150
          gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
151
          handles[num_handles++] = except;
152
        }
153
    }
154
 
155
  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
156
  handles[num_handles++] = sigint_event;
157
 
158
  event = WaitForMultipleObjects (num_handles,
159
                                  handles,
160
                                  FALSE,
161
                                  timeout
162
                                  ? (timeout->tv_sec * 1000
163
                                     + timeout->tv_usec / 1000)
164
                                  : INFINITE);
165
  /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
166
     HANDLES included an abandoned mutex.  Since GDB doesn't use
167
     mutexes, that should never occur.  */
168
  gdb_assert (!(WAIT_ABANDONED_0 <= event
169
                && event < WAIT_ABANDONED_0 + num_handles));
170
  /* We no longer need the helper threads to check for activity.  */
171
  for (indx = 0; indx < num_scbs; ++indx)
172
    serial_done_wait_handle (scbs[indx]);
173
  if (event == WAIT_FAILED)
174
    return -1;
175
  if (event == WAIT_TIMEOUT)
176
    return 0;
177
  /* Run through the READFDS, clearing bits corresponding to descriptors
178
     for which input is unavailable.  */
179
  h = handles[event - WAIT_OBJECT_0];
180
  for (fd = 0, indx = 0; fd < n; ++fd)
181
    {
182
      HANDLE fd_h;
183
 
184
      if ((!readfds || !FD_ISSET (fd, readfds))
185
          && (!exceptfds || !FD_ISSET (fd, exceptfds)))
186
        continue;
187
 
188
      if (readfds && FD_ISSET (fd, readfds))
189
        {
190
          fd_h = handles[indx++];
191
          /* This handle might be ready, even though it wasn't the handle
192
             returned by WaitForMultipleObjects.  */
193
          if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
194
            FD_CLR (fd, readfds);
195
          else
196
            num_ready++;
197
        }
198
 
199
      if (exceptfds && FD_ISSET (fd, exceptfds))
200
        {
201
          fd_h = handles[indx++];
202
          /* This handle might be ready, even though it wasn't the handle
203
             returned by WaitForMultipleObjects.  */
204
          if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
205
            FD_CLR (fd, exceptfds);
206
          else
207
            num_ready++;
208
        }
209
    }
210
 
211
  /* With multi-threaded SIGINT handling, there is a race between the
212
     readline signal handler and GDB.  It may still be in
213
     rl_prep_terminal in another thread.  Do not return until it is
214
     done; we can check the state here because we never longjmp from
215
     signal handlers on Windows.  */
216
  while (RL_ISSTATE (RL_STATE_SIGHANDLER))
217
    Sleep (1);
218
 
219
  if (h == sigint_event
220
      || WaitForSingleObject (sigint_event, 0) == WAIT_OBJECT_0)
221
    {
222
      if (sigint_handler != NULL)
223
        call_async_signal_handler (sigint_handler);
224
 
225
      if (num_ready == 0)
226
        {
227
          errno = EINTR;
228
          return -1;
229
        }
230
    }
231
 
232
  return num_ready;
233
}
234
 
235
/* Wrapper for the body of signal handlers.  On Windows systems, a
236
   SIGINT handler runs in its own thread.  We can't longjmp from
237
   there, and we shouldn't even prompt the user.  Delay HANDLER
238
   until the main thread is next in gdb_select.  */
239
 
240
void
241
gdb_call_async_signal_handler (struct async_signal_handler *handler,
242
                               int immediate_p)
243
{
244
  if (immediate_p)
245
    sigint_handler = handler;
246
  else
247
    {
248
      mark_async_signal_handler (handler);
249
      sigint_handler = NULL;
250
    }
251
  SetEvent (sigint_event);
252
}
253
 
254
void
255
_initialize_mingw_hdep (void)
256
{
257
  sigint_event = CreateEvent (0, FALSE, FALSE, 0);
258
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.