]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/notif.c
Update Copyright year range in all files maintained by GDB.
[thirdparty/binutils-gdb.git] / gdb / gdbserver / notif.c
CommitLineData
14a00470 1/* Notification to GDB.
ecd75fc8 2 Copyright (C) 1989-2014 Free Software Foundation, Inc.
14a00470
YQ
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
52static 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
60void
61notif_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
78int
79handle_notif_ack (char *own_buf, int packet_len)
80{
e7f0d979
YQ
81 size_t i;
82 struct notif_server *np;
14a00470
YQ
83
84 for (i = 0; i < ARRAY_SIZE (notifs); i++)
85 {
e7f0d979
YQ
86 const char *ack_name = notifs[i]->ack_name;
87
88 if (strncmp (own_buf, ack_name, strlen (ack_name)) == 0
89 && packet_len == strlen (ack_name))
14a00470
YQ
90 break;
91 }
92
e7f0d979 93 if (i == ARRAY_SIZE (notifs))
14a00470
YQ
94 return 0;
95
e7f0d979
YQ
96 np = notifs[i];
97
14a00470
YQ
98 /* If we're waiting for GDB to acknowledge a pending event,
99 consider that done. */
100 if (!QUEUE_is_empty (notif_event_p, np->queue))
101 {
102 struct notif_event *head
103 = QUEUE_deque (notif_event_p, np->queue);
104
105 if (remote_debug)
106 fprintf (stderr, "%s: acking %d\n", np->ack_name,
107 QUEUE_length (notif_event_p, np->queue));
108
109 xfree (head);
110 }
111
112 notif_write_event (np, own_buf);
113
114 return 1;
115}
116
117/* Put EVENT to the queue of NOTIF. */
118
119void
120notif_event_enque (struct notif_server *notif,
121 struct notif_event *event)
122{
123 QUEUE_enque (notif_event_p, notif->queue, event);
124
125 if (remote_debug)
126 fprintf (stderr, "pending events: %s %d\n", notif->notif_name,
127 QUEUE_length (notif_event_p, notif->queue));
128
129}
130
131/* Push one event NEW_EVENT of notification NP into NP->queue. */
132
133void
134notif_push (struct notif_server *np, struct notif_event *new_event)
135{
136 int is_first_event = QUEUE_is_empty (notif_event_p, np->queue);
137
138 /* Something interesting. Tell GDB about it. */
139 notif_event_enque (np, new_event);
140
141 /* If this is the first stop reply in the queue, then inform GDB
142 about it, by sending a corresponding notification. */
143 if (is_first_event)
144 {
145 char buf[PBUFSIZ];
146 char *p = buf;
147
148 xsnprintf (p, PBUFSIZ, "%s:", np->notif_name);
149 p += strlen (p);
150
151 np->write (new_event, p);
152 putpkt_notif (buf);
153 }
154}
155
156static void
157notif_event_xfree (struct notif_event *event)
158{
159 xfree (event);
160}
161
162void
163initialize_notif (void)
164{
165 int i = 0;
166
167 for (i = 0; i < ARRAY_SIZE (notifs); i++)
168 notifs[i]->queue
169 = QUEUE_alloc (notif_event_p, notif_event_xfree);
170}