gdb/gdbserver/
[deliverable/binutils-gdb.git] / gdb / gdbserver / notif.c
CommitLineData
14a00470
YQ
1/* Notification to GDB.
2 Copyright (C) 1989, 1993-1995, 1997-2000, 2002-2012 Free Software
3 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/* Async notifications to GDB. When the state of remote target is
21 changed or something interesting to GDB happened, async
22 notifications are used to tell GDB.
23
24 Each type of notification is represented by an object
25 'struct notif_server', in which there is a queue for events to GDB
26 represented by 'struct notif_event'. GDBserver writes (by means of
27 'write' field) each event in the queue into the buffer and send the
28 contents in buffer to GDB. The contents in buffer is specified in
29 RSP. See more in the comments to field 'queue' of
30 'struct notif_server'.
31
32 Here is the workflow of sending events and managing queue:
33 1. At any time, when something interesting FOO happens, a object
34 of 'struct notif_event' or its sub-class EVENT is created for FOO.
35
36 2. Enque EVENT to the 'queue' field of 'struct notif_server' for
37 FOO and send corresponding notification packet to GDB if EVENT is
38 the first one.
39 #1 and #2 are done by function 'notif_push'.
40
41 3. EVENT is not deque'ed until the ack of FOO from GDB arrives.
42 Before ack of FOO arrives, FOO happens again, a new object of
43 EVENT is created and enque EVENT silently.
44 Once GDB has a chance to ack to FOO, it sends an ack to GDBserver,
45 and GDBserver repeatedly sends events to GDB and gets ack of FOO,
46 until queue is empty. Then, GDBserver sends 'OK' to GDB that all
47 queued notification events are done.
48
49 # 3 is done by function 'handle_notif_ack'. */
50
51#include "notif.h"
52
53static struct notif_server *notifs[] =
54{
55 &notif_stop,
56};
57
58/* Write another event or an OK, if there are no more left, to
59 OWN_BUF. */
60
61void
62notif_write_event (struct notif_server *notif, char *own_buf)
63{
64 if (!QUEUE_is_empty (notif_event_p, notif->queue))
65 {
66 struct notif_event *event
67 = QUEUE_peek (notif_event_p, notif->queue);
68
69 notif->write (event, own_buf);
70 }
71 else
72 write_ok (own_buf);
73}
74
75/* Handle the ack in buffer OWN_BUF,and packet length is PACKET_LEN.
76 Return 1 if the ack is handled, and return 0 if the contents
77 in OWN_BUF is not a ack. */
78
79int
80handle_notif_ack (char *own_buf, int packet_len)
81{
82 int i = 0;
83 struct notif_server *np = NULL;
84
85 for (i = 0; i < ARRAY_SIZE (notifs); i++)
86 {
87 np = notifs[i];
88 if (strncmp (own_buf, np->ack_name, strlen (np->ack_name)) == 0
89 && packet_len == strlen (np->ack_name))
90 break;
91 }
92
93 if (np == NULL)
94 return 0;
95
96 /* If we're waiting for GDB to acknowledge a pending event,
97 consider that done. */
98 if (!QUEUE_is_empty (notif_event_p, np->queue))
99 {
100 struct notif_event *head
101 = QUEUE_deque (notif_event_p, np->queue);
102
103 if (remote_debug)
104 fprintf (stderr, "%s: acking %d\n", np->ack_name,
105 QUEUE_length (notif_event_p, np->queue));
106
107 xfree (head);
108 }
109
110 notif_write_event (np, own_buf);
111
112 return 1;
113}
114
115/* Put EVENT to the queue of NOTIF. */
116
117void
118notif_event_enque (struct notif_server *notif,
119 struct notif_event *event)
120{
121 QUEUE_enque (notif_event_p, notif->queue, event);
122
123 if (remote_debug)
124 fprintf (stderr, "pending events: %s %d\n", notif->notif_name,
125 QUEUE_length (notif_event_p, notif->queue));
126
127}
128
129/* Push one event NEW_EVENT of notification NP into NP->queue. */
130
131void
132notif_push (struct notif_server *np, struct notif_event *new_event)
133{
134 int is_first_event = QUEUE_is_empty (notif_event_p, np->queue);
135
136 /* Something interesting. Tell GDB about it. */
137 notif_event_enque (np, new_event);
138
139 /* If this is the first stop reply in the queue, then inform GDB
140 about it, by sending a corresponding notification. */
141 if (is_first_event)
142 {
143 char buf[PBUFSIZ];
144 char *p = buf;
145
146 xsnprintf (p, PBUFSIZ, "%s:", np->notif_name);
147 p += strlen (p);
148
149 np->write (new_event, p);
150 putpkt_notif (buf);
151 }
152}
153
154static void
155notif_event_xfree (struct notif_event *event)
156{
157 xfree (event);
158}
159
160void
161initialize_notif (void)
162{
163 int i = 0;
164
165 for (i = 0; i < ARRAY_SIZE (notifs); i++)
166 notifs[i]->queue
167 = QUEUE_alloc (notif_event_p, notif_event_xfree);
168}
This page took 0.029464 seconds and 4 git commands to generate.