Fill in some DirectDrawPalette HAL fields.
[wine] / server / thread.c
1 /*
2  * Server-side thread management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include "config.h"
8
9 #include <assert.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <stdarg.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #ifdef HAVE_SYS_MMAN_H
18 #include <sys/mman.h>
19 #endif
20 #include <sys/types.h>
21 #include <unistd.h>
22 #include <stdarg.h>
23
24 #include "winbase.h"
25
26 #include "handle.h"
27 #include "process.h"
28 #include "thread.h"
29 #include "request.h"
30
31
32 /* thread queues */
33
34 struct thread_wait
35 {
36     struct thread_wait     *next;       /* next wait structure for this thread */
37     struct thread          *thread;     /* owner thread */
38     int                     count;      /* count of objects */
39     int                     flags;
40     void                   *cookie;     /* magic cookie to return to client */
41     struct timeval          timeout;
42     struct timeout_user    *user;
43     struct wait_queue_entry queues[1];
44 };
45
46 /* asynchronous procedure calls */
47
48 struct thread_apc
49 {
50     struct thread_apc  *next;     /* queue linked list */
51     struct thread_apc  *prev;
52     struct object      *owner;    /* object that queued this apc */
53     void               *func;     /* function to call in client */
54     enum apc_type       type;     /* type of apc function */
55     int                 nb_args;  /* number of arguments */
56     void               *args[1];  /* function arguments */
57 };
58
59
60 /* thread operations */
61
62 static void dump_thread( struct object *obj, int verbose );
63 static int thread_signaled( struct object *obj, struct thread *thread );
64 static void thread_poll_event( struct object *obj, int event );
65 static void destroy_thread( struct object *obj );
66 static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only );
67
68 static const struct object_ops thread_ops =
69 {
70     sizeof(struct thread),      /* size */
71     dump_thread,                /* dump */
72     add_queue,                  /* add_queue */
73     remove_queue,               /* remove_queue */
74     thread_signaled,            /* signaled */
75     no_satisfied,               /* satisfied */
76     NULL,                       /* get_poll_events */
77     thread_poll_event,          /* poll_event */
78     no_get_fd,                  /* get_fd */
79     no_flush,                   /* flush */
80     no_get_file_info,           /* get_file_info */
81     destroy_thread              /* destroy */
82 };
83
84 static struct thread *first_thread;
85 static struct thread *booting_thread;
86
87 /* initialize the structure for a newly allocated thread */
88 inline static void init_thread_structure( struct thread *thread )
89 {
90     int i;
91
92     thread->unix_pid        = 0;  /* not known yet */
93     thread->context         = NULL;
94     thread->teb             = NULL;
95     thread->mutex           = NULL;
96     thread->debug_ctx       = NULL;
97     thread->debug_event     = NULL;
98     thread->queue           = NULL;
99     thread->info            = NULL;
100     thread->wait            = NULL;
101     thread->system_apc.head = NULL;
102     thread->system_apc.tail = NULL;
103     thread->user_apc.head   = NULL;
104     thread->user_apc.tail   = NULL;
105     thread->error           = 0;
106     thread->request_fd      = NULL;
107     thread->reply_fd        = -1;
108     thread->wait_fd         = -1;
109     thread->state           = RUNNING;
110     thread->attached        = 0;
111     thread->exit_code       = 0;
112     thread->next            = NULL;
113     thread->prev            = NULL;
114     thread->priority        = THREAD_PRIORITY_NORMAL;
115     thread->affinity        = 1;
116     thread->suspend         = 0;
117     thread->buffer          = (void *)-1;
118
119     for (i = 0; i < MAX_INFLIGHT_FDS; i++)
120         thread->inflight[i].server = thread->inflight[i].client = -1;
121 }
122
123 /* create a new thread */
124 struct thread *create_thread( int fd, struct process *process )
125 {
126     struct thread *thread;
127
128     if (!(thread = alloc_object( &thread_ops, fd ))) return NULL;
129
130     init_thread_structure( thread );
131
132     thread->process = (struct process *)grab_object( process );
133     if (!current) current = thread;
134
135     if (!booting_thread)  /* first thread ever */
136     {
137         booting_thread = thread;
138         lock_master_socket(1);
139     }
140
141     if ((thread->next = first_thread) != NULL) thread->next->prev = thread;
142     first_thread = thread;
143
144     fcntl( fd, F_SETFL, O_NONBLOCK );
145     set_select_events( &thread->obj, POLLIN );  /* start listening to events */
146     add_process_thread( thread->process, thread );
147     return thread;
148 }
149
150 /* handle a client event */
151 static void thread_poll_event( struct object *obj, int event )
152 {
153     struct thread *thread = (struct thread *)obj;
154     assert( obj->ops == &thread_ops );
155
156     if (event & (POLLERR | POLLHUP)) kill_thread( thread, 0 );
157     else if (event & POLLIN) read_request( thread );
158 }
159
160 /* cleanup everything that is no longer needed by a dead thread */
161 /* used by destroy_thread and kill_thread */
162 static void cleanup_thread( struct thread *thread )
163 {
164     int i;
165     struct thread_apc *apc;
166
167     while ((apc = thread_dequeue_apc( thread, 0 ))) free( apc );
168     if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
169     if (thread->reply_fd != -1) close( thread->reply_fd );
170     if (thread->wait_fd != -1) close( thread->wait_fd );
171     if (thread->request_fd) release_object( thread->request_fd );
172     for (i = 0; i < MAX_INFLIGHT_FDS; i++)
173     {
174         if (thread->inflight[i].client != -1)
175         {
176             close( thread->inflight[i].server );
177             thread->inflight[i].client = thread->inflight[i].server = -1;
178         }
179     }
180     thread->buffer = (void *)-1;
181     thread->reply_fd = -1;
182     thread->wait_fd = -1;
183     thread->request_fd = NULL;
184 }
185
186 /* destroy a thread when its refcount is 0 */
187 static void destroy_thread( struct object *obj )
188 {
189     struct thread_apc *apc;
190     struct thread *thread = (struct thread *)obj;
191     assert( obj->ops == &thread_ops );
192
193     assert( !thread->debug_ctx );  /* cannot still be debugging something */
194     release_object( thread->process );
195     if (thread->next) thread->next->prev = thread->prev;
196     if (thread->prev) thread->prev->next = thread->next;
197     else first_thread = thread->next;
198     while ((apc = thread_dequeue_apc( thread, 0 ))) free( apc );
199     if (thread->info) release_object( thread->info );
200     if (thread->queue) release_object( thread->queue );
201     cleanup_thread( thread );
202 }
203
204 /* dump a thread on stdout for debugging purposes */
205 static void dump_thread( struct object *obj, int verbose )
206 {
207     struct thread *thread = (struct thread *)obj;
208     assert( obj->ops == &thread_ops );
209
210     fprintf( stderr, "Thread pid=%d teb=%p state=%d\n",
211              thread->unix_pid, thread->teb, thread->state );
212 }
213
214 static int thread_signaled( struct object *obj, struct thread *thread )
215 {
216     struct thread *mythread = (struct thread *)obj;
217     return (mythread->state == TERMINATED);
218 }
219
220 /* get a thread pointer from a thread id (and increment the refcount) */
221 struct thread *get_thread_from_id( void *id )
222 {
223     struct thread *t = first_thread;
224     while (t && (t != id)) t = t->next;
225     if (t) grab_object( t );
226     return t;
227 }
228
229 /* get a thread from a handle (and increment the refcount) */
230 struct thread *get_thread_from_handle( handle_t handle, unsigned int access )
231 {
232     return (struct thread *)get_handle_obj( current->process, handle,
233                                             access, &thread_ops );
234 }
235
236 /* find a thread from a Unix pid */
237 struct thread *get_thread_from_pid( int pid )
238 {
239     struct thread *t = first_thread;
240     while (t && (t->unix_pid != pid)) t = t->next;
241     return t;
242 }
243
244 /* set all information about a thread */
245 static void set_thread_info( struct thread *thread,
246                              struct set_thread_info_request *req )
247 {
248     if (req->mask & SET_THREAD_INFO_PRIORITY)
249         thread->priority = req->priority;
250     if (req->mask & SET_THREAD_INFO_AFFINITY)
251     {
252         if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
253         else thread->affinity = req->affinity;
254     }
255 }
256
257 /* suspend a thread */
258 int suspend_thread( struct thread *thread, int check_limit )
259 {
260     int old_count = thread->suspend;
261     if (thread->suspend < MAXIMUM_SUSPEND_COUNT || !check_limit)
262     {
263         if (!(thread->process->suspend + thread->suspend++)) stop_thread( thread );
264     }
265     else set_error( STATUS_SUSPEND_COUNT_EXCEEDED );
266     return old_count;
267 }
268
269 /* resume a thread */
270 int resume_thread( struct thread *thread )
271 {
272     int old_count = thread->suspend;
273     if (thread->suspend > 0)
274     {
275         if (!(--thread->suspend + thread->process->suspend)) continue_thread( thread );
276     }
277     return old_count;
278 }
279
280 /* suspend all threads but the current */
281 void suspend_all_threads( void )
282 {
283     struct thread *thread;
284     for ( thread = first_thread; thread; thread = thread->next )
285         if ( thread != current )
286             suspend_thread( thread, 0 );
287 }
288
289 /* resume all threads but the current */
290 void resume_all_threads( void )
291 {
292     struct thread *thread;
293     for ( thread = first_thread; thread; thread = thread->next )
294         if ( thread != current )
295             resume_thread( thread );
296 }
297
298 /* add a thread to an object wait queue; return 1 if OK, 0 on error */
299 int add_queue( struct object *obj, struct wait_queue_entry *entry )
300 {
301     grab_object( obj );
302     entry->obj    = obj;
303     entry->prev   = obj->tail;
304     entry->next   = NULL;
305     if (obj->tail) obj->tail->next = entry;
306     else obj->head = entry;
307     obj->tail = entry;
308     return 1;
309 }
310
311 /* remove a thread from an object wait queue */
312 void remove_queue( struct object *obj, struct wait_queue_entry *entry )
313 {
314     if (entry->next) entry->next->prev = entry->prev;
315     else obj->tail = entry->prev;
316     if (entry->prev) entry->prev->next = entry->next;
317     else obj->head = entry->next;
318     release_object( obj );
319 }
320
321 /* finish waiting */
322 static void end_wait( struct thread *thread )
323 {
324     struct thread_wait *wait = thread->wait;
325     struct wait_queue_entry *entry;
326     int i;
327
328     assert( wait );
329     for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
330         entry->obj->ops->remove_queue( entry->obj, entry );
331     if (wait->user) remove_timeout_user( wait->user );
332     thread->wait = wait->next;
333     free( wait );
334 }
335
336 /* build the thread wait structure */
337 static int wait_on( int count, struct object *objects[], int flags, int sec, int usec )
338 {
339     struct thread_wait *wait;
340     struct wait_queue_entry *entry;
341     int i;
342
343     if (!(wait = mem_alloc( sizeof(*wait) + (count-1) * sizeof(*entry) ))) return 0;
344     wait->next    = current->wait;
345     wait->thread  = current;
346     wait->count   = count;
347     wait->flags   = flags;
348     wait->user    = NULL;
349     current->wait = wait;
350     if (flags & SELECT_TIMEOUT)
351     {
352         wait->timeout.tv_sec = sec;
353         wait->timeout.tv_usec = usec;
354     }
355
356     for (i = 0, entry = wait->queues; i < count; i++, entry++)
357     {
358         struct object *obj = objects[i];
359         entry->thread = current;
360         if (!obj->ops->add_queue( obj, entry ))
361         {
362             wait->count = i;
363             end_wait( current );
364             return 0;
365         }
366     }
367     return 1;
368 }
369
370 /* check if the thread waiting condition is satisfied */
371 static int check_wait( struct thread *thread )
372 {
373     int i, signaled;
374     struct thread_wait *wait = thread->wait;
375     struct wait_queue_entry *entry = wait->queues;
376
377     assert( wait );
378     if (wait->flags & SELECT_ALL)
379     {
380         int not_ok = 0;
381         /* Note: we must check them all anyway, as some objects may
382          * want to do something when signaled, even if others are not */
383         for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
384             not_ok |= !entry->obj->ops->signaled( entry->obj, thread );
385         if (not_ok) goto other_checks;
386         /* Wait satisfied: tell it to all objects */
387         signaled = 0;
388         for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
389             if (entry->obj->ops->satisfied( entry->obj, thread ))
390                 signaled = STATUS_ABANDONED_WAIT_0;
391         return signaled;
392     }
393     else
394     {
395         for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
396         {
397             if (!entry->obj->ops->signaled( entry->obj, thread )) continue;
398             /* Wait satisfied: tell it to the object */
399             signaled = i;
400             if (entry->obj->ops->satisfied( entry->obj, thread ))
401                 signaled = i + STATUS_ABANDONED_WAIT_0;
402             return signaled;
403         }
404     }
405
406  other_checks:
407     if ((wait->flags & SELECT_INTERRUPTIBLE) && thread->system_apc.head) return STATUS_USER_APC;
408     if ((wait->flags & SELECT_ALERTABLE) && thread->user_apc.head) return STATUS_USER_APC;
409     if (wait->flags & SELECT_TIMEOUT)
410     {
411         struct timeval now;
412         gettimeofday( &now, NULL );
413         if (!time_before( &now, &wait->timeout )) return STATUS_TIMEOUT;
414     }
415     return -1;
416 }
417
418 /* send the wakeup signal to a thread */
419 static int send_thread_wakeup( struct thread *thread, void *cookie, int signaled )
420 {
421     struct wake_up_reply reply;
422     int ret;
423
424     reply.cookie   = cookie;
425     reply.signaled = signaled;
426     if ((ret = write( thread->wait_fd, &reply, sizeof(reply) )) == sizeof(reply)) return 0;
427     if (ret >= 0)
428         fatal_protocol_error( thread, "partial wakeup write %d\n", ret );
429     else if (errno == EPIPE)
430         kill_thread( thread, 0 );  /* normal death */
431     else
432         fatal_protocol_perror( thread, "write" );
433     return -1;
434 }
435
436 /* attempt to wake up a thread */
437 /* return >0 if OK, 0 if the wait condition is still not satisfied */
438 static int wake_thread( struct thread *thread )
439 {
440     int signaled, count;
441     void *cookie;
442
443     for (count = 0; thread->wait; count++)
444     {
445         if ((signaled = check_wait( thread )) == -1) break;
446
447         cookie = thread->wait->cookie;
448         if (debug_level) fprintf( stderr, "%08x: *wakeup* signaled=%d cookie=%p\n",
449                                   (unsigned int)thread, signaled, cookie );
450         end_wait( thread );
451         send_thread_wakeup( thread, cookie, signaled );
452     }
453     return count;
454 }
455
456 /* thread wait timeout */
457 static void thread_timeout( void *ptr )
458 {
459     struct thread_wait *wait = ptr;
460     struct thread *thread = wait->thread;
461     void *cookie = wait->cookie;
462
463     wait->user = NULL;
464     if (thread->wait != wait) return; /* not the top-level wait, ignore it */
465
466     if (debug_level) fprintf( stderr, "%08x: *wakeup* signaled=%d cookie=%p\n",
467                               (unsigned int)thread, STATUS_TIMEOUT, cookie );
468     end_wait( thread );
469     send_thread_wakeup( thread, cookie, STATUS_TIMEOUT );
470     /* check if other objects have become signaled in the meantime */
471     wake_thread( thread );
472 }
473
474 /* select on a list of handles */
475 static void select_on( int count, void *cookie, handle_t *handles, int flags, int sec, int usec )
476 {
477     int ret, i;
478     struct object *objects[MAXIMUM_WAIT_OBJECTS];
479
480     if ((count < 0) || (count > MAXIMUM_WAIT_OBJECTS))
481     {
482         set_error( STATUS_INVALID_PARAMETER );
483         return;
484     }
485     for (i = 0; i < count; i++)
486     {
487         if (!(objects[i] = get_handle_obj( current->process, handles[i], SYNCHRONIZE, NULL )))
488             break;
489     }
490
491     if (i < count) goto done;
492     if (!wait_on( count, objects, flags, sec, usec )) goto done;
493
494     if ((ret = check_wait( current )) != -1)
495     {
496         /* condition is already satisfied */
497         end_wait( current );
498         set_error( ret );
499         goto done;
500     }
501
502     /* now we need to wait */
503     if (flags & SELECT_TIMEOUT)
504     {
505         if (!(current->wait->user = add_timeout_user( &current->wait->timeout,
506                                                       thread_timeout, current->wait )))
507         {
508             end_wait( current );
509             goto done;
510         }
511     }
512     current->wait->cookie = cookie;
513     set_error( STATUS_PENDING );
514
515 done:
516     while (--i >= 0) release_object( objects[i] );
517 }
518
519 /* attempt to wake threads sleeping on the object wait queue */
520 void wake_up( struct object *obj, int max )
521 {
522     struct wait_queue_entry *entry = obj->head;
523
524     while (entry)
525     {
526         struct thread *thread = entry->thread;
527         entry = entry->next;
528         if (wake_thread( thread ))
529         {
530             if (max && !--max) break;
531         }
532     }
533 }
534
535 /* queue an async procedure call */
536 int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
537                       enum apc_type type, int system, int nb_args, ... )
538 {
539     struct thread_apc *apc;
540     struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
541
542     /* cancel a possible previous APC with the same owner */
543     if (owner) thread_cancel_apc( thread, owner, system );
544
545     if (!(apc = mem_alloc( sizeof(*apc) + (nb_args-1)*sizeof(apc->args[0]) ))) return 0;
546     apc->prev    = queue->tail;
547     apc->next    = NULL;
548     apc->owner   = owner;
549     apc->func    = func;
550     apc->type    = type;
551     apc->nb_args = nb_args;
552     if (nb_args)
553     {
554         int i;
555         va_list args;
556         va_start( args, nb_args );
557         for (i = 0; i < nb_args; i++) apc->args[i] = va_arg( args, void * );
558         va_end( args );
559     }
560     queue->tail = apc;
561     if (!apc->prev)  /* first one */
562     {
563         queue->head = apc;
564         wake_thread( thread );
565     }
566     return 1;
567 }
568
569 /* cancel the async procedure call owned by a specific object */
570 void thread_cancel_apc( struct thread *thread, struct object *owner, int system )
571 {
572     struct thread_apc *apc;
573     struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
574     for (apc = queue->head; apc; apc = apc->next)
575     {
576         if (apc->owner != owner) continue;
577         if (apc->next) apc->next->prev = apc->prev;
578         else queue->tail = apc->prev;
579         if (apc->prev) apc->prev->next = apc->next;
580         else queue->head = apc->next;
581         free( apc );
582         return;
583     }
584 }
585
586 /* remove the head apc from the queue; the returned pointer must be freed by the caller */
587 static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only )
588 {
589     struct thread_apc *apc;
590     struct apc_queue *queue = &thread->system_apc;
591
592     if (!queue->head && !system_only) queue = &thread->user_apc;
593     if ((apc = queue->head))
594     {
595         if (apc->next) apc->next->prev = NULL;
596         else queue->tail = NULL;
597         queue->head = apc->next;
598     }
599     return apc;
600 }
601
602 /* add an fd to the inflight list */
603 /* return list index, or -1 on error */
604 int thread_add_inflight_fd( struct thread *thread, int client, int server )
605 {
606     int i;
607
608     if (server == -1) return -1;
609     if (client == -1)
610     {
611         close( server );
612         return -1;
613     }
614
615     /* first check if we already have an entry for this fd */
616     for (i = 0; i < MAX_INFLIGHT_FDS; i++)
617         if (thread->inflight[i].client == client)
618         {
619             close( thread->inflight[i].server );
620             thread->inflight[i].server = server;
621             return i;
622         }
623
624     /* now find a free spot to store it */
625     for (i = 0; i < MAX_INFLIGHT_FDS; i++)
626         if (thread->inflight[i].client == -1)
627         {
628             thread->inflight[i].client = client;
629             thread->inflight[i].server = server;
630             return i;
631         }
632     return -1;
633 }
634
635 /* get an inflight fd and purge it from the list */
636 /* the fd must be closed when no longer used */
637 int thread_get_inflight_fd( struct thread *thread, int client )
638 {
639     int i, ret;
640
641     if (client == -1) return -1;
642
643     do
644     {
645         for (i = 0; i < MAX_INFLIGHT_FDS; i++)
646         {
647             if (thread->inflight[i].client == client)
648             {
649                 ret = thread->inflight[i].server;
650                 thread->inflight[i].server = thread->inflight[i].client = -1;
651                 return ret;
652             }
653         }
654     } while (!receive_fd( thread->process ));  /* in case it is still in the socket buffer */
655     return -1;
656 }
657
658 /* retrieve an LDT selector entry */
659 static void get_selector_entry( struct thread *thread, int entry,
660                                 unsigned int *base, unsigned int *limit,
661                                 unsigned char *flags )
662 {
663     if (!thread->process->ldt_copy)
664     {
665         set_error( STATUS_ACCESS_DENIED );
666         return;
667     }
668     if (entry >= 8192)
669     {
670         set_error( STATUS_INVALID_PARAMETER );  /* FIXME */
671         return;
672     }
673     if (suspend_for_ptrace( thread ))
674     {
675         unsigned char flags_buf[4];
676         int *addr = (int *)thread->process->ldt_copy + entry;
677         if (read_thread_int( thread, addr, base ) == -1) goto done;
678         if (read_thread_int( thread, addr + 8192, limit ) == -1) goto done;
679         addr = (int *)thread->process->ldt_copy + 2*8192 + (entry >> 2);
680         if (read_thread_int( thread, addr, (int *)flags_buf ) == -1) goto done;
681         *flags = flags_buf[entry & 3];
682     done:
683         resume_thread( thread );
684     }
685 }
686
687 /* kill a thread on the spot */
688 void kill_thread( struct thread *thread, int violent_death )
689 {
690     if (thread->state == TERMINATED) return;  /* already killed */
691     thread->state = TERMINATED;
692     if (current == thread) current = NULL;
693     if (debug_level)
694         fprintf( stderr,"%08x: *killed* exit_code=%d\n",
695                  (unsigned int)thread, thread->exit_code );
696     if (thread->wait)
697     {
698         while (thread->wait) end_wait( thread );
699         send_thread_wakeup( thread, NULL, STATUS_PENDING );
700         /* if it is waiting on the socket, we don't need to send a SIGTERM */
701         violent_death = 0;
702     }
703     debug_exit_thread( thread );
704     abandon_mutexes( thread );
705     remove_process_thread( thread->process, thread );
706     wake_up( &thread->obj, 0 );
707     detach_thread( thread, violent_death ? SIGTERM : 0 );
708     remove_select_user( &thread->obj );
709     cleanup_thread( thread );
710     release_object( thread );
711 }
712
713 /* take a snapshot of currently running threads */
714 struct thread_snapshot *thread_snap( int *count )
715 {
716     struct thread_snapshot *snapshot, *ptr;
717     struct thread *thread;
718     int total = 0;
719
720     for (thread = first_thread; thread; thread = thread->next)
721         if (thread->state != TERMINATED) total++;
722     if (!total || !(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL;
723     ptr = snapshot;
724     for (thread = first_thread; thread; thread = thread->next)
725     {
726         if (thread->state == TERMINATED) continue;
727         ptr->thread   = thread;
728         ptr->count    = thread->obj.refcount;
729         ptr->priority = thread->priority;
730         grab_object( thread );
731         ptr++;
732     }
733     *count = total;
734     return snapshot;
735 }
736
737 /* signal that we are finished booting on the client side */
738 DECL_HANDLER(boot_done)
739 {
740     debug_level = max( debug_level, req->debug_level );
741     if (current == booting_thread)
742     {
743         booting_thread = (struct thread *)~0UL;  /* make sure it doesn't match other threads */
744         lock_master_socket(0);  /* allow other clients now */
745     }
746 }
747
748 /* create a new thread */
749 DECL_HANDLER(new_thread)
750 {
751     struct thread *thread;
752     int request_fd = thread_get_inflight_fd( current, req->request_fd );
753
754     if (request_fd == -1)
755     {
756         set_error( STATUS_INVALID_HANDLE );
757         return;
758     }
759
760     if ((thread = create_thread( request_fd, current->process )))
761     {
762         if (req->suspend) thread->suspend++;
763         req->tid = thread;
764         if ((req->handle = alloc_handle( current->process, thread,
765                                          THREAD_ALL_ACCESS, req->inherit )))
766         {
767             /* thread object will be released when the thread gets killed */
768             return;
769         }
770         kill_thread( thread, 1 );
771         request_fd = -1;
772     }
773 }
774
775 /* initialize a new thread */
776 DECL_HANDLER(init_thread)
777 {
778     int reply_fd = thread_get_inflight_fd( current, req->reply_fd );
779     int wait_fd = thread_get_inflight_fd( current, req->wait_fd );
780
781     if (current->unix_pid)
782     {
783         fatal_protocol_error( current, "init_thread: already running\n" );
784         goto error;
785     }
786     if (reply_fd == -1)
787     {
788         fatal_protocol_error( current, "bad reply fd\n" );
789         goto error;
790     }
791     if (wait_fd == -1)
792     {
793         fatal_protocol_error( current, "bad wait fd\n" );
794         goto error;
795     }
796
797     current->unix_pid = req->unix_pid;
798     current->teb      = req->teb;
799     current->reply_fd = reply_fd;
800     current->wait_fd  = wait_fd;
801
802     if (current->suspend + current->process->suspend > 0) stop_thread( current );
803     if (current->process->running_threads > 1)
804         generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry );
805
806     req->pid     = get_process_id( current->process );
807     req->tid     = get_thread_id( current );
808     req->boot    = (current == booting_thread);
809     req->version = SERVER_PROTOCOL_VERSION;
810     return;
811
812  error:
813     if (reply_fd != -1) close( reply_fd );
814     if (wait_fd != -1) close( wait_fd );
815 }
816
817 /* set the shared buffer for a thread */
818 DECL_HANDLER(set_thread_buffer)
819 {
820     unsigned int size = MAX_REQUEST_LENGTH;
821     unsigned int offset = 0;
822     int fd = thread_get_inflight_fd( current, req->fd );
823
824     req->size = size;
825     req->offset = offset;
826
827     if (fd != -1)
828     {
829         if (ftruncate( fd, size ) == -1) file_set_error();
830         else
831         {
832             void *buffer = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset );
833             if (buffer == (void *)-1) file_set_error();
834             else
835             {
836                 if (current->buffer != (void *)-1) munmap( current->buffer, size );
837                 current->buffer = buffer;
838             }
839         }
840         close( fd );
841     }
842     else set_error( STATUS_INVALID_HANDLE );
843 }
844
845 /* terminate a thread */
846 DECL_HANDLER(terminate_thread)
847 {
848     struct thread *thread;
849
850     req->self = 0;
851     req->last = 0;
852     if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
853     {
854         thread->exit_code = req->exit_code;
855         if (thread != current) kill_thread( thread, 1 );
856         else
857         {
858             req->self = 1;
859             req->last = (thread->process->running_threads == 1);
860         }
861         release_object( thread );
862     }
863 }
864
865 /* fetch information about a thread */
866 DECL_HANDLER(get_thread_info)
867 {
868     struct thread *thread;
869     handle_t handle = req->handle;
870
871     if (!handle) thread = get_thread_from_id( req->tid_in );
872     else thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION );
873
874     if (thread)
875     {
876         req->tid       = get_thread_id( thread );
877         req->teb       = thread->teb;
878         req->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STILL_ACTIVE;
879         req->priority  = thread->priority;
880         release_object( thread );
881     }
882 }
883
884 /* set information about a thread */
885 DECL_HANDLER(set_thread_info)
886 {
887     struct thread *thread;
888
889     if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
890     {
891         set_thread_info( thread, req );
892         release_object( thread );
893     }
894 }
895
896 /* suspend a thread */
897 DECL_HANDLER(suspend_thread)
898 {
899     struct thread *thread;
900
901     if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
902     {
903         req->count = suspend_thread( thread, 1 );
904         release_object( thread );
905     }
906 }
907
908 /* resume a thread */
909 DECL_HANDLER(resume_thread)
910 {
911     struct thread *thread;
912
913     if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
914     {
915         req->count = resume_thread( thread );
916         release_object( thread );
917     }
918 }
919
920 /* select on a handle list */
921 DECL_HANDLER(select)
922 {
923     int count = get_req_data_size(req) / sizeof(int);
924     select_on( count, req->cookie, get_req_data(req), req->flags, req->sec, req->usec );
925 }
926
927 /* queue an APC for a thread */
928 DECL_HANDLER(queue_apc)
929 {
930     struct thread *thread;
931     if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
932     {
933         thread_queue_apc( thread, NULL, req->func, APC_USER, !req->user, 1, req->param );
934         release_object( thread );
935     }
936 }
937
938 /* get next APC to call */
939 DECL_HANDLER(get_apc)
940 {
941     struct thread_apc *apc;
942     size_t size;
943
944     for (;;)
945     {
946         if (!(apc = thread_dequeue_apc( current, !req->alertable )))
947         {
948             /* no more APCs */
949             req->func    = NULL;
950             req->type    = APC_NONE;
951             set_req_data_size( req, 0 );
952             return;
953         }
954         /* Optimization: ignore APCs that have a NULL func; they are only used
955          * to wake up a thread, but since we got here the thread woke up already.
956          */
957         if (apc->func) break;
958         free( apc );
959     }
960     size = apc->nb_args * sizeof(apc->args[0]);
961     if (size > get_req_data_size(req)) size = get_req_data_size(req);
962     req->func = apc->func;
963     req->type = apc->type;
964     memcpy( get_req_data(req), apc->args, size );
965     set_req_data_size( req, size );
966     free( apc );
967 }
968
969 /* fetch a selector entry for a thread */
970 DECL_HANDLER(get_selector_entry)
971 {
972     struct thread *thread;
973     if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
974     {
975         get_selector_entry( thread, req->entry, &req->base, &req->limit, &req->flags );
976         release_object( thread );
977     }
978 }