Move notif_queue and remote_async_get_pending_events_token to remote_state
[external/binutils.git] / gdb / remote-notif.c
1 /* Remote notification in GDB protocol
2
3    Copyright (C) 1988-2013 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 /* Remote async notification is sent from remote target over RSP.
21    Each type of notification is represented by an object of
22    'struct notif', which has a field 'pending_reply'.  It is not
23    NULL when GDB receives a notification from GDBserver, but hasn't
24    acknowledge yet.  Before GDB acknowledges the notification,
25    GDBserver shouldn't send notification again (see the header comments
26    in gdbserver/notif.c).
27
28    Notifications are processed in an almost-unified approach for both
29    all-stop mode and non-stop mode, except the timing to process them.
30    In non-stop mode, notifications are processed in
31    remote_async_get_pending_events_handler, while in all-stop mode,
32    they are processed in remote_resume.  */
33
34 #include "defs.h"
35 #include "remote.h"
36 #include "remote-notif.h"
37 #include "observer.h"
38 #include "event-loop.h"
39 #include "target.h"
40 #include "inferior.h"
41 #include "gdbcmd.h"
42
43 #include <string.h>
44
45 int notif_debug = 0;
46
47 /* Supported clients of notifications.  */
48
49 static struct notif_client *notifs[] =
50 {
51   &notif_client_stop,
52 };
53
54 static void do_notif_event_xfree (void *arg);
55
56 /* Parse the BUF for the expected notification NC, and send packet to
57    acknowledge.  */
58
59 void
60 remote_notif_ack (struct notif_client *nc, char *buf)
61 {
62   struct notif_event *event = nc->alloc_event ();
63   struct cleanup *old_chain
64     = make_cleanup (do_notif_event_xfree, event);
65
66   if (notif_debug)
67     fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n",
68                         nc->ack_command);
69
70   nc->parse (nc, buf, event);
71   nc->ack (nc, buf, event);
72
73   discard_cleanups (old_chain);
74 }
75
76 /* Parse the BUF for the expected notification NC.  */
77
78 struct notif_event *
79 remote_notif_parse (struct notif_client *nc, char *buf)
80 {
81   struct notif_event *event = nc->alloc_event ();
82   struct cleanup *old_chain
83     = make_cleanup (do_notif_event_xfree, event);
84
85   if (notif_debug)
86     fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name);
87
88   nc->parse (nc, buf, event);
89
90   discard_cleanups (old_chain);
91   return event;
92 }
93
94 DEFINE_QUEUE_P (notif_client_p);
95
96 /* Process notifications in STATE's notification queue one by one.
97    EXCEPT is not expected in the queue.  */
98
99 void
100 remote_notif_process (struct remote_notif_state *state,
101                       struct notif_client *except)
102 {
103   while (!QUEUE_is_empty (notif_client_p, state->notif_queue))
104     {
105       struct notif_client *nc = QUEUE_deque (notif_client_p,
106                                              state->notif_queue);
107
108       gdb_assert (nc != except);
109
110       if (nc->can_get_pending_events (nc))
111         remote_notif_get_pending_events (nc);
112     }
113 }
114
115 static void
116 remote_async_get_pending_events_handler (gdb_client_data data)
117 {
118   gdb_assert (non_stop);
119   remote_notif_process (data, NULL);
120 }
121
122 /* Remote notification handler.  Parse BUF, queue notification and
123    update STATE.  */
124
125 void
126 handle_notification (struct remote_notif_state *state, char *buf)
127 {
128   struct notif_client *nc = NULL;
129   int i;
130
131   for (i = 0; i < ARRAY_SIZE (notifs); i++)
132     {
133       nc = notifs[i];
134       if (strncmp (buf, nc->name, strlen (nc->name)) == 0
135           && buf[strlen (nc->name)] == ':')
136         break;
137     }
138
139   /* We ignore notifications we don't recognize, for compatibility
140      with newer stubs.  */
141   if (nc == NULL)
142     return;
143
144   if (nc->pending_event)
145     {
146       /* We've already parsed the in-flight reply, but the stub for some
147          reason thought we didn't, possibly due to timeout on its side.
148          Just ignore it.  */
149       if (notif_debug)
150         fprintf_unfiltered (gdb_stdlog,
151                             "notif: ignoring resent notification\n");
152     }
153   else
154     {
155       struct notif_event *event
156         = remote_notif_parse (nc, buf + strlen (nc->name) + 1);
157
158       /* Be careful to only set it after parsing, since an error
159          may be thrown then.  */
160       nc->pending_event = event;
161
162       /* Notify the event loop there's a stop reply to acknowledge
163          and that there may be more events to fetch.  */
164       QUEUE_enque (notif_client_p, state->notif_queue, nc);
165       if (non_stop)
166         {
167           /* In non-stop, We mark REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN
168              in order to go on what we were doing and postpone
169              querying notification events to some point safe to do so.
170              See details in the function comment of
171              remote.c:remote_notif_get_pending_events.
172
173              In all-stop, GDB may be blocked to wait for the reply, we
174              shouldn't return to event loop until the expected reply
175              arrives.  For example:
176
177              1.1) --> vCont;c
178                GDB expects getting stop reply 'T05 thread:2'.
179              1.2) <-- %Notif
180                <GDB marks the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN>
181
182              After step #1.2, we return to the event loop, which
183              notices there is a new event on the
184              REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN and calls the
185              handler, which will send 'vNotif' packet.
186              1.3) --> vNotif
187              It is not safe to start a new sequence, because target
188              is still running and GDB is expecting the stop reply
189              from stub.
190
191              To solve this, whenever we parse a notification
192              successfully, we don't mark the
193              REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN and let GDB blocked
194              there as before to get the sequence done.
195
196              2.1) --> vCont;c
197                GDB expects getting stop reply 'T05 thread:2'
198              2.2) <-- %Notif
199                <Don't mark the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN>
200              2.3) <-- T05 thread:2
201
202              These pending notifications can be processed later.  */
203           mark_async_event_handler (state->get_pending_events_token);
204         }
205
206       if (notif_debug)
207         fprintf_unfiltered (gdb_stdlog,
208                             "notif: Notification '%s' captured\n",
209                             nc->name);
210     }
211 }
212
213 /* Cleanup wrapper.  */
214
215 static void
216 do_notif_event_xfree (void *arg)
217 {
218   struct notif_event *event = arg;
219
220   if (event && event->dtr)
221     event->dtr (event);
222
223   xfree (event);
224 }
225
226 /* Return an allocated remote_notif_state.  */
227
228 struct remote_notif_state *
229 remote_notif_state_allocate (void)
230 {
231   struct remote_notif_state *notif_state = xzalloc (sizeof (*notif_state));
232
233   notif_state->notif_queue = QUEUE_alloc (notif_client_p, NULL);
234
235   /* Register async_event_handler for notification.  */
236
237   notif_state->get_pending_events_token
238     = create_async_event_handler (remote_async_get_pending_events_handler,
239                                   notif_state);
240
241   return notif_state;
242 }
243
244 /* Free STATE and its fields.  */
245
246 void
247 remote_notif_state_xfree (struct remote_notif_state *state)
248 {
249   QUEUE_free (notif_client_p, state->notif_queue);
250
251   /* Unregister async_event_handler for notification.  */
252   if (state->get_pending_events_token != NULL)
253     delete_async_event_handler (&state->get_pending_events_token);
254
255   xfree (state);
256 }
257
258 /* -Wmissing-prototypes */
259 extern initialize_file_ftype _initialize_notif;
260
261 void
262 _initialize_notif (void)
263 {
264   add_setshow_boolean_cmd ("notification", no_class, &notif_debug,
265                            _("\
266 Set debugging of async remote notification."), _("\
267 Show debugging of async remote notification."), _("\
268 When non-zero, debugging output about async remote notifications"
269 " is enabled."),
270                            NULL,
271                            NULL,
272                            &setdebuglist, &showdebuglist);
273 }