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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [gdbserver/] [event-loop.c] - Blame information for rev 330

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 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 int (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
/* Callbacks are just routines that are executed before waiting for the
145
   next event.  In GDB this is struct gdb_timer.  We don't need timers
146
   so rather than copy all that complexity in gdbserver, we provide what
147
   we need, but we do so in a way that if/when the day comes that we need
148
   that complexity, it'll be easier to add - replace callbacks with timers
149
   and use a delta of zero (which is all gdb currently uses timers for anyway).
150
 
151
   PROC will be executed before gdbserver goes to sleep to wait for the
152
   next event.  */
153
 
154
struct callback_event
155
  {
156
    int id;
157
    callback_handler_func *proc;
158
    gdb_client_data *data;
159
    struct callback_event *next;
160
  };
161
 
162
/* Table of registered callbacks.  */
163
 
164
static struct
165
  {
166
    struct callback_event *first;
167
    struct callback_event *last;
168
 
169
    /* Id of the last callback created.  */
170
    int num_callbacks;
171
  }
172
callback_list;
173
 
174
/* Insert an event object into the gdb event queue.
175
 
176
   EVENT_PTR points to the event to be inserted into the queue.  The
177
   caller must allocate memory for the event.  It is freed after the
178
   event has ben handled.  Events in the queue will be processed head
179
   to tail, therefore, events will be processed first in first
180
   out.  */
181
 
182
static void
183
async_queue_event (gdb_event *event_ptr)
184
{
185
  /* The event will become the new last_event.  */
186
 
187
  event_ptr->next_event = NULL;
188
  if (event_queue.first_event == NULL)
189
    event_queue.first_event = event_ptr;
190
  else
191
    event_queue.last_event->next_event = event_ptr;
192
  event_queue.last_event = event_ptr;
193
}
194
 
195
/* Process one event.  If an event was processed, 1 is returned
196
   otherwise 0 is returned.  Scan the queue from head to tail,
197
   processing therefore the high priority events first, by invoking
198
   the associated event handler procedure.  */
199
 
200
static int
201
process_event (void)
202
{
203
  gdb_event *event_ptr, *prev_ptr;
204
  event_handler_func *proc;
205
  int fd;
206
 
207
  /* Look in the event queue to find an event that is ready
208
     to be processed.  */
209
 
210
  for (event_ptr = event_queue.first_event;
211
       event_ptr != NULL;
212
       event_ptr = event_ptr->next_event)
213
    {
214
      /* Call the handler for the event.  */
215
 
216
      proc = event_ptr->proc;
217
      fd = event_ptr->fd;
218
 
219
      /* Let's get rid of the event from the event queue.  We need to
220
         do this now because while processing the event, since the
221
         proc function could end up jumping out to the caller of this
222
         function.  In that case, we would have on the event queue an
223
         event which has been processed, but not deleted.  */
224
 
225
      if (event_queue.first_event == event_ptr)
226
        {
227
          event_queue.first_event = event_ptr->next_event;
228
          if (event_ptr->next_event == NULL)
229
            event_queue.last_event = NULL;
230
        }
231
      else
232
        {
233
          prev_ptr = event_queue.first_event;
234
          while (prev_ptr->next_event != event_ptr)
235
            prev_ptr = prev_ptr->next_event;
236
 
237
          prev_ptr->next_event = event_ptr->next_event;
238
          if (event_ptr->next_event == NULL)
239
            event_queue.last_event = prev_ptr;
240
        }
241
      free (event_ptr);
242
 
243
      /* Now call the procedure associated with the event.  */
244
      if ((*proc) (fd))
245
        return -1;
246
      return 1;
247
    }
248
 
249
  /* This is the case if there are no event on the event queue.  */
250
  return 0;
251
}
252
 
253
/* Append PROC to the callback list.
254
   The result is the "id" of the callback that can be passed back to
255
   delete_callback_event.  */
256
 
257
int
258
append_callback_event (callback_handler_func *proc, gdb_client_data data)
259
{
260
  struct callback_event *event_ptr;
261
 
262
  event_ptr = xmalloc (sizeof (*event_ptr));
263
  event_ptr->id = callback_list.num_callbacks++;
264
  event_ptr->proc = proc;
265
  event_ptr->data = data;
266
  event_ptr->next = NULL;
267
  if (callback_list.first == NULL)
268
    callback_list.first = event_ptr;
269
  if (callback_list.last != NULL)
270
    callback_list.last->next = event_ptr;
271
  callback_list.last = event_ptr;
272
  return event_ptr->id;
273
}
274
 
275
/* Delete callback ID.
276
   It is not an error callback ID doesn't exist.  */
277
 
278
void
279
delete_callback_event (int id)
280
{
281
  struct callback_event **p;
282
 
283
  for (p = &callback_list.first; *p != NULL; p = &(*p)->next)
284
    {
285
      struct callback_event *event_ptr = *p;
286
 
287
      if (event_ptr->id == id)
288
        {
289
          *p = event_ptr->next;
290
          if (event_ptr == callback_list.last)
291
            callback_list.last = NULL;
292
          free (event_ptr);
293
          break;
294
        }
295
    }
296
}
297
 
298
/* Run the next callback.
299
   The result is 1 if a callback was called and event processing
300
   should continue, -1 if the callback wants the event loop to exit,
301
   and 0 if there are no more callbacks.  */
302
 
303
static int
304
process_callback (void)
305
{
306
  struct callback_event *event_ptr;
307
 
308
  event_ptr = callback_list.first;
309
  if (event_ptr != NULL)
310
    {
311
      callback_handler_func *proc = event_ptr->proc;
312
      gdb_client_data *data = event_ptr->data;
313
 
314
      /* Remove the event before calling PROC,
315
         more events may get added by PROC.  */
316
      callback_list.first = event_ptr->next;
317
      if (callback_list.first == NULL)
318
        callback_list.last = NULL;
319
      free  (event_ptr);
320
      if ((*proc) (data))
321
        return -1;
322
      return 1;
323
    }
324
 
325
  return 0;
326
}
327
 
328
/* Add a file handler/descriptor to the list of descriptors we are
329
   interested in.  FD is the file descriptor for the file/stream to be
330
   listened to.  MASK is a combination of READABLE, WRITABLE,
331
   EXCEPTION.  PROC is the procedure that will be called when an event
332
   occurs for FD.  CLIENT_DATA is the argument to pass to PROC.  */
333
 
334
static void
335
create_file_handler (int fd, int mask, handler_func *proc,
336
                     gdb_client_data client_data)
337
{
338
  file_handler *file_ptr;
339
 
340
  /* Do we already have a file handler for this file? (We may be
341
     changing its associated procedure).  */
342
  for (file_ptr = gdb_notifier.first_file_handler;
343
       file_ptr != NULL;
344
       file_ptr = file_ptr->next_file)
345
    if (file_ptr->fd == fd)
346
      break;
347
 
348
  /* It is a new file descriptor.  Add it to the list.  Otherwise,
349
     just change the data associated with it.  */
350
  if (file_ptr == NULL)
351
    {
352
      file_ptr = xmalloc (sizeof (*file_ptr));
353
      file_ptr->fd = fd;
354
      file_ptr->ready_mask = 0;
355
      file_ptr->next_file = gdb_notifier.first_file_handler;
356
      gdb_notifier.first_file_handler = file_ptr;
357
 
358
      if (mask & GDB_READABLE)
359
        FD_SET (fd, &gdb_notifier.check_masks[0]);
360
      else
361
        FD_CLR (fd, &gdb_notifier.check_masks[0]);
362
 
363
      if (mask & GDB_WRITABLE)
364
        FD_SET (fd, &gdb_notifier.check_masks[1]);
365
      else
366
        FD_CLR (fd, &gdb_notifier.check_masks[1]);
367
 
368
      if (mask & GDB_EXCEPTION)
369
        FD_SET (fd, &gdb_notifier.check_masks[2]);
370
      else
371
        FD_CLR (fd, &gdb_notifier.check_masks[2]);
372
 
373
      if (gdb_notifier.num_fds <= fd)
374
        gdb_notifier.num_fds = fd + 1;
375
    }
376
 
377
  file_ptr->proc = proc;
378
  file_ptr->client_data = client_data;
379
  file_ptr->mask = mask;
380
}
381
 
382
/* Wrapper function for create_file_handler.  */
383
 
384
void
385
add_file_handler (int fd, handler_func *proc, gdb_client_data client_data)
386
{
387
  create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
388
}
389
 
390
/* Remove the file descriptor FD from the list of monitored fd's:
391
   i.e. we don't care anymore about events on the FD.  */
392
 
393
void
394
delete_file_handler (int fd)
395
{
396
  file_handler *file_ptr, *prev_ptr = NULL;
397
  int i;
398
 
399
  /* Find the entry for the given file. */
400
 
401
  for (file_ptr = gdb_notifier.first_file_handler;
402
       file_ptr != NULL;
403
       file_ptr = file_ptr->next_file)
404
    if (file_ptr->fd == fd)
405
      break;
406
 
407
  if (file_ptr == NULL)
408
    return;
409
 
410
  if (file_ptr->mask & GDB_READABLE)
411
    FD_CLR (fd, &gdb_notifier.check_masks[0]);
412
  if (file_ptr->mask & GDB_WRITABLE)
413
    FD_CLR (fd, &gdb_notifier.check_masks[1]);
414
  if (file_ptr->mask & GDB_EXCEPTION)
415
    FD_CLR (fd, &gdb_notifier.check_masks[2]);
416
 
417
  /* Find current max fd.  */
418
 
419
  if ((fd + 1) == gdb_notifier.num_fds)
420
    {
421
      gdb_notifier.num_fds--;
422
      for (i = gdb_notifier.num_fds; i; i--)
423
        {
424
          if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
425
              || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
426
              || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
427
            break;
428
        }
429
      gdb_notifier.num_fds = i;
430
    }
431
 
432
  /* Deactivate the file descriptor, by clearing its mask, so that it
433
     will not fire again.  */
434
 
435
  file_ptr->mask = 0;
436
 
437
  /* Get rid of the file handler in the file handler list.  */
438
  if (file_ptr == gdb_notifier.first_file_handler)
439
    gdb_notifier.first_file_handler = file_ptr->next_file;
440
  else
441
    {
442
      for (prev_ptr = gdb_notifier.first_file_handler;
443
           prev_ptr->next_file != file_ptr;
444
           prev_ptr = prev_ptr->next_file)
445
        ;
446
      prev_ptr->next_file = file_ptr->next_file;
447
    }
448
  free (file_ptr);
449
}
450
 
451
/* Handle the given event by calling the procedure associated to the
452
   corresponding file handler.  Called by process_event indirectly,
453
   through event_ptr->proc.  EVENT_FILE_DESC is file descriptor of the
454
   event in the front of the event queue.  */
455
 
456
static int
457
handle_file_event (int event_file_desc)
458
{
459
  file_handler *file_ptr;
460
  int mask;
461
 
462
  /* Search the file handler list to find one that matches the fd in
463
     the event.  */
464
  for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
465
       file_ptr = file_ptr->next_file)
466
    {
467
      if (file_ptr->fd == event_file_desc)
468
        {
469
          /* See if the desired events (mask) match the received
470
             events (ready_mask).  */
471
 
472
          if (file_ptr->ready_mask & GDB_EXCEPTION)
473
            {
474
              fprintf (stderr, "Exception condition detected on fd %d\n",
475
                       file_ptr->fd);
476
              file_ptr->error = 1;
477
            }
478
          else
479
            file_ptr->error = 0;
480
          mask = file_ptr->ready_mask & file_ptr->mask;
481
 
482
          /* Clear the received events for next time around.  */
483
          file_ptr->ready_mask = 0;
484
 
485
          /* If there was a match, then call the handler.  */
486
          if (mask != 0)
487
            {
488
              if ((*file_ptr->proc) (file_ptr->error,
489
                                     file_ptr->client_data) < 0)
490
                return -1;
491
            }
492
          break;
493
        }
494
    }
495
 
496
  return 0;
497
}
498
 
499
/* Create a file event, to be enqueued in the event queue for
500
   processing.  The procedure associated to this event is always
501
   handle_file_event, which will in turn invoke the one that was
502
   associated to FD when it was registered with the event loop.  */
503
 
504
static gdb_event *
505
create_file_event (int fd)
506
{
507
  gdb_event *file_event_ptr;
508
 
509
  file_event_ptr = xmalloc (sizeof (gdb_event));
510
  file_event_ptr->proc = handle_file_event;
511
  file_event_ptr->fd = fd;
512
  return file_event_ptr;
513
}
514
 
515
/* Called by do_one_event to wait for new events on the monitored file
516
   descriptors.  Queue file events as they are detected by the poll.
517
   If there are no events, this function will block in the call to
518
   select.  Return -1 if there are no files descriptors to monitor,
519
   otherwise return 0.  */
520
 
521
static int
522
wait_for_event (void)
523
{
524
  file_handler *file_ptr;
525
  gdb_event *file_event_ptr;
526
  int num_found = 0;
527
 
528
  /* Make sure all output is done before getting another event.  */
529
  fflush (stdout);
530
  fflush (stderr);
531
 
532
  if (gdb_notifier.num_fds == 0)
533
    return -1;
534
 
535
  gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
536
  gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
537
  gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
538
  num_found = select (gdb_notifier.num_fds,
539
                      &gdb_notifier.ready_masks[0],
540
                      &gdb_notifier.ready_masks[1],
541
                      &gdb_notifier.ready_masks[2],
542
                      NULL);
543
 
544
  /* Clear the masks after an error from select.  */
545
  if (num_found == -1)
546
    {
547
      FD_ZERO (&gdb_notifier.ready_masks[0]);
548
      FD_ZERO (&gdb_notifier.ready_masks[1]);
549
      FD_ZERO (&gdb_notifier.ready_masks[2]);
550
#ifdef EINTR
551
      /* Dont print anything if we got a signal, let gdb handle
552
         it.  */
553
      if (errno != EINTR)
554
        perror_with_name ("select");
555
#endif
556
    }
557
 
558
  /* Enqueue all detected file events.  */
559
 
560
  for (file_ptr = gdb_notifier.first_file_handler;
561
       file_ptr != NULL && num_found > 0;
562
       file_ptr = file_ptr->next_file)
563
    {
564
      int mask = 0;
565
 
566
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
567
        mask |= GDB_READABLE;
568
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
569
        mask |= GDB_WRITABLE;
570
      if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
571
        mask |= GDB_EXCEPTION;
572
 
573
      if (!mask)
574
        continue;
575
      else
576
        num_found--;
577
 
578
      /* Enqueue an event only if this is still a new event for this
579
         fd.  */
580
 
581
      if (file_ptr->ready_mask == 0)
582
        {
583
          file_event_ptr = create_file_event (file_ptr->fd);
584
          async_queue_event (file_event_ptr);
585
        }
586
      file_ptr->ready_mask = mask;
587
    }
588
 
589
  return 0;
590
}
591
 
592
/* Start up the event loop.  This is the entry point to the event
593
   loop.  */
594
 
595
void
596
start_event_loop (void)
597
{
598
  /* Loop until there is nothing to do.  This is the entry point to
599
     the event loop engine.  If nothing is ready at this time, wait
600
     for something to happen (via wait_for_event), then process it.
601
     Return when there are no longer event sources to wait for.  */
602
 
603
  while (1)
604
    {
605
      /* Any events already waiting in the queue?  */
606
      int res = process_event ();
607
 
608
      /* Did the event handler want the event loop to stop?  */
609
      if (res == -1)
610
        return;
611
 
612
      if (res)
613
        continue;
614
 
615
      /* Process any queued callbacks before we go to sleep.  */
616
      res = process_callback ();
617
 
618
      /* Did the callback want the event loop to stop?  */
619
      if (res == -1)
620
        return;
621
 
622
      if (res)
623
        continue;
624
 
625
      /* Wait for a new event.  If wait_for_event returns -1, we
626
         should get out because this means that there are no event
627
         sources left.  This will make the event loop stop, and the
628
         application exit.  */
629
 
630
      if (wait_for_event () < 0)
631
        return;
632
    }
633
 
634
  /* We are done with the event loop.  There are no more event sources
635
     to listen to.  So we exit gdbserver.  */
636
}

powered by: WebSVN 2.1.0

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