From f6507ed2354e8509b71691c4248faaca879387ae Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 6 Apr 2000 22:05:16 +0000 Subject: [PATCH] Do not send a debug event for a thread until the previous event for the same thread has been continued. --- server/debugger.c | 33 +++++++++++++++++++++------------ server/thread.c | 3 ++- server/thread.h | 2 ++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/server/debugger.c b/server/debugger.c index ccfbd502bc1..e9292552c35 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -36,7 +36,6 @@ struct debug_ctx struct object obj; /* object header */ struct debug_event *event_head; /* head of pending events queue */ struct debug_event *event_tail; /* tail of pending events queue */ - struct debug_event *to_send; /* next event on the queue to send to debugger */ }; @@ -216,8 +215,8 @@ static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event else debug_ctx->event_head = event->next; if (event->next) event->next->prev = event->prev; else debug_ctx->event_tail = event->prev; - if (debug_ctx->to_send == event) debug_ctx->to_send = event->next; event->next = event->prev = NULL; + if (event->sender->debug_event == event) event->sender->debug_event = NULL; release_object( event ); } @@ -230,11 +229,20 @@ static void link_event( struct debug_ctx *debug_ctx, struct debug_event *event ) debug_ctx->event_tail = event; if (event->prev) event->prev->next = event; else debug_ctx->event_head = event; - if (!debug_ctx->to_send) + if (!event->sender->debug_event) wake_up( &debug_ctx->obj, 0 ); +} + +/* find the next event that we can send to the debugger */ +static struct debug_event *find_event_to_send( struct debug_ctx *debug_ctx ) +{ + struct debug_event *event; + for (event = debug_ctx->event_head; event; event = event->next) { - debug_ctx->to_send = event; - wake_up( &debug_ctx->obj, 0 ); + if (event->state == EVENT_SENT) continue; /* already sent */ + if (event->sender->debug_event) continue; /* thread busy with another one */ + break; } + return event; } /* build a reply for the wait_debug_event request */ @@ -245,14 +253,14 @@ static void build_wait_debug_reply( struct thread *thread, struct object *obj, i if (obj) { struct debug_ctx *debug_ctx = (struct debug_ctx *)obj; - struct debug_event *event = debug_ctx->to_send; + struct debug_event *event = find_event_to_send( debug_ctx ); /* the object that woke us has to be our debug context */ assert( obj->ops == &debug_ctx_ops ); assert( event ); event->state = EVENT_SENT; - debug_ctx->to_send = event->next; + event->sender->debug_event = event; req->event.code = event->data.code; req->pid = event->sender->process; req->tid = event->sender; @@ -330,15 +338,15 @@ static void debug_ctx_dump( struct object *obj, int verbose ) { struct debug_ctx *debug_ctx = (struct debug_ctx *)obj; assert( obj->ops == &debug_ctx_ops ); - fprintf( stderr, "Debug context head=%p tail=%p to_send=%p\n", - debug_ctx->event_head, debug_ctx->event_tail, debug_ctx->to_send ); + fprintf( stderr, "Debug context head=%p tail=%p\n", + debug_ctx->event_head, debug_ctx->event_tail ); } static int debug_ctx_signaled( struct object *obj, struct thread *thread ) { struct debug_ctx *debug_ctx = (struct debug_ctx *)obj; assert( obj->ops == &debug_ctx_ops ); - return debug_ctx->to_send != NULL; + return find_event_to_send( debug_ctx ) != NULL; } static void debug_ctx_destroy( struct object *obj ) @@ -378,11 +386,13 @@ static int continue_debug_event( struct process *process, struct thread *thread, /* find the event in the queue */ for (event = debug_ctx->event_head; event; event = event->next) { - if (event == debug_ctx->to_send) goto error; + if (event->state != EVENT_SENT) continue; if (event->sender == thread) break; } if (!event) goto error; + assert( event->sender->debug_event == event ); + event->status = status; event->state = EVENT_CONTINUED; wake_up( &event->obj, 0 ); @@ -503,7 +513,6 @@ int set_process_debugger( struct process *process, struct thread *debugger ) if (!(debug_ctx = alloc_object( &debug_ctx_ops, -1 ))) return 0; debug_ctx->event_head = NULL; debug_ctx->event_tail = NULL; - debug_ctx->to_send = NULL; debugger->debug_ctx = debug_ctx; } process->debugger = debugger; diff --git a/server/thread.c b/server/thread.c index e205eaa5fe0..72c1fce7bdf 100644 --- a/server/thread.c +++ b/server/thread.c @@ -130,6 +130,7 @@ struct thread *create_thread( int fd, struct process *process, int suspend ) thread->teb = NULL; thread->mutex = NULL; thread->debug_ctx = NULL; + thread->debug_event = NULL; thread->wait = NULL; thread->apc = NULL; thread->apc_count = 0; @@ -584,7 +585,7 @@ void kill_thread( struct thread *thread, int violent_death ) /* signal that we are finished booting on the client side */ DECL_HANDLER(boot_done) { - debug_level = req->debug_level; + debug_level = max( debug_level, req->debug_level ); /* Make sure last_req is initialized */ current->last_req = REQ_BOOT_DONE; if (current == booting_thread) diff --git a/server/thread.h b/server/thread.h index d851d462f6f..2913a4234b0 100644 --- a/server/thread.h +++ b/server/thread.h @@ -20,6 +20,7 @@ struct thread_wait; struct thread_apc; struct mutex; struct debug_ctx; +struct debug_event; enum run_state { @@ -38,6 +39,7 @@ struct thread struct process *process; struct mutex *mutex; /* list of currently owned mutexes */ struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */ + struct debug_event *debug_event; /* debug event being sent to debugger */ struct thread_wait *wait; /* current wait condition if sleeping */ struct thread_apc *apc; /* list of async procedure calls */ int apc_count; /* number of outstanding APCs */