GDBserver

notif.c
Go to the documentation of this file.
1 /* Notification to GDB.
2 Copyright (C) 1989-2018 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 "server.h"
51 #include "notif.h"
52
53 static 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
61 void
62 notif_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
79 int
80 handle_notif_ack (char *own_buf, int packet_len)
81 {
82 size_t i;
83 struct notif_server *np;
84
85 for (i = 0; i < ARRAY_SIZE (notifs); i++)
86 {
87 const char *ack_name = notifs[i]->ack_name;
88
89 if (startswith (own_buf, ack_name)
90 && packet_len == strlen (ack_name))
91 break;
92 }
93
94 if (i == ARRAY_SIZE (notifs))
95 return 0;
96
97 np = notifs[i];
98
99 /* If we're waiting for GDB to acknowledge a pending event,
100 consider that done. */
101 if (!QUEUE_is_empty (notif_event_p, np->queue))
102 {
103 struct notif_event *head
104 = QUEUE_deque (notif_event_p, np->queue);
105
106 if (remote_debug)
107 debug_printf ("%s: acking %d\n", np->ack_name,
108 QUEUE_length (notif_event_p, np->queue));
109
110 xfree (head);
111 }
112
113 notif_write_event (np, own_buf);
114
115 return 1;
116 }
117
118 /* Put EVENT to the queue of NOTIF. */
119
120 void
121 notif_event_enque (struct notif_server *notif,
122 struct notif_event *event)
123 {
124 QUEUE_enque (notif_event_p, notif->queue, event);
125
126 if (remote_debug)
127 debug_printf ("pending events: %s %d\n", notif->notif_name,
128 QUEUE_length (notif_event_p, notif->queue));
129
130 }
131
132 /* Push one event NEW_EVENT of notification NP into NP->queue. */
133
134 void
135 notif_push (struct notif_server *np, struct notif_event *new_event)
136 {
137 int is_first_event = QUEUE_is_empty (notif_event_p, np->queue);
138
139 /* Something interesting. Tell GDB about it. */
140 notif_event_enque (np, new_event);
141
142 /* If this is the first stop reply in the queue, then inform GDB
143 about it, by sending a corresponding notification. */
144 if (is_first_event)
145 {
146 char buf[PBUFSIZ];
147 char *p = buf;
148
149 xsnprintf (p, PBUFSIZ, "%s:", np->notif_name);
150 p += strlen (p);
151
152 np->write (new_event, p);
153 putpkt_notif (buf);
154 }
155 }
156
157 static void
158 notif_event_xfree (struct notif_event *event)
159 {
160 xfree (event);
161 }
162
163 void
164 initialize_notif (void)
165 {
166 int i = 0;
167
168 for (i = 0; i < ARRAY_SIZE (notifs); i++)
169 notifs[i]->queue
170 = QUEUE_alloc (notif_event_p, notif_event_xfree);
171 }
notif_event
Definition: notif.h:26
xfree
static void xfree(T *ptr)
Definition: common-utils.h:54
notif_push
void notif_push(struct notif_server *np, struct notif_event *new_event)
Definition: notif.c:135
QUEUE_enque
#define QUEUE_enque(TYPE, Q, V)
Definition: queue.h:55
notif_event_enque
void notif_event_enque(struct notif_server *notif, struct notif_event *event)
Definition: notif.c:121
QUEUE_length
#define QUEUE_length(TYPE, Q)
Definition: queue.h:73
QUEUE_is_empty
#define QUEUE_is_empty(TYPE, Q)
Definition: queue.h:66
notif_event_xfree
static void notif_event_xfree(struct notif_event *event)
Definition: notif.c:158
notif_server::notif_name
const char * notif_name
Definition: notif.h:44
handle_notif_ack
int handle_notif_ack(char *own_buf, int packet_len)
Definition: notif.c:80
notif_server
Definition: notif.h:37
notif_server::write
void(* write)(struct notif_event *event, char *own_buf)
Definition: notif.h:52
write_ok
void write_ok(char *buf)
Definition: remote-utils.c:1042
server.h
startswith
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:107
QUEUE_deque
#define QUEUE_deque(TYPE, Q)
Definition: queue.h:59
putpkt_notif
int putpkt_notif(char *buf)
Definition: remote-utils.c:695
notif_server::ack_name
const char * ack_name
Definition: notif.h:40
QUEUE_alloc
#define QUEUE_alloc(TYPE, FREE_FUNC)
Definition: queue.h:70
xsnprintf
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
own_buf
char * own_buf
Definition: server.c:138
notif_stop
struct notif_server notif_stop
Definition: server.c:244
remote_debug
int remote_debug
Definition: remote-utils.c:106
notif.h
QUEUE_peek
#define QUEUE_peek(TYPE, Q)
Definition: queue.h:63
notifs
static struct notif_server * notifs[]
Definition: notif.c:53
debug_printf
void debug_printf(const char *fmt,...)
Definition: common-debug.c:30
PBUFSIZ
#define PBUFSIZ
Definition: server.h:144
notif_write_event
void notif_write_event(struct notif_server *notif, char *own_buf)
Definition: notif.c:62
initialize_notif
void initialize_notif(void)
Definition: notif.c:164