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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [gdbserver/] [event-loop.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Event loop machinery for the remote server for GDB.
2
   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2008, 2010
3
   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
/* Based on src/gdb/event-loop.c.  */
21
 
22
#include "server.h"
23
 
24
#include <sys/types.h>
25
#include <string.h>
26
#include <sys/time.h>
27
 
28
#ifdef USE_WIN32API
29
#include <windows.h>
30
#include <io.h>
31
#endif
32
 
33
#ifdef HAVE_ERRNO_H
34
#include <errno.h>
35
#endif
36
 
37
#ifdef HAVE_UNISTD_H
38
#include <unistd.h>
39
#endif
40
 
41
typedef struct gdb_event gdb_event;
42
typedef void (event_handler_func) (int);
43
 
44
/* Tell create_file_handler what events we are interested in.  */
45
 
46
#define GDB_READABLE    (1<<1)
47
#define GDB_WRITABLE    (1<<2)
48
#define GDB_EXCEPTION   (1<<3)
49
 
50
/* Events are queued by calling async_queue_event and serviced later
51
   on by do_one_event.  An event can be, for instance, a file
52
   descriptor becoming ready to be read.  Servicing an event simply
53
   means that the procedure PROC will be called.  We have 2 queues,
54
   one for file handlers that we listen to in the event loop, and one
55
   for the file handlers+events that are ready.  The procedure PROC
56
   associated with each event is always the same (handle_file_event).
57
   Its duty is to invoke the handler associated with the file
58
   descriptor whose state change generated the event, plus doing other
59
   cleanups and such.  */
60
 
61
struct gdb_event
62
  {
63
    /* Procedure to call to service this event.  */
64
    event_handler_func *proc;
65
 
66
    /* File descriptor that is ready.  */
67
    int fd;
68
 
69
    /* Next in list of events or NULL.  */
70
    struct gdb_event *next_event;
71
  };
72
 
73
/* Information about each file descriptor we register with the event
74
   loop.  */
75
 
76
typedef struct file_handler
77
  {
78
    /* File descriptor.  */
79
    int fd;
80
 
81
    /* Events we want to monitor.  */
82
    int mask;
83
 
84
    /* Events that have been seen since the last time.  */
85
    int ready_mask;
86
 
87
    /* Procedure to call when fd is ready.  */
88
    handler_func *proc;
89
 
90
    /* Argument to pass to proc.  */
91
    gdb_client_data client_data;
92
 
93
    /* Was an error detected on this fd?  */
94
    int error;
95
 
96
    /* Next registered file descriptor.  */
97
    struct file_handler *next_file;
98
  }
99
file_handler;
100
 
101
/* Event queue:
102
 
103
   Events can be inserted at the front of the queue or at the end of
104
   the queue.  Events will be extracted from the queue for processing
105
   starting from the head.  Therefore, events inserted at the head of
106
   the queue will be processed in a last in first out fashion, while
107
   those inserted at the tail of the queue will be processed in a
108
   first in first out manner.  All the fields are NULL if the queue is
109
   empty.  */
110
 
111
static struct
112
  {
113
    /* The first pending event.  */
114
    gdb_event *first_event;
115
 
116
    /* The last pending event.  */
117
    gdb_event *last_event;
118
  }
119
event_queue;
120
 
121
/* Gdb_notifier is just a list of file descriptors gdb is interested
122
   in.  These are the input file descriptor, and the target file
123
   descriptor.  Each of the elements in the gdb_notifier list is
124
   basically a description of what kind of events gdb is interested
125
   in, for each fd.  */
126
 
127
static struct
128
  {
129
    /* Ptr to head of file handler list.  */
130
    file_handler *first_file_handler;
131
 
132
    /* Masks to be used in the next call to select.  Bits are set in
133
       response to calls to create_file_handler.  */
134
    fd_set check_masks[3];
135
 
136
    /* What file descriptors were found ready by select.  */
137
    fd_set ready_masks[3];
138
 
139
    /* Number of valid bits (highest fd value + 1). (for select) */
140
    int num_fds;
141
  }
142
gdb_notifier;
143
 
144
/* Insert an event object into the gdb event queue.
145
 
146
   EVENT_PTR points to the event to be inserted into the queue.  The
147
   caller must allocate memory for the event.  It is freed after the
148
   event has ben handled.  Events in the queue will be processed head
149
   to tail, therefore, events will be processed first in first
150
   out.  */
151
 
152
static void
153
async_queue_event (gdb_event *event_ptr)
154
{
155
  /* The event will become the new last_event.  */
156
 
157
  event_ptr->next_event = NULL;
158
  if (event_queue.first_event == NULL)
159
    event_queue.first_event = event_ptr;
160
  else
161
    event_queue.last_event->next_event = event_ptr;
162
  event_queue.last_event = event_ptr;
163
}
164
 
165
/* Process one event.  If an event was processed, 1 is returned
166
   otherwise 0 is returned.  Scan the queue from head to tail,
167
   processing therefore the high priority events first, by invoking
168
   the associated event handler procedure.  */
169
 
170
static int
171
process_event (void)
172
{
173
  gdb_event *event_ptr, *prev_ptr;
174
  event_handler_func *proc;
175
  int fd;
176
 
177
  /* Look in the event queue to find an event that is ready
178
     to be processed.  */
179
 
180
  for (event_ptr = event_queue.first_event;
181
       event_ptr != NULL;
182
       event_ptr = event_ptr->next_event)
183
    {
184
      /* Call the handler for the event.  */
185
 
186
      proc = event_ptr->proc;
187
      fd = event_ptr->fd;
188
 
189
      /* Let's get rid of the event from the event queue.  We need to
190
         do this now because while processing the event, since the
191
         proc function could end up jumping out to the caller of this
192
         function.  In that case, we would have on the event queue an
193
         event which has been processed, but not deleted.  */
194
 
195
      if (event_queue.first_event == event_ptr)
196
        {
197
          event_queue.first_event = event_ptr->next_event;
198
          if (event_ptr->next_event == NULL)
199
            event_queue.last_event = NULL;
200
        }
201
      else
202
        {
203
          prev_ptr = event_queue.first_event;
204
          while (prev_ptr->next_event != event_ptr)
205
            prev_ptr = prev_ptr->next_event;
206
 
207
          prev_ptr->next_event = event_ptr->next_event;
208
          if (event_ptr->next_event == NULL)
209
            event_queue.last_event = prev_ptr;
210
        }
211
      free (event_ptr);
212
 
213
      /* Now call the procedure associated with the event.  */
214
      (*proc) (fd);
215
      return 1;
216
    }
217
 
218
  /* This is the case if there are no event on the event queue.  */
219
  return 0;
220
}
221
 
222
/* Add a file handler/descriptor to the list of descriptors we are
223
   interested in.  FD is the file descriptor for the file/stream to be
224
   listened to.  MASK is a combination of READABLE, WRITABLE,
225
   EXCEPTION.  PROC is the procedure that will be called when an event
226
   occurs for FD.  CLIENT_DATA is the argument to pass to PROC.  */
227
 
228
static void
229
create_file_handler (int fd, int mask, handler_func *proc,
230
                     gdb_client_data client_data)
231
{
232
  file_handler *file_ptr;
233
 
234
  /* Do we already have a file handler for this file? (We may be
235
     changing its associated procedure).  */
236
  for (file_ptr = gdb_notifier.first_file_handler;
237
       file_ptr != NULL;
238
       file_ptr = file_ptr->next_file)
239
    if (file_ptr->fd == fd)
240
      break;
241
 
242
  /* It is a new file descriptor.  Add it to the list.  Otherwise,
243
     just change the data associated with it.  */
244
  if (file_ptr == NULL)
245
    {
246
      file_ptr = xmalloc (sizeof (*file_ptr));
247
      file_ptr->fd = fd;
248
      file_ptr->ready_mask = 0;
249
      file_ptr->next_file = gdb_notifier.first_file_handler;
250
      gdb_notifier.first_file_handler = file_ptr;
251
 
252
      if (mask & GDB_READABLE)
253
        FD_SET (fd, &gdb_notifier.check_masks[0]);
254
      else
255
        FD_CLR (fd, &gdb_notifier.check_masks[0]);
256
 
257
      if (mask & GDB_WRITABLE)
258
        FD_SET (fd, &gdb_notifier.check_masks[1]);
259
      else
260
        FD_CLR (fd, &gdb_notifier.check_masks[1]);
261
 
262
      if (mask & GDB_EXCEPTION)
263
        FD_SET (fd, &gdb_notifier.check_masks[2]);
264
      else
265
        FD_CLR (fd, &gdb_notifier.check_masks[2]);
266
 
267
      if (gdb_notifier.num_fds <= fd)
268
        gdb_notifier.num_fds = fd + 1;
269
    }
270
 
271
  file_ptr->proc = proc;
272
  file_ptr->client_data = client_data;
273
  file_ptr->mask = mask;
274
}
275
 
276
/* Wrapper function for create_file_handler.  */
277
 
278
void
279
add_file_handler (int fd, handler_func *proc, gdb_client_data client_data)
280
{
281
  create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
282
}
283
 
284
/* Remove the file descriptor FD from the list of monitored fd's:
285
   i.e. we don't care anymore about events on the FD.  */
286
 
287
void
288
delete_file_handler (int fd)
289
{
290
  file_handler *file_ptr, *prev_ptr = NULL;
291
  int i;
292
 
293
  /* Find the entry for the given file. */
294
 
295
  for (file_ptr = gdb_notifier.first_file_handler;
296
       file_ptr != NULL;
297
       file_ptr = file_ptr->next_file)
298
    if (file_ptr->fd == fd)
299
      break;
300
 
301
  if (file_ptr == NULL)
302
    return;
303
 
304
  if (file_ptr->mask & GDB_READABLE)
305
    FD_CLR (fd, &gdb_notifier.check_masks[0]);
306
  if (file_ptr->mask & GDB_WRITABLE)
307
    FD_CLR (fd, &gdb_notifier.check_masks[1]);
308
  if (file_ptr->mask & GDB_EXCEPTION)
309
    FD_CLR (fd, &gdb_notifier.check_masks[2]);
310
 
311
  /* Find current max fd.  */
312
 
313
  if ((fd + 1) == gdb_notifier.num_fds)
314
    {
315
      gdb_notifier.num_fds--;
316
      for (i = gdb_notifier.num_fds; i; i--)
317
        {
318
          if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
319
              || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
320
              || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
321
            break;
322
        }
323
      gdb_notifier.num_fds = i;
324
    }
325
 
326
  /* Deactivate the file descriptor, by clearing its mask, so that it
327
     will not fire again.  */
328
 
329
  file_ptr->mask = 0;
330
 
331
  /* Get rid of the file handler in the file handler list.  */
332
  if (file_ptr == gdb_notifier.first_file_handler)
333
    gdb_notifier.first_file_handler = file_ptr->next_file;
334
  else
335
    {
336
      for (prev_ptr = gdb_notifier.first_file_handler;
337
           prev_ptr->next_file != file_ptr;
338
           prev_ptr = prev_ptr->next_file)
339
        ;
340
      prev_ptr->next_file = file_ptr->next_file;
341
    }
342
  free (file_ptr);
343
}
344
 
345
/* Handle the given event by calling the procedure associated to the
346
   corresponding file handler.  Called by process_event indirectly,
347
   through event_ptr->proc.  EVENT_FILE_DESC is file descriptor of the
348
   event in the front of the event queue.  */
349
 
350
static void
351
handle_file_event (int event_file_desc)
352
{
353
  file_handler *file_ptr;
354
  int mask;
355
 
356
  /* Search the file handler list to find one that matches the fd in
357
     the event.  */
358
  for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
359
       file_ptr = file_ptr->next_file)
360
    {
361
      if (file_ptr->fd == event_file_desc)
362
        {
363
          /* See if the desired events (mask) match the received
364
             events (ready_mask).  */
365
 
366
          if (file_ptr->ready_mask & GDB_EXCEPTION)
367
            {
368
              fprintf (stderr, "Exception condition detected on fd %d\n",
369
                       file_ptr->fd);
370
              file_ptr->error = 1;
371
            }
372
          else
373
            file_ptr->error = 0;
374
          mask = file_ptr->ready_mask & file_ptr->mask;
375
 
376
          /* Clear the received events for next time around.  */
377
          file_ptr->ready_mask = 0;
378
 
379
          /* If there was a match, then call the handler.  */
380
          if (mask != 0)
381
            (*file_ptr->proc) (file_ptr->error, file_ptr->client_data);
382
          break;
383
        }
384
    }
385
}
386
 
387
/* Create a file event, to be enqueued in the event queue for
388
   processing.  The procedure associated to this event is always
389
   handle_file_event, which will in turn invoke the one that was
390
   associated to FD when it was registered with the event loop.  */
391
 
392
static gdb_event *
393
create_file_event (int fd)
394
{
395
  gdb_event *file_event_ptr;
396
 
397
  file_event_ptr = xmalloc (sizeof (gdb_event));
398
  file_event_ptr->proc = handle_file_event;
399
  file_event_ptr->fd = fd;
400
  return file_event_ptr;
401
}
402
 
403
/* Called by do_one_event to wait for new events on the monitored file
404
   descriptors.  Queue file events as they are detected by the poll.
405
   If there are no events, this function will block in the call to
406
   select.  Return -1 if there are no files descriptors to monitor,
407
   otherwise return 0.  */
408
 
409
static int
410
wait_for_event (void)
411
{
412
  file_handler *file_ptr;
413
  gdb_event *file_event_ptr;
414
  int num_found = 0;
415
 
416
  /* Make sure all output is done before getting another event.  */
417
  fflush (stdout);
418
  fflush (stderr);
419
 
420
  if (gdb_notifier.num_fds == 0)
421
    return -1;
422
 
423
  gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
424
  gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
425
  gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
426
  num_found = select (gdb_notifier.num_fds,
427
                      &gdb_notifier.ready_masks[0],
428
                      &gdb_notifier.ready_masks[1],
429
                      &gdb_notifier.ready_masks[2],
430
                      NULL);
431
 
432
  /* Clear the masks after an error from select.  */
433
  if (num_found == -1)
434
    {
435
      FD_ZERO (&gdb_notifier.ready_masks[0]);
436
      FD_ZERO (&gdb_notifier.ready_masks[1]);
437
      FD_ZERO (&gdb_notifier.ready_masks[2]);
438
#ifdef EINTR
439
      /* Dont print anything if we got a signal, let gdb handle
440
         it.  */
441
      if (errno != EINTR)
442
        perror_with_name ("select");
443
#endif
444
    }
445
 
446
  /* Enqueue all detected file events.  */
447
 
448
  for (file_ptr = gdb_notifier.first_file_handler;
449
       file_ptr != NULL && num_found > 0;
450
       file_ptr = file_ptr->next_file)
451
    {
452
      int mask = 0;
453
 
454
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
455
        mask |= GDB_READABLE;
456
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
457
        mask |= GDB_WRITABLE;
458
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
459
        mask |= GDB_EXCEPTION;
460
 
461
      if (!mask)
462
        continue;
463
      else
464
        num_found--;
465
 
466
      /* Enqueue an event only if this is still a new event for this
467
         fd.  */
468
 
469
      if (file_ptr->ready_mask == 0)
470
        {
471
          file_event_ptr = create_file_event (file_ptr->fd);
472
          async_queue_event (file_event_ptr);
473
        }
474
      file_ptr->ready_mask = mask;
475
    }
476
 
477
  return 0;
478
}
479
 
480
/* Start up the event loop.  This is the entry point to the event
481
   loop.  */
482
 
483
void
484
start_event_loop (void)
485
{
486
  /* Loop until there is nothing to do.  This is the entry point to
487
     the event loop engine.  If nothing is ready at this time, wait
488
     for something to happen (via wait_for_event), then process it.
489
     Return when there are no longer event sources to wait for.  */
490
 
491
  while (1)
492
    {
493
      /* Any events already waiting in the queue?  */
494
      if (process_event ())
495
        continue;
496
 
497
      /* Wait for a new event.  If wait_for_event returns -1, we
498
         should get out because this means that there are no event
499
         sources left.  This will make the event loop stop, and the
500
         application exit.  */
501
 
502
      if (wait_for_event () < 0)
503
        return;
504
    }
505
 
506
  /* We are done with the event loop.  There are no more event sources
507
     to listen to.  So we exit gdbserver.  */
508
}

powered by: WebSVN 2.1.0

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