1/* Remote notification in GDB protocol 2 3 Copyright (C) 1988-2023 Free Software 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#ifndef REMOTE_NOTIF_H 21#define REMOTE_NOTIF_H 22 23#include <list> 24#include <memory> 25 26/* An event of a type of async remote notification. */ 27 28struct notif_event 29{ 30 virtual ~notif_event () 31 { 32 } 33}; 34 35/* A unique pointer holding a notif_event. */ 36 37typedef std::unique_ptr<notif_event> notif_event_up; 38 39/* ID of the notif_client. */ 40 41enum REMOTE_NOTIF_ID 42{ 43 REMOTE_NOTIF_STOP = 0, 44 REMOTE_NOTIF_LAST, 45}; 46 47struct remote_target; 48 49/* A client to a sort of async remote notification. */ 50 51struct notif_client 52{ 53 /* The name of notification packet. */ 54 const char *name; 55 56 /* The packet to acknowledge a previous reply. */ 57 const char *ack_command; 58 59 /* Parse BUF to get the expected event and update EVENT. This 60 function may throw exception if contents in BUF is not the 61 expected event. */ 62 void (*parse) (remote_target *remote, 63 struct notif_client *self, const char *buf, 64 struct notif_event *event); 65 66 /* Send field <ack_command> to remote, and do some checking. If 67 something wrong, throw an exception. */ 68 void (*ack) (remote_target *remote, 69 struct notif_client *self, const char *buf, 70 struct notif_event *event); 71 72 /* Check this notification client can get pending events in 73 'remote_notif_process'. */ 74 int (*can_get_pending_events) (remote_target *remote, 75 struct notif_client *self); 76 77 /* Allocate an event. */ 78 notif_event_up (*alloc_event) (); 79 80 /* Id of this notif_client. */ 81 const enum REMOTE_NOTIF_ID id; 82}; 83 84/* State on remote async notification. */ 85 86struct remote_notif_state 87{ 88 remote_notif_state () = default; 89 ~remote_notif_state (); 90 91 DISABLE_COPY_AND_ASSIGN (remote_notif_state); 92 93 /* The remote target. */ 94 remote_target *remote; 95 96 /* Notification queue. */ 97 98 std::list<notif_client *> notif_queue; 99 100 /* Asynchronous signal handle registered as event loop source for when 101 the remote sent us a notification. The registered callback 102 will do a ACK sequence to pull the rest of the events out of 103 the remote side into our event queue. */ 104 105 struct async_event_handler *get_pending_events_token; 106 107 /* One pending event for each notification client. This is where we 108 keep it until it is acknowledged. When there is a notification 109 packet, parse it, and create an object of 'struct notif_event' to 110 assign to it. This field is unchanged until GDB starts to ack 111 this notification (which is done by 112 remote.c:remote_notif_pending_replies). */ 113 114 struct notif_event *pending_event[REMOTE_NOTIF_LAST] {}; 115}; 116 117void remote_notif_ack (remote_target *remote, notif_client *nc, 118 const char *buf); 119struct notif_event *remote_notif_parse (remote_target *remote, 120 notif_client *nc, 121 const char *buf); 122 123void handle_notification (struct remote_notif_state *notif_state, 124 const char *buf); 125 126void remote_notif_process (struct remote_notif_state *state, 127 struct notif_client *except); 128remote_notif_state *remote_notif_state_allocate (remote_target *remote); 129 130extern struct notif_client notif_client_stop; 131 132extern bool notif_debug; 133 134#endif /* REMOTE_NOTIF_H */ 135