Update years in copyright notice for the GDB files.
[external/binutils.git] / gdb / gdbserver / notif.c
1 /* Notification to GDB.
2    Copyright (C) 1989-2013 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 /* Async notifications to GDB.  When the state of remote target is
20    changed or something interesting to GDB happened, async
21    notifications are used to tell GDB.
22
23    Each type of notification is represented by an object
24    'struct notif_server', in which there is a queue for events to GDB
25    represented by 'struct notif_event'.  GDBserver writes (by means of
26    'write' field) each event in the queue into the buffer and send the
27    contents in buffer to GDB.  The contents in buffer is specified in
28    RSP.  See more in the comments to field 'queue' of
29    'struct notif_server'.
30
31    Here is the workflow of sending events and managing queue:
32    1.  At any time, when something interesting FOO happens, a object
33    of 'struct notif_event' or its sub-class EVENT is created for FOO.
34
35    2.  Enque EVENT to the 'queue' field of 'struct notif_server' for
36    FOO and send corresponding notification packet to GDB if EVENT is
37    the first one.
38    #1 and #2 are done by function 'notif_push'.
39
40    3.  EVENT is not deque'ed until the ack of FOO from GDB arrives.
41    Before ack of FOO arrives, FOO happens again, a new object of
42    EVENT is created and enque EVENT silently.
43    Once GDB has a chance to ack to FOO, it sends an ack to GDBserver,
44    and GDBserver repeatedly sends events to GDB and gets ack of FOO,
45    until queue is empty.  Then, GDBserver sends 'OK' to GDB that all
46    queued notification events are done.
47
48    # 3 is done by function 'handle_notif_ack'.  */
49
50 #include "notif.h"
51
52 static struct notif_server *notifs[] =
53 {
54   &notif_stop,
55 };
56
57 /* Write another event or an OK, if there are no more left, to
58    OWN_BUF.  */
59
60 void
61 notif_write_event (struct notif_server *notif, char *own_buf)
62 {
63   if (!QUEUE_is_empty (notif_event_p, notif->queue))
64     {
65       struct notif_event *event
66         = QUEUE_peek (notif_event_p, notif->queue);
67
68       notif->write (event, own_buf);
69     }
70   else
71     write_ok (own_buf);
72 }
73
74 /* Handle the ack in buffer OWN_BUF,and packet length is PACKET_LEN.
75    Return 1 if the ack is handled, and return 0 if the contents
76    in OWN_BUF is not a ack.  */
77
78 int
79 handle_notif_ack (char *own_buf, int packet_len)
80 {
81   int i = 0;
82   struct notif_server *np = NULL;
83
84   for (i = 0; i < ARRAY_SIZE (notifs); i++)
85     {
86       np = notifs[i];
87       if (strncmp (own_buf, np->ack_name, strlen (np->ack_name)) == 0
88           && packet_len == strlen (np->ack_name))
89         break;
90     }
91
92   if (np == NULL)
93     return 0;
94
95   /* If we're waiting for GDB to acknowledge a pending event,
96      consider that done.  */
97   if (!QUEUE_is_empty (notif_event_p, np->queue))
98     {
99       struct notif_event *head
100         = QUEUE_deque (notif_event_p, np->queue);
101
102       if (remote_debug)
103         fprintf (stderr, "%s: acking %d\n", np->ack_name,
104                  QUEUE_length (notif_event_p, np->queue));
105
106       xfree (head);
107     }
108
109   notif_write_event (np, own_buf);
110
111   return 1;
112 }
113
114 /* Put EVENT to the queue of NOTIF.  */
115
116 void
117 notif_event_enque (struct notif_server *notif,
118                    struct notif_event *event)
119 {
120   QUEUE_enque (notif_event_p, notif->queue, event);
121
122   if (remote_debug)
123     fprintf (stderr, "pending events: %s %d\n", notif->notif_name,
124              QUEUE_length (notif_event_p, notif->queue));
125
126 }
127
128 /* Push one event NEW_EVENT of notification NP into NP->queue.  */
129
130 void
131 notif_push (struct notif_server *np, struct notif_event *new_event)
132 {
133   int is_first_event = QUEUE_is_empty (notif_event_p, np->queue);
134
135   /* Something interesting.  Tell GDB about it.  */
136   notif_event_enque (np, new_event);
137
138   /* If this is the first stop reply in the queue, then inform GDB
139      about it, by sending a corresponding notification.  */
140   if (is_first_event)
141     {
142       char buf[PBUFSIZ];
143       char *p = buf;
144
145       xsnprintf (p, PBUFSIZ, "%s:", np->notif_name);
146       p += strlen (p);
147
148       np->write (new_event, p);
149       putpkt_notif (buf);
150     }
151 }
152
153 static void
154 notif_event_xfree (struct notif_event *event)
155 {
156   xfree (event);
157 }
158
159 void
160 initialize_notif (void)
161 {
162   int i = 0;
163
164   for (i = 0; i < ARRAY_SIZE (notifs); i++)
165     notifs[i]->queue
166       = QUEUE_alloc (notif_event_p, notif_event_xfree);
167 }