From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32323 invoked by alias); 30 Sep 2013 07:58:03 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 32312 invoked by uid 89); 30 Sep 2013 07:58:03 -0000 Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 30 Sep 2013 07:58:03 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.5 required=5.0 tests=AWL,BAYES_00,GARBLED_BODY,RDNS_NONE,SPF_HELO_FAIL autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1VQYMg-0002O5-Hq from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Mon, 30 Sep 2013 00:57:58 -0700 Received: from SVR-ORW-FEM-03.mgc.mentorg.com ([147.34.97.39]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 30 Sep 2013 00:57:58 -0700 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.2.247.3; Mon, 30 Sep 2013 00:57:57 -0700 Message-ID: <52492EAE.5030802@codesourcery.com> Date: Mon, 30 Sep 2013 07:58:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130110 Thunderbird/17.0.2 MIME-Version: 1.0 To: Subject: Move pending_event to remote_notif_state ([PATCH 1/6] Move notif_queue to remote_state) References: <1376877311-4135-1-git-send-email-yao@codesourcery.com> <1376877311-4135-2-git-send-email-yao@codesourcery.com> <52430B69.4090301@redhat.com> <5249293D.8050700@codesourcery.com> In-Reply-To: <5249293D.8050700@codesourcery.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2013-09/txt/msg01000.txt.bz2 On 09/30/2013 03:33 PM, Yao Qi wrote: > The pending event should be connection-local. I'll post a patch to move > pending event to remote_notif_state too. This patch moves pending_event to remote_notif_state. Each remote_notif_state has an array of pending_event for all notif_client. 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 used to be attached to ifnerior_exit observer, so the INF can't be NULL any more. The NULL checking is removed too. -- Yao (齐尧) gdb: 2013-09-30 Yao Qi * remote-notif.h (REMOTE_NOTIF_ID): New enum. (struct notif_client) : Moved to struct remote_notif_state. : New field. (struct remote_notif_state) : 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_allocate): Clear pending_event. (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. --- gdb/remote-notif.c | 31 +++++++++++++++----- gdb/remote-notif.h | 28 ++++++++++++++----- gdb/remote.c | 76 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/gdb/remote-notif.c b/gdb/remote-notif.c index 0bec097..a0225b7 100644 --- a/gdb/remote-notif.c +++ b/gdb/remote-notif.c @@ -51,6 +51,8 @@ static struct notif_client *notifs[] = ¬if_client_stop, }; +gdb_static_assert (ARRAY_SIZE (notifs) == REMOTE_NOTIF_LAST); + static void do_notif_event_xfree (void *arg); /* Parse the BUF for the expected notification NC, and send packet to @@ -141,7 +143,7 @@ handle_notification (struct remote_notif_state *state, char *buf) if (nc == NULL) return; - if (nc->pending_event) + if (state->pending_event[nc->id] != NULL) { /* We've already parsed the in-flight reply, but the stub for some reason thought we didn't, possibly due to timeout on its side. @@ -157,7 +159,7 @@ handle_notification (struct remote_notif_state *state, char *buf) /* Be careful to only set it after parsing, since an error may be thrown then. */ - nc->pending_event = event; + state->pending_event[nc->id] = event; /* Notify the event loop there's a stop reply to acknowledge and that there may be more events to fetch. */ @@ -210,19 +212,25 @@ handle_notification (struct remote_notif_state *state, char *buf) } } -/* Cleanup wrapper. */ +/* Invoke destructor of EVENT and xfree it. */ -static void -do_notif_event_xfree (void *arg) +void +notif_event_xfree (struct notif_event *event) { - struct notif_event *event = arg; - - if (event && event->dtr) + if (event != NULL && event->dtr != NULL) event->dtr (event); xfree (event); } +/* Cleanup wrapper. */ + +static void +do_notif_event_xfree (void *arg) +{ + notif_event_xfree (arg); +} + /* Return an allocated remote_notif_state. */ struct remote_notif_state * @@ -238,6 +246,8 @@ remote_notif_state_allocate (void) = create_async_event_handler (remote_async_get_pending_events_handler, notif_state); + memset (notif_state->pending_event, 0, sizeof (notif_state->pending_event)); + return notif_state; } @@ -246,12 +256,17 @@ remote_notif_state_allocate (void) void remote_notif_state_xfree (struct remote_notif_state *state) { + int i; + QUEUE_free (notif_client_p, state->notif_queue); /* Unregister async_event_handler for notification. */ if (state->remote_async_get_pending_events_token != NULL) delete_async_event_handler (&state->remote_async_get_pending_events_token); + for (i = 0; i < REMOTE_NOTIF_LAST; i++) + notif_event_xfree (state->pending_event[i]); + xfree (state); } diff --git a/gdb/remote-notif.h b/gdb/remote-notif.h index fbb1b3b..6c8f60b 100644 --- a/gdb/remote-notif.h +++ b/gdb/remote-notif.h @@ -31,6 +31,14 @@ struct notif_event void (*dtr) (struct notif_event *self); }; +/* ID of the notif_client. */ + +enum REMOTE_NOTIF_ID +{ + REMOTE_NOTIF_STOP = 0, + REMOTE_NOTIF_LAST, +}; + /* A client to a sort of async remote notification. */ typedef struct notif_client @@ -59,13 +67,8 @@ typedef struct notif_client /* Allocate an event. */ struct notif_event *(*alloc_event) (void); - /* One pending event. This is where we keep it until it is - acknowledged. When there is a notification packet, parse it, - and create an object of 'struct notif_event' to assign to - it. This field is unchanged until GDB starts to ack this - notification (which is done by - remote.c:remote_notif_pending_replies). */ - struct notif_event *pending_event; + /* Id of this notif_client. */ + const enum REMOTE_NOTIF_ID id; } *notif_client_p; DECLARE_QUEUE_P (notif_client_p); @@ -83,12 +86,23 @@ struct remote_notif_state the remote side into our event queue. */ struct async_event_handler *remote_async_get_pending_events_token; + +/* One pending event for each notification client. This is where we + keep it until it is acknowledged. When there is a notification + packet, parse it, and create an object of 'struct notif_event' to + assign to it. This field is unchanged until GDB starts to ack + this notification (which is done by + remote.c:remote_notif_pending_replies). */ + + struct notif_event *pending_event[REMOTE_NOTIF_LAST]; }; void remote_notif_ack (struct notif_client *nc, char *buf); struct notif_event *remote_notif_parse (struct notif_client *nc, char *buf); +void notif_event_xfree (struct notif_event *event); + void handle_notification (struct remote_notif_state *notif_state, char *buf); diff --git a/gdb/remote.c b/gdb/remote.c index 6ac3f51..8a07c97 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); @@ -5414,16 +5409,22 @@ 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 (rns == 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 +5432,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 +5803,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 +5811,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 +5917,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. */ -- 1.7.7.6