2 * Server-side thread management
4 * Copyright (C) 1998 Alexandre Julliard
15 #ifdef HAVE_SYS_MMAN_H
18 #include <sys/ptrace.h>
19 #include <sys/types.h>
37 struct wait_queue_entry
39 struct wait_queue_entry *next;
40 struct wait_queue_entry *prev;
42 struct thread *thread;
47 int count; /* count of objects */
49 struct timeval timeout;
50 struct timeout_user *user;
51 struct wait_queue_entry queues[1];
54 /* asynchronous procedure calls */
58 void *func; /* function to call in client */
59 void *param; /* function param */
61 #define MAX_THREAD_APC 16 /* Max outstanding APCs for a thread */
64 /* thread operations */
66 static void dump_thread( struct object *obj, int verbose );
67 static int thread_signaled( struct object *obj, struct thread *thread );
68 static void destroy_thread( struct object *obj );
70 static const struct object_ops thread_ops =
72 sizeof(struct thread),
85 static const int use_ptrace = 1; /* set to 0 to disable ptrace */
86 static struct thread *first_thread;
88 /* allocate the buffer for the communication with the client */
89 static int alloc_client_buffer( struct thread *thread )
93 if ((fd = create_anonymous_file()) == -1) return -1;
94 if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error;
95 if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE,
96 MAP_SHARED, fd, 0 )) == (void*)-1) goto error;
101 if (fd != -1) close( fd );
105 /* create a new thread */
106 static struct thread *create_thread( int fd, struct process *process, int suspend )
108 struct thread *thread;
111 if (!(thread = alloc_object( &thread_ops ))) return NULL;
113 thread->client = NULL;
114 thread->unix_pid = 0; /* not known yet */
116 thread->mutex = NULL;
117 thread->debug_ctx = NULL;
118 thread->debug_first = NULL;
119 thread->debug_event = NULL;
122 thread->apc_count = 0;
124 thread->state = RUNNING;
125 thread->attached = 0;
126 thread->exit_code = 0x103; /* STILL_ACTIVE */
129 thread->priority = THREAD_PRIORITY_NORMAL;
130 thread->affinity = 1;
131 thread->suspend = (suspend != 0);
132 thread->buffer = (void *)-1;
133 thread->last_req = REQ_GET_THREAD_BUFFER;
135 if (!first_thread) /* creating the first thread */
138 thread->process = process = create_initial_process();
141 else thread->process = (struct process *)grab_object( process );
143 if ((thread->next = first_thread) != NULL) thread->next->prev = thread;
144 first_thread = thread;
145 add_process_thread( process, thread );
147 if ((buf_fd = alloc_client_buffer( thread )) == -1) goto error;
148 if (!(thread->client = add_client( fd, thread )))
153 set_reply_fd( thread, buf_fd ); /* send the fd to the client */
154 send_reply( thread );
158 remove_process_thread( process, thread );
159 release_object( thread );
163 /* create the initial thread and start the main server loop */
164 void create_initial_thread( int fd )
166 create_thread( fd, NULL, 0 );
170 /* destroy a thread when its refcount is 0 */
171 static void destroy_thread( struct object *obj )
173 struct thread *thread = (struct thread *)obj;
174 assert( obj->ops == &thread_ops );
176 assert( !thread->debug_ctx ); /* cannot still be debugging something */
177 release_object( thread->process );
178 if (thread->next) thread->next->prev = thread->prev;
179 if (thread->prev) thread->prev->next = thread->next;
180 else first_thread = thread->next;
181 if (thread->apc) free( thread->apc );
182 if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
185 /* dump a thread on stdout for debugging purposes */
186 static void dump_thread( struct object *obj, int verbose )
188 struct thread *thread = (struct thread *)obj;
189 assert( obj->ops == &thread_ops );
191 fprintf( stderr, "Thread pid=%d teb=%p state=%d\n",
192 thread->unix_pid, thread->teb, thread->state );
195 static int thread_signaled( struct object *obj, struct thread *thread )
197 struct thread *mythread = (struct thread *)obj;
198 return (mythread->state == TERMINATED);
201 /* get a thread pointer from a thread id (and increment the refcount) */
202 struct thread *get_thread_from_id( void *id )
204 struct thread *t = first_thread;
205 while (t && (t != id)) t = t->next;
206 if (t) grab_object( t );
210 /* get a thread from a handle (and increment the refcount) */
211 struct thread *get_thread_from_handle( int handle, unsigned int access )
213 return (struct thread *)get_handle_obj( current->process, handle,
214 access, &thread_ops );
217 /* set all information about a thread */
218 static void set_thread_info( struct thread *thread,
219 struct set_thread_info_request *req )
221 if (req->mask & SET_THREAD_INFO_PRIORITY)
222 thread->priority = req->priority;
223 if (req->mask & SET_THREAD_INFO_AFFINITY)
225 if (req->affinity != 1) set_error( ERROR_INVALID_PARAMETER );
226 else thread->affinity = req->affinity;
230 /* find a thread from a Unix pid */
231 static struct thread *get_thread_from_pid( int pid )
233 struct thread *t = first_thread;
234 while (t && (t->unix_pid != pid)) t = t->next;
238 /* wait for a ptraced child to get a certain signal */
239 /* if the signal is 0, we simply check if anything is pending and return at once */
240 void wait4_thread( struct thread *thread, int signal )
247 pid = thread ? thread->unix_pid : -1;
248 if ((pid = wait4( pid, &status, WUNTRACED | (signal ? 0 : WNOHANG), NULL )) == -1)
253 if (WIFSTOPPED(status))
255 int sig = WSTOPSIG(status);
256 if (debug_level) fprintf( stderr, "ptrace: pid %d got sig %d\n", pid, sig );
259 case SIGSTOP: /* continue at once if not suspended */
261 if (!(thread = get_thread_from_pid( pid ))) break;
262 if (!(thread->process->suspend + thread->suspend))
263 ptrace( PTRACE_CONT, pid, 0, sig );
265 default: /* ignore other signals for now */
266 ptrace( PTRACE_CONT, pid, 0, sig );
269 if (signal && sig != signal) goto restart;
271 else if (WIFSIGNALED(status))
273 int exit_code = WTERMSIG(status);
275 fprintf( stderr, "ptrace: pid %d killed by sig %d\n", pid, exit_code );
277 if (!(thread = get_thread_from_pid( pid ))) return;
278 if (thread->client) remove_client( thread->client, exit_code );
280 else if (WIFEXITED(status))
282 int exit_code = WEXITSTATUS(status);
284 fprintf( stderr, "ptrace: pid %d exited with status %d\n", pid, exit_code );
286 if (!(thread = get_thread_from_pid( pid ))) return;
287 if (thread->client) remove_client( thread->client, exit_code );
289 else fprintf( stderr, "wait4: pid %d unknown status %x\n", pid, status );
292 /* attach to a Unix thread */
293 static int attach_thread( struct thread *thread )
295 /* this may fail if the client is already being debugged */
296 if (!use_ptrace || (ptrace( PTRACE_ATTACH, thread->unix_pid, 0, 0 ) == -1)) return 0;
297 if (debug_level) fprintf( stderr, "ptrace: attached to pid %d\n", thread->unix_pid );
298 thread->attached = 1;
299 wait4_thread( thread, SIGSTOP );
303 /* detach from a Unix thread and kill it */
304 static void detach_thread( struct thread *thread )
306 if (!thread->unix_pid) return;
307 kill( thread->unix_pid, SIGTERM );
308 if (thread->suspend + thread->process->suspend) continue_thread( thread );
309 if (thread->attached)
311 wait4_thread( thread, SIGTERM );
312 if (debug_level) fprintf( stderr, "ptrace: detaching from %d\n", thread->unix_pid );
313 ptrace( PTRACE_DETACH, thread->unix_pid, 0, SIGTERM );
314 thread->attached = 0;
318 /* stop a thread (at the Unix level) */
319 void stop_thread( struct thread *thread )
321 if (!thread->unix_pid) return;
322 /* first try to attach to it */
323 if (!thread->attached)
324 if (attach_thread( thread )) return; /* this will have stopped it */
325 /* attached already, or attach failed -> send a signal */
326 kill( thread->unix_pid, SIGSTOP );
327 if (thread->attached) wait4_thread( thread, SIGSTOP );
330 /* make a thread continue (at the Unix level) */
331 void continue_thread( struct thread *thread )
333 if (!thread->unix_pid) return;
334 if (!thread->attached) kill( thread->unix_pid, SIGCONT );
335 else ptrace( PTRACE_CONT, thread->unix_pid, 0, SIGSTOP );
338 /* suspend a thread */
339 static int suspend_thread( struct thread *thread )
341 int old_count = thread->suspend;
342 if (thread->suspend < MAXIMUM_SUSPEND_COUNT)
344 if (!(thread->process->suspend + thread->suspend++)) stop_thread( thread );
349 /* resume a thread */
350 static int resume_thread( struct thread *thread )
352 int old_count = thread->suspend;
353 if (thread->suspend > 0)
355 if (!(--thread->suspend + thread->process->suspend)) continue_thread( thread );
360 /* suspend all threads but the current */
361 void suspend_all_threads( void )
363 struct thread *thread;
364 for ( thread = first_thread; thread; thread = thread->next )
365 if ( thread != current )
366 suspend_thread( thread );
369 /* resume all threads but the current */
370 void resume_all_threads( void )
372 struct thread *thread;
373 for ( thread = first_thread; thread; thread = thread->next )
374 if ( thread != current )
375 resume_thread( thread );
378 /* add a thread to an object wait queue; return 1 if OK, 0 on error */
379 int add_queue( struct object *obj, struct wait_queue_entry *entry )
383 entry->prev = obj->tail;
385 if (obj->tail) obj->tail->next = entry;
386 else obj->head = entry;
391 /* remove a thread from an object wait queue */
392 void remove_queue( struct object *obj, struct wait_queue_entry *entry )
394 if (entry->next) entry->next->prev = entry->prev;
395 else obj->tail = entry->prev;
396 if (entry->prev) entry->prev->next = entry->next;
397 else obj->head = entry->next;
398 release_object( obj );
402 static void end_wait( struct thread *thread )
404 struct thread_wait *wait = thread->wait;
405 struct wait_queue_entry *entry;
409 for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
410 entry->obj->ops->remove_queue( entry->obj, entry );
411 if (wait->user) remove_timeout_user( wait->user );
416 /* build the thread wait structure */
417 static int wait_on( struct thread *thread, int count,
418 int *handles, int flags, int timeout )
420 struct thread_wait *wait;
421 struct wait_queue_entry *entry;
425 if ((count < 0) || (count > MAXIMUM_WAIT_OBJECTS))
427 set_error( ERROR_INVALID_PARAMETER );
430 if (!(wait = mem_alloc( sizeof(*wait) + (count-1) * sizeof(*entry) ))) return 0;
435 if (flags & SELECT_TIMEOUT) make_timeout( &wait->timeout, timeout );
437 for (i = 0, entry = wait->queues; i < count; i++, entry++)
439 if (!(obj = get_handle_obj( thread->process, handles[i],
440 SYNCHRONIZE, NULL )))
446 entry->thread = thread;
447 if (!obj->ops->add_queue( obj, entry ))
453 release_object( obj );
458 /* check if the thread waiting condition is satisfied */
459 static int check_wait( struct thread *thread, int *signaled )
462 struct thread_wait *wait = thread->wait;
463 struct wait_queue_entry *entry = wait->queues;
466 if (wait->flags & SELECT_ALL)
469 /* Note: we must check them all anyway, as some objects may
470 * want to do something when signaled, even if others are not */
471 for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
472 not_ok |= !entry->obj->ops->signaled( entry->obj, thread );
473 if (not_ok) goto other_checks;
474 /* Wait satisfied: tell it to all objects */
476 for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
477 if (entry->obj->ops->satisfied( entry->obj, thread ))
478 *signaled = STATUS_ABANDONED_WAIT_0;
483 for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
485 if (!entry->obj->ops->signaled( entry->obj, thread )) continue;
486 /* Wait satisfied: tell it to the object */
488 if (entry->obj->ops->satisfied( entry->obj, thread ))
489 *signaled = i + STATUS_ABANDONED_WAIT_0;
495 if ((wait->flags & SELECT_ALERTABLE) && thread->apc)
497 *signaled = STATUS_USER_APC;
500 if (wait->flags & SELECT_TIMEOUT)
503 gettimeofday( &now, NULL );
504 if ((now.tv_sec > wait->timeout.tv_sec) ||
505 ((now.tv_sec == wait->timeout.tv_sec) &&
506 (now.tv_usec >= wait->timeout.tv_usec)))
508 *signaled = STATUS_TIMEOUT;
515 /* attempt to wake up a thread */
516 /* return 1 if OK, 0 if the wait condition is still not satisfied */
517 static int wake_thread( struct thread *thread )
519 struct select_request *req = get_req_ptr( thread );
521 if (!check_wait( thread, &req->signaled )) return 0;
526 /* sleep on a list of objects */
527 static void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
529 struct select_request *req;
530 assert( !thread->wait );
531 if (!wait_on( thread, count, handles, flags, timeout )) goto error;
532 if (wake_thread( thread )) return;
533 /* now we need to wait */
534 if (flags & SELECT_TIMEOUT)
536 if (!(thread->wait->user = add_timeout_user( &thread->wait->timeout,
537 call_timeout_handler, thread )))
540 thread->state = SLEEPING;
544 req = get_req_ptr( thread );
548 /* timeout for the current thread */
549 void thread_timeout(void)
551 struct select_request *req = get_req_ptr( current );
553 assert( current->wait );
554 current->wait->user = NULL;
556 req->signaled = STATUS_TIMEOUT;
557 send_reply( current );
560 /* attempt to wake threads sleeping on the object wait queue */
561 void wake_up( struct object *obj, int max )
563 struct wait_queue_entry *entry = obj->head;
567 struct thread *thread = entry->thread;
569 if (wake_thread( thread ))
571 send_reply( thread );
572 if (max && !--max) break;
577 /* queue an async procedure call */
578 static int thread_queue_apc( struct thread *thread, void *func, void *param )
580 struct thread_apc *apc;
583 if (!(thread->apc = mem_alloc( MAX_THREAD_APC * sizeof(*apc) )))
585 thread->apc_count = 0;
587 else if (thread->apc_count >= MAX_THREAD_APC) return 0;
588 thread->apc[thread->apc_count].func = func;
589 thread->apc[thread->apc_count].param = param;
593 if (wake_thread( thread )) send_reply( thread );
598 /* kill a thread on the spot */
599 void kill_thread( struct thread *thread, int exit_code )
601 if (thread->state == TERMINATED) return; /* already killed */
602 remove_client( thread->client, exit_code ); /* this will call thread_killed */
605 /* a thread has been killed */
606 void thread_killed( struct thread *thread, int exit_code )
608 thread->state = TERMINATED;
609 thread->exit_code = exit_code;
610 thread->client = NULL;
611 if (thread->wait) end_wait( thread );
612 debug_exit_thread( thread, exit_code );
613 abandon_mutexes( thread );
614 remove_process_thread( thread->process, thread );
615 wake_up( &thread->obj, 0 );
616 detach_thread( thread );
617 release_object( thread );
620 /* create a new thread */
621 DECL_HANDLER(new_thread)
623 struct thread *thread;
624 struct process *process;
626 if ((process = get_process_from_id( req->pid )))
628 if ((fd = dup(fd)) != -1)
630 if ((thread = create_thread( fd, process, req->suspend )))
633 if ((req->handle = alloc_handle( current->process, thread,
634 THREAD_ALL_ACCESS, req->inherit )) == -1)
635 release_object( thread );
636 /* else will be released when the thread gets killed */
640 else file_set_error();
641 release_object( process );
645 /* retrieve the thread buffer file descriptor */
646 DECL_HANDLER(get_thread_buffer)
648 fatal_protocol_error( current, "get_thread_buffer: should never get called directly\n" );
651 /* initialize a new thread */
652 DECL_HANDLER(init_thread)
654 if (current->unix_pid)
656 fatal_protocol_error( current, "init_thread: already running\n" );
659 current->unix_pid = req->unix_pid;
660 current->teb = req->teb;
661 if (current->suspend + current->process->suspend > 0) stop_thread( current );
662 req->pid = current->process;
666 /* terminate a thread */
667 DECL_HANDLER(terminate_thread)
669 struct thread *thread;
671 if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
673 kill_thread( thread, req->exit_code );
674 release_object( thread );
678 /* fetch information about a thread */
679 DECL_HANDLER(get_thread_info)
681 struct thread *thread;
683 if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
686 req->exit_code = thread->exit_code;
687 req->priority = thread->priority;
688 release_object( thread );
692 /* set information about a thread */
693 DECL_HANDLER(set_thread_info)
695 struct thread *thread;
697 if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
699 set_thread_info( thread, req );
700 release_object( thread );
704 /* suspend a thread */
705 DECL_HANDLER(suspend_thread)
707 struct thread *thread;
709 if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
711 req->count = suspend_thread( thread );
712 release_object( thread );
716 /* resume a thread */
717 DECL_HANDLER(resume_thread)
719 struct thread *thread;
721 if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
723 req->count = resume_thread( thread );
724 release_object( thread );
728 /* select on a handle list */
731 sleep_on( current, req->count, req->handles, req->flags, req->timeout );
734 /* queue an APC for a thread */
735 DECL_HANDLER(queue_apc)
737 struct thread *thread;
738 if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
740 thread_queue_apc( thread, req->func, req->param );
741 release_object( thread );
745 /* get list of APC to call */
746 DECL_HANDLER(get_apcs)
748 if ((req->count = current->apc_count))
750 memcpy( req->apcs, current->apc, current->apc_count * sizeof(*current->apc) );
751 free( current->apc );
753 current->apc_count = 0;