GDBserver
notif.c
Go to the documentation of this file.
1 /* Notification to GDB.
2  Copyright (C) 1989-2015 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  fprintf (stderr, "%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
122  struct notif_event *event)
123 {
124  QUEUE_enque (notif_event_p, notif->queue, event);
125 
126  if (remote_debug)
127  fprintf (stderr, "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
159 {
160  xfree (event);
161 }
162 
163 void
165 {
166  int i = 0;
167 
168  for (i = 0; i < ARRAY_SIZE (notifs); i++)
169  notifs[i]->queue
171 }
void notif_push(struct notif_server *np, struct notif_event *new_event)
Definition: notif.c:135
#define QUEUE_enque(TYPE, Q, V)
Definition: queue.h:55
void notif_event_enque(struct notif_server *notif, struct notif_event *event)
Definition: notif.c:121
#define QUEUE_length(TYPE, Q)
Definition: queue.h:73
#define QUEUE_is_empty(TYPE, Q)
Definition: queue.h:66
static void notif_event_xfree(struct notif_event *event)
Definition: notif.c:158
const char * notif_name
Definition: notif.h:44
int handle_notif_ack(char *own_buf, int packet_len)
Definition: notif.c:80
void(* write)(struct notif_event *event, char *own_buf)
Definition: notif.h:52
void write_ok(char *buf)
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:75
#define QUEUE_deque(TYPE, Q)
Definition: queue.h:59
int putpkt_notif(char *buf)
Definition: remote-utils.c:716
const char * ack_name
Definition: notif.h:40
#define QUEUE_alloc(TYPE, FREE_FUNC)
Definition: queue.h:70
void xfree(void *ptr)
Definition: common-utils.c:97
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
static char * own_buf
Definition: server.c:111
struct notif_server notif_stop
Definition: server.c:186
int remote_debug
Definition: remote-utils.c:103
#define QUEUE_peek(TYPE, Q)
Definition: queue.h:63
#define PBUFSIZ
Definition: server.h:129
void notif_write_event(struct notif_server *notif, char *own_buf)
Definition: notif.c:62
void initialize_notif(void)
Definition: notif.c:164