diff options
author | qiyao <qiyao> | 2013-10-04 07:42:06 +0000 |
---|---|---|
committer | qiyao <qiyao> | 2013-10-04 07:42:06 +0000 |
commit | d8de0472d930925e8a8bb8d8bfcd489f07c8a203 (patch) | |
tree | b50d70718f7b21027d9ce5498e24f9ce01848c45 /gdb/remote.c | |
parent | 70166e7ad853a415d641fb5222b39953cc20c209 (diff) | |
download | gdb-d8de0472d930925e8a8bb8d8bfcd489f07c8a203.tar.gz |
Move pending_event to remote_notif_state.
This patch moves pending_event to remote_notif_state. All pending
events are destroyed in remote_notif_state_xfree. However,
discard_pending_stop_replies release pending event too, so the pending
event of stop notification is released twice, we need some refactor
here. We add a new function discard_pending_stop_replies_in_queue
which only discard events in stop_reply_queue, and let
remote_notif_state_xfree release pending event for all notif_client.
After this change, discard_pending_stop_replies is only attached to
ifnerior_exit observer, so the INF can't be NULL any more. The
NULL checking is removed too.
gdb:
2013-10-04 Yao Qi <yao@codesourcery.com>
* remote-notif.h (REMOTE_NOTIF_ID): New enum.
(struct notif_client) <pending_event>: Moved
to struct remote_notif_state.
<id>: New field.
(struct remote_notif_state) <pending_event>: New field.
(notif_event_xfree): Declare.
* remote-notif.c (handle_notification): Adjust.
(notif_event_xfree): New function.
(do_notif_event_xfree): Call notif_event_xfree.
(remote_notif_state_xfree): Call notif_event_xfree to free
each element in field pending_event.
* remote.c (discard_pending_stop_replies): Remove declaration.
(discard_pending_stop_replies_in_queue): Declare.
(remote_close): Call discard_pending_stop_replies_in_queue
instead of discard_pending_stop_replies.
(remote_start_remote): Adjust.
(stop_reply_xfree): Call notif_event_xfree.
(notif_client_stop): Adjust initialization.
(remote_notif_remove_all): Rename it to ...
(remove_stop_reply_for_inferior): ... this. Update comments.
Don't check INF is NULL.
(discard_pending_stop_replies): Return early if notif_state is
NULL. Adjust. Don't check INF is NULL.
(remote_notif_get_pending_events): Adjust.
(discard_pending_stop_replies_in_queue): New function.
(remote_wait_ns): Likewise.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 6ac3f511eb0..60086d25f03 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -220,7 +220,7 @@ struct stop_reply; static void stop_reply_xfree (struct stop_reply *); static void remote_parse_stop_reply (char *, struct stop_reply *); static void push_stop_reply (struct stop_reply *); -static void discard_pending_stop_replies (struct inferior *); +static void discard_pending_stop_replies_in_queue (void); static int peek_stop_reply (ptid_t ptid); static void remote_async_inferior_event_handler (gdb_client_data); @@ -3067,11 +3067,9 @@ remote_close (void) inferior_ptid = null_ptid; discard_all_inferiors (); - /* Stop replies may from inferiors which are still unknown to GDB. - We are closing the remote target, so we should discard - everything, including the stop replies from GDB-unknown - inferiors. */ - discard_pending_stop_replies (NULL); + /* We are closing the remote target, so we should discard + everything of this target. */ + discard_pending_stop_replies_in_queue (); if (remote_async_inferior_event_token) delete_async_event_handler (&remote_async_inferior_event_token); @@ -3572,7 +3570,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p) /* remote_notif_get_pending_replies acks this one, and gets the rest out. */ - notif_client_stop.pending_event + rs->notif_state->pending_event[notif_client_stop.id] = remote_notif_parse (notif, rs->buf); remote_notif_get_pending_events (notif); @@ -5304,11 +5302,7 @@ static QUEUE (stop_reply_p) *stop_reply_queue; static void stop_reply_xfree (struct stop_reply *r) { - if (r != NULL) - { - VEC_free (cached_reg_t, r->regcache); - xfree (r); - } + notif_event_xfree ((struct notif_event *) r); } static void @@ -5375,7 +5369,7 @@ struct notif_client notif_client_stop = remote_notif_stop_ack, remote_notif_stop_can_get_pending_events, remote_notif_stop_alloc_reply, - NULL, + REMOTE_NOTIF_STOP, }; /* A parameter to pass data in and out. */ @@ -5386,18 +5380,19 @@ struct queue_iter_param struct stop_reply *output; }; -/* Remove all queue elements meet the condition it checks. */ +/* Remove stop replies in the queue if its pid is equal to the given + inferior's pid. */ static int -remote_notif_remove_all (QUEUE (stop_reply_p) *q, - QUEUE_ITER (stop_reply_p) *iter, - stop_reply_p event, - void *data) +remove_stop_reply_for_inferior (QUEUE (stop_reply_p) *q, + QUEUE_ITER (stop_reply_p) *iter, + stop_reply_p event, + void *data) { struct queue_iter_param *param = data; struct inferior *inf = param->input; - if (inf == NULL || ptid_get_pid (event->ptid) == inf->pid) + if (ptid_get_pid (event->ptid) == inf->pid) { stop_reply_xfree (event); QUEUE_remove_elem (stop_reply_p, q, iter); @@ -5406,24 +5401,29 @@ remote_notif_remove_all (QUEUE (stop_reply_p) *q, return 1; } -/* Discard all pending stop replies of inferior INF. If INF is NULL, - discard everything. */ +/* Discard all pending stop replies of inferior INF. */ static void discard_pending_stop_replies (struct inferior *inf) { int i; struct queue_iter_param param; - struct stop_reply *reply - = (struct stop_reply *) notif_client_stop.pending_event; + struct stop_reply *reply; + struct remote_state *rs = get_remote_state (); + struct remote_notif_state *rns = rs->notif_state; + + /* This function can be notified when an inferior exists. When the + target is not remote, the notification state is NULL. */ + if (rs->remote_desc == NULL) + return; + + reply = (struct stop_reply *) rns->pending_event[notif_client_stop.id]; /* Discard the in-flight notification. */ - if (reply != NULL - && (inf == NULL - || ptid_get_pid (reply->ptid) == inf->pid)) + if (reply != NULL && ptid_get_pid (reply->ptid) == inf->pid) { stop_reply_xfree (reply); - notif_client_stop.pending_event = NULL; + rns->pending_event[notif_client_stop.id] = NULL; } param.input = inf; @@ -5431,7 +5431,22 @@ discard_pending_stop_replies (struct inferior *inf) /* Discard the stop replies we have already pulled with vStopped. */ QUEUE_iterate (stop_reply_p, stop_reply_queue, - remote_notif_remove_all, ¶m); + remove_stop_reply_for_inferior, ¶m); +} + +/* Discard the stop replies in stop_reply_queue. */ + +static void +discard_pending_stop_replies_in_queue (void) +{ + struct queue_iter_param param; + + param.input = NULL; + param.output = NULL; + /* Discard the stop replies we have already pulled with + vStopped. */ + QUEUE_iterate (stop_reply_p, stop_reply_queue, + remove_stop_reply_for_inferior, ¶m); } /* A parameter to pass data in and out. */ @@ -5787,7 +5802,7 @@ remote_notif_get_pending_events (struct notif_client *nc) { struct remote_state *rs = get_remote_state (); - if (nc->pending_event) + if (rs->notif_state->pending_event[nc->id] != NULL) { if (notif_debug) fprintf_unfiltered (gdb_stdlog, @@ -5795,8 +5810,8 @@ remote_notif_get_pending_events (struct notif_client *nc) nc->name); /* acknowledge */ - nc->ack (nc, rs->buf, nc->pending_event); - nc->pending_event = NULL; + nc->ack (nc, rs->buf, rs->notif_state->pending_event[nc->id]); + rs->notif_state->pending_event[nc->id] = NULL; while (1) { @@ -5901,7 +5916,7 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options) /* Acknowledge a pending stop reply that may have arrived in the mean time. */ - if (notif_client_stop.pending_event != NULL) + if (rs->notif_state->pending_event[notif_client_stop.id] != NULL) remote_notif_get_pending_events (¬if_client_stop); /* If indeed we noticed a stop reply, we're done. */ |