GDBserver
|
00001 /* Notification to GDB. 00002 Copyright (C) 1989-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 /* Async notifications to GDB. When the state of remote target is 00020 changed or something interesting to GDB happened, async 00021 notifications are used to tell GDB. 00022 00023 Each type of notification is represented by an object 00024 'struct notif_server', in which there is a queue for events to GDB 00025 represented by 'struct notif_event'. GDBserver writes (by means of 00026 'write' field) each event in the queue into the buffer and send the 00027 contents in buffer to GDB. The contents in buffer is specified in 00028 RSP. See more in the comments to field 'queue' of 00029 'struct notif_server'. 00030 00031 Here is the workflow of sending events and managing queue: 00032 1. At any time, when something interesting FOO happens, a object 00033 of 'struct notif_event' or its sub-class EVENT is created for FOO. 00034 00035 2. Enque EVENT to the 'queue' field of 'struct notif_server' for 00036 FOO and send corresponding notification packet to GDB if EVENT is 00037 the first one. 00038 #1 and #2 are done by function 'notif_push'. 00039 00040 3. EVENT is not deque'ed until the ack of FOO from GDB arrives. 00041 Before ack of FOO arrives, FOO happens again, a new object of 00042 EVENT is created and enque EVENT silently. 00043 Once GDB has a chance to ack to FOO, it sends an ack to GDBserver, 00044 and GDBserver repeatedly sends events to GDB and gets ack of FOO, 00045 until queue is empty. Then, GDBserver sends 'OK' to GDB that all 00046 queued notification events are done. 00047 00048 # 3 is done by function 'handle_notif_ack'. */ 00049 00050 #include "notif.h" 00051 00052 static struct notif_server *notifs[] = 00053 { 00054 ¬if_stop, 00055 }; 00056 00057 /* Write another event or an OK, if there are no more left, to 00058 OWN_BUF. */ 00059 00060 void 00061 notif_write_event (struct notif_server *notif, char *own_buf) 00062 { 00063 if (!QUEUE_is_empty (notif_event_p, notif->queue)) 00064 { 00065 struct notif_event *event 00066 = QUEUE_peek (notif_event_p, notif->queue); 00067 00068 notif->write (event, own_buf); 00069 } 00070 else 00071 write_ok (own_buf); 00072 } 00073 00074 /* Handle the ack in buffer OWN_BUF,and packet length is PACKET_LEN. 00075 Return 1 if the ack is handled, and return 0 if the contents 00076 in OWN_BUF is not a ack. */ 00077 00078 int 00079 handle_notif_ack (char *own_buf, int packet_len) 00080 { 00081 int i = 0; 00082 struct notif_server *np = NULL; 00083 00084 for (i = 0; i < ARRAY_SIZE (notifs); i++) 00085 { 00086 np = notifs[i]; 00087 if (strncmp (own_buf, np->ack_name, strlen (np->ack_name)) == 0 00088 && packet_len == strlen (np->ack_name)) 00089 break; 00090 } 00091 00092 if (np == NULL) 00093 return 0; 00094 00095 /* If we're waiting for GDB to acknowledge a pending event, 00096 consider that done. */ 00097 if (!QUEUE_is_empty (notif_event_p, np->queue)) 00098 { 00099 struct notif_event *head 00100 = QUEUE_deque (notif_event_p, np->queue); 00101 00102 if (remote_debug) 00103 fprintf (stderr, "%s: acking %d\n", np->ack_name, 00104 QUEUE_length (notif_event_p, np->queue)); 00105 00106 xfree (head); 00107 } 00108 00109 notif_write_event (np, own_buf); 00110 00111 return 1; 00112 } 00113 00114 /* Put EVENT to the queue of NOTIF. */ 00115 00116 void 00117 notif_event_enque (struct notif_server *notif, 00118 struct notif_event *event) 00119 { 00120 QUEUE_enque (notif_event_p, notif->queue, event); 00121 00122 if (remote_debug) 00123 fprintf (stderr, "pending events: %s %d\n", notif->notif_name, 00124 QUEUE_length (notif_event_p, notif->queue)); 00125 00126 } 00127 00128 /* Push one event NEW_EVENT of notification NP into NP->queue. */ 00129 00130 void 00131 notif_push (struct notif_server *np, struct notif_event *new_event) 00132 { 00133 int is_first_event = QUEUE_is_empty (notif_event_p, np->queue); 00134 00135 /* Something interesting. Tell GDB about it. */ 00136 notif_event_enque (np, new_event); 00137 00138 /* If this is the first stop reply in the queue, then inform GDB 00139 about it, by sending a corresponding notification. */ 00140 if (is_first_event) 00141 { 00142 char buf[PBUFSIZ]; 00143 char *p = buf; 00144 00145 xsnprintf (p, PBUFSIZ, "%s:", np->notif_name); 00146 p += strlen (p); 00147 00148 np->write (new_event, p); 00149 putpkt_notif (buf); 00150 } 00151 } 00152 00153 static void 00154 notif_event_xfree (struct notif_event *event) 00155 { 00156 xfree (event); 00157 } 00158 00159 void 00160 initialize_notif (void) 00161 { 00162 int i = 0; 00163 00164 for (i = 0; i < ARRAY_SIZE (notifs); i++) 00165 notifs[i]->queue 00166 = QUEUE_alloc (notif_event_p, notif_event_xfree); 00167 }