Revert "winex11.drv: Optimise getting the bits of a DIB after calling SetDIBits."
[wine] / dlls / kernel32 / tests / thread.c
1 /*
2  * Unit test suite for directory functions.
3  *
4  * Copyright 2002 Geoffrey Hausheer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* Define _WIN32_WINNT to get SetThreadIdealProcessor on Windows */
22 #define _WIN32_WINNT 0x0500
23
24 #include <assert.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 #include "wine/test.h"
29 #include <windef.h>
30 #include <winbase.h>
31 #include <winnt.h>
32 #include <winerror.h>
33
34 /* Specify the number of simultaneous threads to test */
35 #define NUM_THREADS 4
36 /* Specify whether to test the extended priorities for Win2k/XP */
37 #define USE_EXTENDED_PRIORITIES 0
38 /* Specify whether to test the stack allocation in CreateThread */
39 #define CHECK_STACK 0
40
41 /* Set CHECK_STACK to 1 if you want to try to test the stack-limit from
42    CreateThread.  So far I have been unable to make this work, and
43    I am in doubt as to how portable it is.  Also, according to MSDN,
44    you shouldn't mix C-run-time-libraries (i.e. alloca) with CreateThread.
45    Anyhow, the check is currently commented out
46 */
47 #if CHECK_STACK
48 # ifdef __try
49 #  define __TRY __try
50 #  define __EXCEPT __except
51 #  define __ENDTRY
52 # else
53 #  include "wine/exception.h"
54 # endif
55 #endif
56
57 typedef BOOL (WINAPI *GetThreadPriorityBoost_t)(HANDLE,PBOOL);
58 static GetThreadPriorityBoost_t pGetThreadPriorityBoost=NULL;
59
60 typedef HANDLE (WINAPI *OpenThread_t)(DWORD,BOOL,DWORD);
61 static OpenThread_t pOpenThread=NULL;
62
63 typedef BOOL (WINAPI *QueueUserWorkItem_t)(LPTHREAD_START_ROUTINE,PVOID,ULONG);
64 static QueueUserWorkItem_t pQueueUserWorkItem=NULL;
65
66 typedef DWORD (WINAPI *SetThreadIdealProcessor_t)(HANDLE,DWORD);
67 static SetThreadIdealProcessor_t pSetThreadIdealProcessor=NULL;
68
69 typedef BOOL (WINAPI *SetThreadPriorityBoost_t)(HANDLE,BOOL);
70 static SetThreadPriorityBoost_t pSetThreadPriorityBoost=NULL;
71
72 typedef BOOL (WINAPI *RegisterWaitForSingleObject_t)(PHANDLE,HANDLE,WAITORTIMERCALLBACK,PVOID,ULONG,ULONG);
73 static RegisterWaitForSingleObject_t pRegisterWaitForSingleObject=NULL;
74
75 typedef BOOL (WINAPI *UnregisterWait_t)(HANDLE);
76 static UnregisterWait_t pUnregisterWait=NULL;
77
78 static HANDLE create_target_process(const char *arg)
79 {
80     char **argv;
81     char cmdline[MAX_PATH];
82     PROCESS_INFORMATION pi;
83     STARTUPINFO si = { 0 };
84     si.cb = sizeof(si);
85
86     winetest_get_mainargs( &argv );
87     sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
88     ok(CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
89                      &si, &pi) != 0, "error: %u\n", GetLastError());
90     ok(CloseHandle(pi.hThread) != 0, "error %u\n", GetLastError());
91     return pi.hProcess;
92 }
93
94 /* Functions not tested yet:
95   AttachThreadInput
96   SetThreadContext
97   SwitchToThread
98
99 In addition there are no checks that the inheritance works properly in
100 CreateThread
101 */
102
103 /* Functions to ensure that from a group of threads, only one executes
104    certain chunks of code at a time, and we know which one is executing
105    it.  It basically makes multithreaded execution linear, which defeats
106    the purpose of multiple threads, but makes testing easy.  */
107 static HANDLE all_synced;
108 static LONG num_syncing_threads, num_synced;
109
110 static void init_thread_sync_helpers(LONG num_threads)
111 {
112   all_synced = CreateEvent(NULL, FALSE, FALSE, NULL);
113   ok(all_synced != NULL, "CreateEvent failed\n");
114   num_syncing_threads = num_threads;
115   num_synced = 0;
116 }
117
118 static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
119 {
120   LONG num = InterlockedIncrement(&num_synced);
121   assert(0 < num && num <= num_syncing_threads);
122   if (num == num_syncing_threads)
123     /* FIXME: MSDN claims PulseEvent is unreliable.  For a test this isn't
124        so important, but we could use condition variables with more effort.
125        The given approach is clearer, though.  */
126     PulseEvent(all_synced);
127   else
128   {
129     DWORD ret = WaitForSingleObject(all_synced, 60000);
130     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
131   }
132   return sync_id == my_id;
133 }
134
135 static void resync_after_run(void)
136 {
137   LONG num = InterlockedDecrement(&num_synced);
138   assert(0 <= num && num < num_syncing_threads);
139   if (num == 0)
140     PulseEvent(all_synced);
141   else
142   {
143     DWORD ret = WaitForSingleObject(all_synced, 60000);
144     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
145   }
146 }
147
148 static void cleanup_thread_sync_helpers(void)
149 {
150   CloseHandle(all_synced);
151   all_synced = NULL;
152 }
153
154 DWORD tlsIndex;
155
156 typedef struct {
157   int threadnum;
158   HANDLE *event;
159   DWORD *threadmem;
160 } t1Struct;
161
162 /* WinME supports OpenThread but doesn't know about access restrictions so
163    we require them to be either completely ignored or always obeyed.
164 */
165 INT obeying_ars = 0; /* -1 == no, 0 == dunno yet, 1 == yes */
166 #define obey_ar(x) \
167   (obeying_ars == 0 \
168     ? ((x) \
169       ? (obeying_ars = +1) \
170       : ((obeying_ars = -1), \
171          trace("not restricted, assuming consistent behaviour\n"))) \
172     : (obeying_ars < 0) \
173       ? ok(!(x), "access restrictions obeyed\n") \
174       : ok( (x), "access restrictions not obeyed\n"))
175
176 /* Basic test that simultaneous threads can access shared memory,
177    that the thread local storage routines work correctly, and that
178    threads actually run concurrently
179 */
180 static DWORD WINAPI threadFunc1(LPVOID p)
181 {
182     t1Struct *tstruct = (t1Struct *)p;
183    int i;
184 /* write our thread # into shared memory */
185    tstruct->threadmem[tstruct->threadnum]=GetCurrentThreadId();
186    ok(TlsSetValue(tlsIndex,(LPVOID)(tstruct->threadnum+1))!=0,
187       "TlsSetValue failed\n");
188 /* The threads synchronize before terminating.  This is done by
189    Signaling an event, and waiting for all events to occur
190 */
191    SetEvent(tstruct->event[tstruct->threadnum]);
192    WaitForMultipleObjects(NUM_THREADS,tstruct->event,TRUE,INFINITE);
193 /* Double check that all threads really did run by validating that
194    they have all written to the shared memory. There should be no race
195    here, since all threads were synchronized after the write.*/
196    for(i=0;i<NUM_THREADS;i++) {
197      while(tstruct->threadmem[i]==0) ;
198    }
199
200    /* lstrlenA contains an exception handler so this makes sure exceptions work in threads */
201    ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
202
203 /* Check that no one changed our tls memory */
204    ok((int)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
205       "TlsGetValue failed\n");
206    return NUM_THREADS+tstruct->threadnum;
207 }
208
209 static DWORD WINAPI threadFunc2(LPVOID p)
210 {
211    return 99;
212 }
213
214 static DWORD WINAPI threadFunc3(LPVOID p)
215 {
216    HANDLE thread;
217    thread=GetCurrentThread();
218    SuspendThread(thread);
219    return 99;
220 }
221
222 static DWORD WINAPI threadFunc4(LPVOID p)
223 {
224     HANDLE event = (HANDLE)p;
225    if(event != NULL) {
226      SetEvent(event);
227    }
228    Sleep(99000);
229    return 0;
230 }
231
232 #if CHECK_STACK
233 static DWORD WINAPI threadFunc5(LPVOID p)
234 {
235   DWORD *exitCode = (DWORD *)p;
236   SYSTEM_INFO sysInfo;
237   sysInfo.dwPageSize=0;
238   GetSystemInfo(&sysInfo);
239   *exitCode=0;
240    __TRY
241    {
242      alloca(2*sysInfo.dwPageSize);
243    }
244     __EXCEPT(1) {
245      *exitCode=1;
246    }
247    __ENDTRY
248    return 0;
249 }
250 #endif
251
252 static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
253 {
254     SetEvent((HANDLE) p);
255     return 0;
256 }
257
258 static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
259 {
260     CloseHandle((HANDLE) p);
261     return 0;
262 }
263
264 static void create_function_addr_events(HANDLE events[2])
265 {
266     char buffer[256];
267
268     sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent);
269     events[0] = CreateEvent(NULL, FALSE, FALSE, buffer);
270
271     sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle);
272     events[1] = CreateEvent(NULL, FALSE, FALSE, buffer);
273 }
274
275 /* check CreateRemoteThread */
276 static VOID test_CreateRemoteThread(void)
277 {
278     HANDLE hProcess, hThread, hEvent, hRemoteEvent;
279     DWORD tid, ret, exitcode;
280     HANDLE hAddrEvents[2];
281
282     hProcess = create_target_process("sleep");
283     ok(hProcess != NULL, "Can't start process\n");
284
285     /* ensure threadFunc_SetEvent & threadFunc_CloseHandle are the same
286      * address as in the child process */
287     create_function_addr_events(hAddrEvents);
288     ret = WaitForMultipleObjects(2, hAddrEvents, TRUE, 5000);
289     if (ret == WAIT_TIMEOUT)
290     {
291         skip("child process wasn't mapped at same address, so can't do CreateRemoteThread tests.\n");
292         return;
293     }
294
295     hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
296     ok(hEvent != NULL, "Can't create event, err=%u\n", GetLastError());
297     ret = DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hRemoteEvent,
298                           0, FALSE, DUPLICATE_SAME_ACCESS);
299     ok(ret != 0, "DuplicateHandle failed, err=%u\n", GetLastError());
300
301     /* create suspended remote thread with entry point SetEvent() */
302     SetLastError(0xdeadbeef);
303     hThread = CreateRemoteThread(hProcess, NULL, 0, threadFunc_SetEvent,
304                                  hRemoteEvent, CREATE_SUSPENDED, &tid);
305     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
306     {
307         skip("CreateRemoteThread is not implemented\n");
308         goto cleanup;
309     }
310     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
311     ok(tid != 0, "null tid\n");
312     ret = SuspendThread(hThread);
313     ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
314     ret = ResumeThread(hThread);
315     ok(ret == 2, "ret=%u, err=%u\n", ret, GetLastError());
316
317     /* thread still suspended, so wait times out */
318     ret = WaitForSingleObject(hEvent, 100);
319     ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
320
321     ret = ResumeThread(hThread);
322     ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
323
324     /* wait that doesn't time out */
325     ret = WaitForSingleObject(hEvent, 100);
326     ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%u\n", ret);
327
328     /* wait for thread end */
329     ret = WaitForSingleObject(hThread, 100);
330     ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
331     CloseHandle(hThread);
332
333     /* create and wait for remote thread with entry point CloseHandle() */
334     hThread = CreateRemoteThread(hProcess, NULL, 0,
335                                  threadFunc_CloseHandle,
336                                  hRemoteEvent, 0, &tid);
337     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
338     ret = WaitForSingleObject(hThread, 100);
339     ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
340     CloseHandle(hThread);
341
342     /* create remote thread with entry point SetEvent() */
343     hThread = CreateRemoteThread(hProcess, NULL, 0,
344                                  threadFunc_SetEvent,
345                                  hRemoteEvent, 0, &tid);
346     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
347
348     /* closed handle, so wait times out */
349     ret = WaitForSingleObject(hEvent, 100);
350     ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
351
352     /* check that remote SetEvent() failed */
353     ret = GetExitCodeThread(hThread, &exitcode);
354     ok(ret != 0, "GetExitCodeThread failed, err=%u\n", GetLastError());
355     if (ret) ok(exitcode == 0, "SetEvent succeeded, expected to fail\n");
356     CloseHandle(hThread);
357
358 cleanup:
359     TerminateProcess(hProcess, 0);
360     CloseHandle(hEvent);
361     CloseHandle(hProcess);
362 }
363
364 /* Check basic functionality of CreateThread and Tls* functions */
365 static VOID test_CreateThread_basic(void)
366 {
367    HANDLE thread[NUM_THREADS],event[NUM_THREADS];
368    DWORD threadid[NUM_THREADS],curthreadId;
369    DWORD threadmem[NUM_THREADS];
370    DWORD exitCode;
371    t1Struct tstruct[NUM_THREADS];
372    int error;
373    DWORD i,j;
374    DWORD GLE, ret;
375
376    /* lstrlenA contains an exception handler so this makes sure exceptions work in the main thread */
377    ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
378
379 /* Retrieve current Thread ID for later comparisons */
380   curthreadId=GetCurrentThreadId();
381 /* Allocate some local storage */
382   ok((tlsIndex=TlsAlloc())!=TLS_OUT_OF_INDEXES,"TlsAlloc failed\n");
383 /* Create events for thread synchronization */
384   for(i=0;i<NUM_THREADS;i++) {
385     threadmem[i]=0;
386 /* Note that it doesn't matter what type of event we choose here.  This
387    test isn't trying to thoroughly test events
388 */
389     event[i]=CreateEventA(NULL,TRUE,FALSE,NULL);
390     tstruct[i].threadnum=i;
391     tstruct[i].threadmem=threadmem;
392     tstruct[i].event=event;
393   }
394
395 /* Test that passing arguments to threads works okay */
396   for(i=0;i<NUM_THREADS;i++) {
397     thread[i] = CreateThread(NULL,0,threadFunc1,
398                              &tstruct[i],0,&threadid[i]);
399     ok(thread[i]!=NULL,"Create Thread failed\n");
400   }
401 /* Test that the threads actually complete */
402   for(i=0;i<NUM_THREADS;i++) {
403     error=WaitForSingleObject(thread[i],5000);
404     ok(error==WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
405     if(error!=WAIT_OBJECT_0) {
406       TerminateThread(thread[i],i+NUM_THREADS);
407     }
408     ok(GetExitCodeThread(thread[i],&exitCode),"Could not retrieve ext code\n");
409     ok(exitCode==i+NUM_THREADS,"Thread returned an incorrect exit code\n");
410   }
411 /* Test that each thread executed in its parent's address space
412    (it was able to change threadmem and pass that change back to its parent)
413    and that each thread id was independent).  Note that we prove that the
414    threads actually execute concurrently by having them block on each other
415    in threadFunc1
416 */
417   for(i=0;i<NUM_THREADS;i++) {
418     error=0;
419     for(j=i+1;j<NUM_THREADS;j++) {
420       if (threadmem[i]==threadmem[j]) {
421         error=1;
422       }
423     }
424     ok(!error && threadmem[i]==threadid[i] && threadmem[i]!=curthreadId,
425          "Thread did not execute successfully\n");
426     ok(CloseHandle(thread[i])!=0,"CloseHandle failed\n");
427   }
428   ok(TlsFree(tlsIndex)!=0,"TlsFree failed\n");
429
430   /* Test how passing NULL as a pointer to threadid works */
431   SetLastError(0xFACEaBAD);
432   thread[0] = CreateThread(NULL,0,threadFunc2,NULL,0,NULL);
433   GLE = GetLastError();
434   if (thread[0]) { /* NT */
435     ok(GLE==0xFACEaBAD, "CreateThread set last error to %d, expected 4207848365\n", GLE);
436     ret = WaitForSingleObject(thread[0],100);
437     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
438     ret = GetExitCodeThread(thread[0],&exitCode);
439     ok(ret!=0, "GetExitCodeThread returned %d (expected nonzero)\n", ret);
440     ok(exitCode==99, "threadFunc2 exited with code: %d (expected 99)\n", exitCode);
441     ok(CloseHandle(thread[0])!=0,"Error closing thread handle\n");
442   }
443   else { /* 9x */
444     ok(GLE==ERROR_INVALID_PARAMETER, "CreateThread set last error to %d, expected 87\n", GLE);
445   }
446 }
447
448 /* Check that using the CREATE_SUSPENDED flag works */
449 static VOID test_CreateThread_suspended(void)
450 {
451   HANDLE thread;
452   DWORD threadId;
453   int error;
454
455   thread = CreateThread(NULL,0,threadFunc2,NULL,
456                         CREATE_SUSPENDED,&threadId);
457   ok(thread!=NULL,"Create Thread failed\n");
458 /* Check that the thread is suspended */
459   ok(SuspendThread(thread)==1,"Thread did not start suspended\n");
460   ok(ResumeThread(thread)==2,"Resume thread returned an invalid value\n");
461 /* Check that resume thread didn't actually start the thread.  I can't think
462    of a better way of checking this than just waiting.  I am not sure if this
463    will work on slow computers.
464 */
465   ok(WaitForSingleObject(thread,1000)==WAIT_TIMEOUT,
466      "ResumeThread should not have actually started the thread\n");
467 /* Now actually resume the thread and make sure that it actually completes*/
468   ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
469   ok((error=WaitForSingleObject(thread,1000))==WAIT_OBJECT_0,
470      "Thread did not resume\n");
471   if(error!=WAIT_OBJECT_0) {
472     TerminateThread(thread,1);
473   }
474   ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
475 }
476
477 /* Check that SuspendThread and ResumeThread work */
478 static VOID test_SuspendThread(void)
479 {
480   HANDLE thread,access_thread;
481   DWORD threadId,exitCode,error;
482   int i;
483
484   thread = CreateThread(NULL,0,threadFunc3,NULL,
485                         0,&threadId);
486   ok(thread!=NULL,"Create Thread failed\n");
487 /* Check that the thread is suspended */
488 /* Note that this is a polling method, and there is a race between
489    SuspendThread being called (in the child, and the loop below timing out,
490    so the test could fail on a heavily loaded or slow computer.
491 */
492   error=0;
493   for(i=0;error==0 && i<100;i++) {
494     error=SuspendThread(thread);
495     ResumeThread(thread);
496     if(error==0) {
497       Sleep(50);
498       i++;
499     }
500   }
501   ok(error==1,"SuspendThread did not work\n");
502 /* check that access restrictions are obeyed */
503   if (pOpenThread) {
504     access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME),
505                            0,threadId);
506     ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
507     if (access_thread!=NULL) {
508       obey_ar(SuspendThread(access_thread)==~0U);
509       obey_ar(ResumeThread(access_thread)==~0U);
510       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
511     }
512   }
513 /* Double check that the thread really is suspended */
514   ok((error=GetExitCodeThread(thread,&exitCode))!=0 && exitCode==STILL_ACTIVE,
515      "Thread did not really suspend\n");
516 /* Resume the thread, and make sure it actually completes */
517   ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
518   ok((error=WaitForSingleObject(thread,1000))==WAIT_OBJECT_0,
519      "Thread did not resume\n");
520   if(error!=WAIT_OBJECT_0) {
521     TerminateThread(thread,1);
522   }
523   /* Trying to suspend a terminated thread should fail */
524   error=SuspendThread(thread);
525   ok(error==~0U, "wrong return code: %d\n", error);
526   ok(GetLastError()==ERROR_ACCESS_DENIED || GetLastError()==ERROR_NO_MORE_ITEMS, "unexpected error code: %d\n", GetLastError());
527
528   ok(CloseHandle(thread)!=0,"CloseHandle Failed\n");
529 }
530
531 /* Check that TerminateThread works properly
532 */
533 static VOID test_TerminateThread(void)
534 {
535   HANDLE thread,access_thread,event;
536   DWORD threadId,exitCode;
537   event=CreateEventA(NULL,TRUE,FALSE,NULL);
538   thread = CreateThread(NULL,0,threadFunc4,
539                         (LPVOID)event, 0,&threadId);
540   ok(thread!=NULL,"Create Thread failed\n");
541 /* TerminateThread has a race condition in Wine.  If the thread is terminated
542    before it starts, it leaves a process behind.  Therefore, we wait for the
543    thread to signal that it has started.  There is no easy way to force the
544    race to occur, so we don't try to find it.
545 */
546   ok(WaitForSingleObject(event,5000)==WAIT_OBJECT_0,
547      "TerminateThread didn't work\n");
548 /* check that access restrictions are obeyed */
549   if (pOpenThread) {
550     access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_TERMINATE),
551                              0,threadId);
552     ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
553     if (access_thread!=NULL) {
554       obey_ar(TerminateThread(access_thread,99)==0);
555       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
556     }
557   }
558 /* terminate a job and make sure it terminates */
559   ok(TerminateThread(thread,99)!=0,"TerminateThread failed\n");
560   ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
561      "TerminateThread didn't work\n");
562   ok(GetExitCodeThread(thread,&exitCode)!=STILL_ACTIVE,
563      "TerminateThread should not leave the thread 'STILL_ACTIVE'\n");
564   ok(exitCode==99, "TerminateThread returned invalid exit code\n");
565   ok(CloseHandle(thread)!=0,"Error Closing thread handle\n");
566 }
567
568 /* Check if CreateThread obeys the specified stack size.  This code does
569    not work properly, and is currently disabled
570 */
571 static VOID test_CreateThread_stack(void)
572 {
573 #if CHECK_STACK
574 /* The only way I know of to test the stack size is to use alloca
575    and __try/__except.  However, this is probably not portable,
576    and I couldn't get it to work under Wine anyhow.  However, here
577    is the code which should allow for testing that CreateThread
578    respects the stack-size limit
579 */
580      HANDLE thread;
581      DWORD threadId,exitCode;
582
583      SYSTEM_INFO sysInfo;
584      sysInfo.dwPageSize=0;
585      GetSystemInfo(&sysInfo);
586      ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
587      thread = CreateThread(NULL,sysInfo.dwPageSize,
588                            threadFunc5,&exitCode,
589                            0,&threadId);
590      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
591         "TerminateThread didn't work\n");
592      ok(exitCode==1,"CreateThread did not obey stack-size-limit\n");
593      ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
594 #endif
595 }
596
597 /* Check whether setting/retrieving thread priorities works */
598 static VOID test_thread_priority(void)
599 {
600    HANDLE curthread,access_thread;
601    DWORD curthreadId,exitCode;
602    int min_priority=-2,max_priority=2;
603    BOOL disabled,rc;
604    int i;
605
606    curthread=GetCurrentThread();
607    curthreadId=GetCurrentThreadId();
608 /* Check thread priority */
609 /* NOTE: on Win2k/XP priority can be from -7 to 6.  All other platforms it
610          is -2 to 2.  However, even on a real Win2k system, using thread
611          priorities beyond the -2 to 2 range does not work.  If you want to try
612          anyway, enable USE_EXTENDED_PRIORITIES
613 */
614    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_NORMAL,
615       "GetThreadPriority Failed\n");
616
617    if (pOpenThread) {
618 /* check that access control is obeyed */
619      access_thread=pOpenThread(THREAD_ALL_ACCESS &
620                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
621                        0,curthreadId);
622      ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
623      if (access_thread!=NULL) {
624        obey_ar(SetThreadPriority(access_thread,1)==0);
625        obey_ar(GetThreadPriority(access_thread)==THREAD_PRIORITY_ERROR_RETURN);
626        obey_ar(GetExitCodeThread(access_thread,&exitCode)==0);
627        ok(CloseHandle(access_thread),"Error Closing thread handle\n");
628      }
629    }
630 #if USE_EXTENDED_PRIORITIES
631    min_priority=-7; max_priority=6;
632 #endif
633    for(i=min_priority;i<=max_priority;i++) {
634      ok(SetThreadPriority(curthread,i)!=0,
635         "SetThreadPriority Failed for priority: %d\n",i);
636      ok(GetThreadPriority(curthread)==i,
637         "GetThreadPriority Failed for priority: %d\n",i);
638    }
639    ok(SetThreadPriority(curthread,THREAD_PRIORITY_TIME_CRITICAL)!=0,
640       "SetThreadPriority Failed\n");
641    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_TIME_CRITICAL,
642       "GetThreadPriority Failed\n");
643    ok(SetThreadPriority(curthread,THREAD_PRIORITY_IDLE)!=0,
644        "SetThreadPriority Failed\n");
645    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_IDLE,
646        "GetThreadPriority Failed\n");
647    ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed\n");
648
649 /* Check that the thread priority is not changed if SetThreadPriority
650    is called with a value outside of the max/min range */
651    SetThreadPriority(curthread,min_priority);
652    SetLastError(0xdeadbeef);
653    rc = SetThreadPriority(curthread,min_priority-1);
654
655    ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
656    ok(GetLastError() == ERROR_INVALID_PARAMETER ||
657       GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
658       "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
659       GetLastError());
660    ok(GetThreadPriority(curthread)==min_priority,
661       "GetThreadPriority didn't return min_priority\n");
662
663    SetThreadPriority(curthread,max_priority);
664    SetLastError(0xdeadbeef);
665    rc = SetThreadPriority(curthread,max_priority+1);
666
667    ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
668    ok(GetLastError() == ERROR_INVALID_PARAMETER ||
669       GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
670       "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
671       GetLastError());
672    ok(GetThreadPriority(curthread)==max_priority,
673       "GetThreadPriority didn't return max_priority\n");
674
675 /* Check thread priority boost */
676    if (!pGetThreadPriorityBoost || !pSetThreadPriorityBoost) 
677      return; /* Win9x */
678
679    SetLastError(0xdeadbeef);
680    rc=pGetThreadPriorityBoost(curthread,&disabled);
681    if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
682      return; /* WinME */
683
684    todo_wine
685      ok(rc!=0,"error=%d\n",GetLastError());
686
687    if (pOpenThread) {
688 /* check that access control is obeyed */
689      access_thread=pOpenThread(THREAD_ALL_ACCESS &
690                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
691                        0,curthreadId);
692      ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
693      if (access_thread!=NULL) {
694        obey_ar(pSetThreadPriorityBoost(access_thread,1)==0);
695        obey_ar(pGetThreadPriorityBoost(access_thread,&disabled)==0);
696        ok(CloseHandle(access_thread),"Error Closing thread handle\n");
697      }
698    }
699
700    todo_wine {
701      rc = pSetThreadPriorityBoost(curthread,1);
702      ok( rc != 0, "error=%d\n",GetLastError());
703      rc=pGetThreadPriorityBoost(curthread,&disabled);
704      ok(rc!=0 && disabled==1,
705         "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
706
707      rc = pSetThreadPriorityBoost(curthread,0);
708      ok( rc != 0, "error=%d\n",GetLastError());
709      rc=pGetThreadPriorityBoost(curthread,&disabled);
710      ok(rc!=0 && disabled==0,
711         "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
712    }
713 }
714
715 /* check the GetThreadTimes function */
716 static VOID test_GetThreadTimes(void)
717 {
718      HANDLE thread,access_thread=NULL;
719      FILETIME creationTime,exitTime,kernelTime,userTime;
720      DWORD threadId;
721      int error;
722
723      thread = CreateThread(NULL,0,threadFunc2,NULL,
724                            CREATE_SUSPENDED,&threadId);
725
726      ok(thread!=NULL,"Create Thread failed\n");
727 /* check that access control is obeyed */
728      if (pOpenThread) {
729        access_thread=pOpenThread(THREAD_ALL_ACCESS &
730                                    (~THREAD_QUERY_INFORMATION), 0,threadId);
731        ok(access_thread!=NULL,
732           "OpenThread returned an invalid handle\n");
733      }
734      ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
735      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
736         "ResumeThread didn't work\n");
737      creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
738      exitTime.dwLowDateTime=99;     exitTime.dwHighDateTime=99;
739      kernelTime.dwLowDateTime=99;   kernelTime.dwHighDateTime=99;
740      userTime.dwLowDateTime=99;     userTime.dwHighDateTime=99;
741 /* GetThreadTimes should set all of the parameters passed to it */
742      error=GetThreadTimes(thread,&creationTime,&exitTime,
743                           &kernelTime,&userTime);
744      if (error!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
745        ok(error!=0,"GetThreadTimes failed\n");
746        ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
747           "creationTime was invalid\n");
748        ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
749           "exitTime was invalid\n");
750        ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
751           "kernelTimewas invalid\n");
752        ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
753           "userTime was invalid\n");
754        ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
755        if(access_thread!=NULL)
756        {
757          error=GetThreadTimes(access_thread,&creationTime,&exitTime,
758                               &kernelTime,&userTime);
759          obey_ar(error==0);
760        }
761      }
762      if(access_thread!=NULL) {
763        ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
764      }
765 }
766
767 /* Check the processor affinity functions */
768 /* NOTE: These functions should also be checked that they obey access control
769 */
770 static VOID test_thread_processor(void)
771 {
772    HANDLE curthread,curproc;
773    DWORD_PTR processMask,systemMask;
774    SYSTEM_INFO sysInfo;
775    int error=0;
776
777    sysInfo.dwNumberOfProcessors=0;
778    GetSystemInfo(&sysInfo);
779    ok(sysInfo.dwNumberOfProcessors>0,
780       "GetSystemInfo failed to return a valid # of processors\n");
781 /* Use the current Thread/process for all tests */
782    curthread=GetCurrentThread();
783    ok(curthread!=NULL,"GetCurrentThread failed\n");
784    curproc=GetCurrentProcess();
785    ok(curproc!=NULL,"GetCurrentProcess failed\n");
786 /* Check the Affinity Mask functions */
787    ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
788       "GetProcessAffinityMask failed\n");
789    ok(SetThreadAffinityMask(curthread,processMask)==processMask,
790       "SetThreadAffinityMask failed\n");
791    ok(SetThreadAffinityMask(curthread,processMask+1)==0,
792       "SetThreadAffinityMask passed for an illegal processor\n");
793 /* NOTE: This only works on WinNT/2000/XP) */
794    if (pSetThreadIdealProcessor) {
795      todo_wine {
796        SetLastError(0);
797        error=pSetThreadIdealProcessor(curthread,0);
798        if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
799          ok(error!=-1, "SetThreadIdealProcessor failed\n");
800        }
801      }
802      if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
803        error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
804        ok(error==-1,
805           "SetThreadIdealProcessor succeeded with an illegal processor #\n");
806        todo_wine {
807          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
808          ok(error==0, "SetThreadIdealProcessor returned an incorrect value\n");
809        }
810      }
811    }
812 }
813
814 static VOID test_GetThreadExitCode(void)
815 {
816     DWORD exitCode, threadid;
817     DWORD GLE, ret;
818     HANDLE thread;
819
820     ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
821     ok(ret==0, "GetExitCodeThread returned non zero value: %d\n", ret);
822     GLE = GetLastError();
823     ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %d (expected 6)\n", GLE);
824
825     thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
826     ret = WaitForSingleObject(thread,100);
827     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
828     ret = GetExitCodeThread(thread,&exitCode);
829     ok(ret==exitCode || ret==1, 
830        "GetExitCodeThread returned %d (expected 1 or %d)\n", ret, exitCode);
831     ok(exitCode==99, "threadFunc2 exited with code %d (expected 99)\n", exitCode);
832     ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
833 }
834
835 #ifdef __i386__
836
837 static int test_value = 0;
838 static HANDLE event;
839
840 static void WINAPI set_test_val( int val )
841 {
842     test_value += val;
843 }
844
845 static DWORD WINAPI threadFunc6(LPVOID p)
846 {
847     SetEvent( event );
848     Sleep( 1000 );
849     test_value *= (int)p;
850     return 0;
851 }
852
853 static void test_SetThreadContext(void)
854 {
855     CONTEXT ctx;
856     int *stack;
857     HANDLE thread;
858     DWORD threadid;
859     DWORD prevcount;
860     BOOL ret;
861
862     SetLastError(0xdeadbeef);
863     event = CreateEvent( NULL, TRUE, FALSE, NULL );
864     thread = CreateThread( NULL, 0, threadFunc6, (void *)2, 0, &threadid );
865     ok( thread != NULL, "CreateThread failed : (%d)\n", GetLastError() );
866     if (!thread)
867     {
868         trace("Thread creation failed, skipping rest of test\n");
869         return;
870     }
871     WaitForSingleObject( event, INFINITE );
872     SuspendThread( thread );
873     CloseHandle( event );
874
875     ctx.ContextFlags = CONTEXT_FULL;
876     SetLastError(0xdeadbeef);
877     ret = GetThreadContext( thread, &ctx );
878     ok( ret, "GetThreadContext failed : (%u)\n", GetLastError() );
879
880     if (ret)
881     {
882         /* simulate a call to set_test_val(10) */
883         stack = (int *)ctx.Esp;
884         stack[-1] = 10;
885         stack[-2] = ctx.Eip;
886         ctx.Esp -= 2 * sizeof(int *);
887         ctx.Eip = (DWORD)set_test_val;
888         SetLastError(0xdeadbeef);
889         ok( SetThreadContext( thread, &ctx ), "SetThreadContext failed : (%d)\n", GetLastError() );
890     }
891
892     SetLastError(0xdeadbeef);
893     prevcount = ResumeThread( thread );
894     ok ( prevcount == 1, "Previous suspend count (%d) instead of 1, last error : (%d)\n",
895                          prevcount, GetLastError() );
896
897     WaitForSingleObject( thread, INFINITE );
898     ok( test_value == 20, "test_value %d instead of 20\n", test_value );
899 }
900
901 #endif  /* __i386__ */
902
903 static HANDLE finish_event;
904 static LONG times_executed;
905
906 static DWORD CALLBACK work_function(void *p)
907 {
908     LONG executed = InterlockedIncrement(&times_executed);
909
910     if (executed == 100)
911         SetEvent(finish_event);
912     return 0;
913 }
914
915 static void test_QueueUserWorkItem(void)
916 {
917     int i;
918     DWORD wait_result;
919     DWORD before, after;
920
921     /* QueueUserWorkItem not present on win9x */
922     if (!pQueueUserWorkItem) return;
923
924     finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
925
926     before = GetTickCount();
927
928     for (i = 0; i < 100; i++)
929     {
930         BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
931         ok(ret, "QueueUserWorkItem failed with error %d\n", GetLastError());
932     }
933
934     wait_result = WaitForSingleObject(finish_event, 10000);
935
936     after = GetTickCount();
937     trace("100 QueueUserWorkItem calls took %dms\n", after - before);
938     ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%x\n", wait_result);
939
940     ok(times_executed == 100, "didn't execute all of the work items\n");
941 }
942
943 static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
944 {
945     HANDLE event = p;
946     SetEvent(event);
947     ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
948 }
949
950 static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
951 {
952     HANDLE event = p;
953     SetEvent(event);
954     ok(TimerOrWaitFired, "wait should have timed out\n");
955 }
956
957 static void test_RegisterWaitForSingleObject(void)
958 {
959     BOOL ret;
960     HANDLE wait_handle;
961     HANDLE handle;
962     HANDLE complete_event;
963
964     if (!pRegisterWaitForSingleObject || !pUnregisterWait)
965     {
966         skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
967         return;
968     }
969
970     /* test signaled case */
971
972     handle = CreateEvent(NULL, TRUE, TRUE, NULL);
973     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
974
975     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
976     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
977
978     WaitForSingleObject(complete_event, INFINITE);
979     /* give worker thread chance to complete */
980     Sleep(100);
981
982     ret = pUnregisterWait(wait_handle);
983     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
984
985     /* test cancel case */
986
987     ResetEvent(handle);
988
989     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
990     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
991
992     ret = pUnregisterWait(wait_handle);
993     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
994
995     /* test timeout case */
996
997     ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
998     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
999
1000     WaitForSingleObject(complete_event, INFINITE);
1001     /* give worker thread chance to complete */
1002     Sleep(100);
1003
1004     ret = pUnregisterWait(wait_handle);
1005     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1006 }
1007
1008 static DWORD TLS_main;
1009 static DWORD TLS_index0, TLS_index1;
1010
1011 static DWORD WINAPI TLS_InheritanceProc(LPVOID p)
1012 {
1013   /* We should NOT inherit the TLS values from our parent or from the
1014      main thread.  */
1015   LPVOID val;
1016
1017   val = TlsGetValue(TLS_main);
1018   ok(val == NULL, "TLS inheritance failed\n");
1019
1020   val = TlsGetValue(TLS_index0);
1021   ok(val == NULL, "TLS inheritance failed\n");
1022
1023   val = TlsGetValue(TLS_index1);
1024   ok(val == NULL, "TLS inheritance failed\n");
1025
1026   return 0;
1027 }
1028
1029 /* Basic TLS usage test.  Make sure we can create slots and the values we
1030    store in them are separate among threads.  Also test TLS value
1031    inheritance with TLS_InheritanceProc.  */
1032 static DWORD WINAPI TLS_ThreadProc(LPVOID p)
1033 {
1034   LONG id = (LONG) p;
1035   LPVOID val;
1036   BOOL ret;
1037
1038   if (sync_threads_and_run_one(0, id))
1039   {
1040     TLS_index0 = TlsAlloc();
1041     ok(TLS_index0 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1042   }
1043   resync_after_run();
1044
1045   if (sync_threads_and_run_one(1, id))
1046   {
1047     TLS_index1 = TlsAlloc();
1048     ok(TLS_index1 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1049
1050     /* Slot indices should be different even if created in different
1051        threads.  */
1052     ok(TLS_index0 != TLS_index1, "TlsAlloc failed\n");
1053
1054     /* Both slots should be initialized to NULL */
1055     val = TlsGetValue(TLS_index0);
1056     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1057     ok(val == NULL, "TLS slot not initialized correctly\n");
1058
1059     val = TlsGetValue(TLS_index1);
1060     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1061     ok(val == NULL, "TLS slot not initialized correctly\n");
1062   }
1063   resync_after_run();
1064
1065   if (sync_threads_and_run_one(0, id))
1066   {
1067     val = TlsGetValue(TLS_index0);
1068     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1069     ok(val == NULL, "TLS slot not initialized correctly\n");
1070
1071     val = TlsGetValue(TLS_index1);
1072     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1073     ok(val == NULL, "TLS slot not initialized correctly\n");
1074
1075     ret = TlsSetValue(TLS_index0, (LPVOID) 1);
1076     ok(ret, "TlsSetValue failed\n");
1077
1078     ret = TlsSetValue(TLS_index1, (LPVOID) 2);
1079     ok(ret, "TlsSetValue failed\n");
1080
1081     val = TlsGetValue(TLS_index0);
1082     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1083     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1084
1085     val = TlsGetValue(TLS_index1);
1086     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1087     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1088   }
1089   resync_after_run();
1090
1091   if (sync_threads_and_run_one(1, id))
1092   {
1093     val = TlsGetValue(TLS_index0);
1094     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1095     ok(val == NULL, "TLS slot not initialized correctly\n");
1096
1097     val = TlsGetValue(TLS_index1);
1098     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1099     ok(val == NULL, "TLS slot not initialized correctly\n");
1100
1101     ret = TlsSetValue(TLS_index0, (LPVOID) 3);
1102     ok(ret, "TlsSetValue failed\n");
1103
1104     ret = TlsSetValue(TLS_index1, (LPVOID) 4);
1105     ok(ret, "TlsSetValue failed\n");
1106
1107     val = TlsGetValue(TLS_index0);
1108     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1109     ok(val == (LPVOID) 3, "TLS slot not initialized correctly\n");
1110
1111     val = TlsGetValue(TLS_index1);
1112     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1113     ok(val == (LPVOID) 4, "TLS slot not initialized correctly\n");
1114   }
1115   resync_after_run();
1116
1117   if (sync_threads_and_run_one(0, id))
1118   {
1119     HANDLE thread;
1120     DWORD waitret;
1121
1122     val = TlsGetValue(TLS_index0);
1123     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1124     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1125
1126     val = TlsGetValue(TLS_index1);
1127     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1128     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1129
1130     thread = CreateThread(NULL, 0, TLS_InheritanceProc, 0, 0, NULL);
1131     ok(thread != NULL, "CreateThread failed\n");
1132     waitret = WaitForSingleObject(thread, 60000);
1133     ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1134     CloseHandle(thread);
1135
1136     ret = TlsFree(TLS_index0);
1137     ok(ret, "TlsFree failed\n");
1138   }
1139   resync_after_run();
1140
1141   if (sync_threads_and_run_one(1, id))
1142   {
1143     ret = TlsFree(TLS_index1);
1144     ok(ret, "TlsFree failed\n");
1145   }
1146   resync_after_run();
1147
1148   return 0;
1149 }
1150
1151 static void test_TLS(void)
1152 {
1153   HANDLE threads[2];
1154   LONG i;
1155   DWORD ret;
1156   BOOL suc;
1157
1158   init_thread_sync_helpers(2);
1159
1160   /* Allocate a TLS slot in the main thread to test for inheritance.  */
1161   TLS_main = TlsAlloc();
1162   ok(TLS_main != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1163   suc = TlsSetValue(TLS_main, (LPVOID) 4114);
1164   ok(suc, "TlsSetValue failed\n");
1165
1166   for (i = 0; i < 2; ++i)
1167   {
1168     threads[i] = CreateThread(NULL, 0, TLS_ThreadProc, (LPVOID) i, 0, NULL);
1169     ok(threads[i] != NULL, "CreateThread failed\n");
1170   }
1171
1172   ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1173   ok(ret == WAIT_OBJECT_0, "WaitForMultipleObjects failed\n");
1174
1175   for (i = 0; i < 2; ++i)
1176     CloseHandle(threads[i]);
1177
1178   suc = TlsFree(TLS_main);
1179   ok(suc, "TlsFree failed\n");
1180   cleanup_thread_sync_helpers();
1181 }
1182
1183 START_TEST(thread)
1184 {
1185    HINSTANCE lib;
1186    int argc;
1187    char **argv;
1188    argc = winetest_get_mainargs( &argv );
1189 /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
1190    so that the compile passes
1191 */
1192    lib=GetModuleHandleA("kernel32.dll");
1193    ok(lib!=NULL,"Couldn't get a handle for kernel32.dll\n");
1194    pGetThreadPriorityBoost=(GetThreadPriorityBoost_t)GetProcAddress(lib,"GetThreadPriorityBoost");
1195    pOpenThread=(OpenThread_t)GetProcAddress(lib,"OpenThread");
1196    pQueueUserWorkItem=(QueueUserWorkItem_t)GetProcAddress(lib,"QueueUserWorkItem");
1197    pSetThreadIdealProcessor=(SetThreadIdealProcessor_t)GetProcAddress(lib,"SetThreadIdealProcessor");
1198    pSetThreadPriorityBoost=(SetThreadPriorityBoost_t)GetProcAddress(lib,"SetThreadPriorityBoost");
1199    pRegisterWaitForSingleObject=(RegisterWaitForSingleObject_t)GetProcAddress(lib,"RegisterWaitForSingleObject");
1200    pUnregisterWait=(UnregisterWait_t)GetProcAddress(lib,"UnregisterWait");
1201
1202    if (argc >= 3)
1203    {
1204        if (!strcmp(argv[2], "sleep"))
1205        {
1206            HANDLE hAddrEvents[2];
1207            create_function_addr_events(hAddrEvents);
1208            SetEvent(hAddrEvents[0]);
1209            SetEvent(hAddrEvents[1]);
1210            Sleep(5000); /* spawned process runs for at most 5 seconds */
1211            return;
1212        }
1213        while (1)
1214        {
1215            HANDLE hThread;
1216            hThread = CreateThread(NULL, 0, threadFunc2, NULL, 0, NULL);
1217            ok(hThread != NULL, "CreateThread failed, error %u\n",
1218               GetLastError());
1219            ok(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0,
1220               "Thread did not exit in time\n");
1221            if (hThread == NULL) break;
1222            CloseHandle(hThread);
1223        }
1224        return;
1225    }
1226
1227    test_CreateRemoteThread();
1228    test_CreateThread_basic();
1229    test_CreateThread_suspended();
1230    test_SuspendThread();
1231    test_TerminateThread();
1232    test_CreateThread_stack();
1233    test_thread_priority();
1234    test_GetThreadTimes();
1235    test_thread_processor();
1236    test_GetThreadExitCode();
1237 #ifdef __i386__
1238    test_SetThreadContext();
1239 #endif
1240    test_QueueUserWorkItem();
1241    test_RegisterWaitForSingleObject();
1242    test_TLS();
1243 }