Commit f6507ed2 authored by Alexandre Julliard's avatar Alexandre Julliard

Do not send a debug event for a thread until the previous event for

the same thread has been continued.
parent 08b289d7
......@@ -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;
......
......@@ -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)
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment