kernel32/tests: Get rid of the Win9x support in the file sharing tests.
[wine] / dlls / kernel32 / tests / thread.c
1 /*
2  * Unit test suite for thread 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 static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL);
58 static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD);
59 static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG);
60 static DWORD (WINAPI *pSetThreadIdealProcessor)(HANDLE,DWORD);
61 static BOOL (WINAPI *pSetThreadPriorityBoost)(HANDLE,BOOL);
62 static BOOL (WINAPI *pRegisterWaitForSingleObject)(PHANDLE,HANDLE,WAITORTIMERCALLBACK,PVOID,ULONG,ULONG);
63 static BOOL (WINAPI *pUnregisterWait)(HANDLE);
64 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
65 static BOOL (WINAPI *pSetThreadErrorMode)(DWORD,PDWORD);
66 static DWORD (WINAPI *pGetThreadErrorMode)(void);
67 static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
68
69 static HANDLE create_target_process(const char *arg)
70 {
71     char **argv;
72     char cmdline[MAX_PATH];
73     PROCESS_INFORMATION pi;
74     BOOL ret;
75     STARTUPINFO si = { 0 };
76     si.cb = sizeof(si);
77
78     winetest_get_mainargs( &argv );
79     sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
80     ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
81     ok(ret, "error: %u\n", GetLastError());
82     ret = CloseHandle(pi.hThread);
83     ok(ret, "error %u\n", GetLastError());
84     return pi.hProcess;
85 }
86
87 /* Functions not tested yet:
88   AttachThreadInput
89   SetThreadContext
90   SwitchToThread
91
92 In addition there are no checks that the inheritance works properly in
93 CreateThread
94 */
95
96 /* Functions to ensure that from a group of threads, only one executes
97    certain chunks of code at a time, and we know which one is executing
98    it.  It basically makes multithreaded execution linear, which defeats
99    the purpose of multiple threads, but makes testing easy.  */
100 static HANDLE start_event, stop_event;
101 static LONG num_synced;
102
103 static void init_thread_sync_helpers(void)
104 {
105   start_event = CreateEvent(NULL, TRUE, FALSE, NULL);
106   ok(start_event != NULL, "CreateEvent failed\n");
107   stop_event = CreateEvent(NULL, TRUE, FALSE, NULL);
108   ok(stop_event != NULL, "CreateEvent failed\n");
109   num_synced = -1;
110 }
111
112 static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
113 {
114   LONG num = InterlockedIncrement(&num_synced);
115   assert(-1 <= num && num <= 1);
116   if (num == 1)
117   {
118       ResetEvent( stop_event );
119       SetEvent( start_event );
120   }
121   else
122   {
123     DWORD ret = WaitForSingleObject(start_event, 10000);
124     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed %x\n",ret);
125   }
126   return sync_id == my_id;
127 }
128
129 static void resync_after_run(void)
130 {
131   LONG num = InterlockedDecrement(&num_synced);
132   assert(-1 <= num && num <= 1);
133   if (num == -1)
134   {
135       ResetEvent( start_event );
136       SetEvent( stop_event );
137   }
138   else
139   {
140     DWORD ret = WaitForSingleObject(stop_event, 10000);
141     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
142   }
143 }
144
145 static void cleanup_thread_sync_helpers(void)
146 {
147   CloseHandle(start_event);
148   CloseHandle(stop_event);
149 }
150
151 static DWORD tlsIndex;
152
153 typedef struct {
154   int threadnum;
155   HANDLE *event;
156   DWORD *threadmem;
157 } t1Struct;
158
159 /* WinME supports OpenThread but doesn't know about access restrictions so
160    we require them to be either completely ignored or always obeyed.
161 */
162 static INT obeying_ars = 0; /* -1 == no, 0 == dunno yet, 1 == yes */
163 #define obey_ar(x) \
164   (obeying_ars == 0 \
165     ? ((x) \
166       ? (obeying_ars = +1) \
167       : ((obeying_ars = -1), \
168          trace("not restricted, assuming consistent behaviour\n"))) \
169     : (obeying_ars < 0) \
170       ? ok(!(x), "access restrictions obeyed\n") \
171       : ok( (x), "access restrictions not obeyed\n"))
172
173 /* Basic test that simultaneous threads can access shared memory,
174    that the thread local storage routines work correctly, and that
175    threads actually run concurrently
176 */
177 static DWORD WINAPI threadFunc1(LPVOID p)
178 {
179    t1Struct *tstruct = p;
180    int i;
181 /* write our thread # into shared memory */
182    tstruct->threadmem[tstruct->threadnum]=GetCurrentThreadId();
183    ok(TlsSetValue(tlsIndex,(LPVOID)(INT_PTR)(tstruct->threadnum+1))!=0,
184       "TlsSetValue failed\n");
185 /* The threads synchronize before terminating.  This is done by
186    Signaling an event, and waiting for all events to occur
187 */
188    SetEvent(tstruct->event[tstruct->threadnum]);
189    WaitForMultipleObjects(NUM_THREADS,tstruct->event,TRUE,INFINITE);
190 /* Double check that all threads really did run by validating that
191    they have all written to the shared memory. There should be no race
192    here, since all threads were synchronized after the write.*/
193    for(i=0;i<NUM_THREADS;i++) {
194      while(tstruct->threadmem[i]==0) ;
195    }
196
197    /* lstrlenA contains an exception handler so this makes sure exceptions work in threads */
198    ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
199
200 /* Check that no one changed our tls memory */
201    ok((INT_PTR)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
202       "TlsGetValue failed\n");
203    return NUM_THREADS+tstruct->threadnum;
204 }
205
206 static DWORD WINAPI threadFunc2(LPVOID p)
207 {
208    return 99;
209 }
210
211 static DWORD WINAPI threadFunc3(LPVOID p)
212 {
213    HANDLE thread;
214    thread=GetCurrentThread();
215    SuspendThread(thread);
216    return 99;
217 }
218
219 static DWORD WINAPI threadFunc4(LPVOID p)
220 {
221    HANDLE event = p;
222    if(event != NULL) {
223      SetEvent(event);
224    }
225    Sleep(99000);
226    return 0;
227 }
228
229 #if CHECK_STACK
230 static DWORD WINAPI threadFunc5(LPVOID p)
231 {
232   DWORD *exitCode = p;
233   SYSTEM_INFO sysInfo;
234   sysInfo.dwPageSize=0;
235   GetSystemInfo(&sysInfo);
236   *exitCode=0;
237    __TRY
238    {
239      alloca(2*sysInfo.dwPageSize);
240    }
241     __EXCEPT(1) {
242      *exitCode=1;
243    }
244    __ENDTRY
245    return 0;
246 }
247 #endif
248
249 static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
250 {
251     SetEvent(p);
252     return 0;
253 }
254
255 static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
256 {
257     CloseHandle(p);
258     return 0;
259 }
260
261 static void create_function_addr_events(HANDLE events[2])
262 {
263     char buffer[256];
264
265     sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent);
266     events[0] = CreateEvent(NULL, FALSE, FALSE, buffer);
267
268     sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle);
269     events[1] = CreateEvent(NULL, FALSE, FALSE, buffer);
270 }
271
272 /* check CreateRemoteThread */
273 static VOID test_CreateRemoteThread(void)
274 {
275     HANDLE hProcess, hThread, hEvent, hRemoteEvent;
276     DWORD tid, ret, exitcode;
277     HANDLE hAddrEvents[2];
278
279     hProcess = create_target_process("sleep");
280     ok(hProcess != NULL, "Can't start process\n");
281
282     /* ensure threadFunc_SetEvent & threadFunc_CloseHandle are the same
283      * address as in the child process */
284     create_function_addr_events(hAddrEvents);
285     ret = WaitForMultipleObjects(2, hAddrEvents, TRUE, 5000);
286     if (ret == WAIT_TIMEOUT)
287     {
288         skip("child process wasn't mapped at same address, so can't do CreateRemoteThread tests.\n");
289         return;
290     }
291
292     hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
293     ok(hEvent != NULL, "Can't create event, err=%u\n", GetLastError());
294     ret = DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hRemoteEvent,
295                           0, FALSE, DUPLICATE_SAME_ACCESS);
296     ok(ret != 0, "DuplicateHandle failed, err=%u\n", GetLastError());
297
298     /* create suspended remote thread with entry point SetEvent() */
299     SetLastError(0xdeadbeef);
300     hThread = CreateRemoteThread(hProcess, NULL, 0, threadFunc_SetEvent,
301                                  hRemoteEvent, CREATE_SUSPENDED, &tid);
302     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
303     {
304         win_skip("CreateRemoteThread is not implemented\n");
305         goto cleanup;
306     }
307     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
308     ok(tid != 0, "null tid\n");
309     ret = SuspendThread(hThread);
310     ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
311     ret = ResumeThread(hThread);
312     ok(ret == 2, "ret=%u, err=%u\n", ret, GetLastError());
313
314     /* thread still suspended, so wait times out */
315     ret = WaitForSingleObject(hEvent, 1000);
316     ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
317
318     ret = ResumeThread(hThread);
319     ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
320
321     /* wait that doesn't time out */
322     ret = WaitForSingleObject(hEvent, 1000);
323     ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%u\n", ret);
324
325     /* wait for thread end */
326     ret = WaitForSingleObject(hThread, 1000);
327     ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
328     CloseHandle(hThread);
329
330     /* create and wait for remote thread with entry point CloseHandle() */
331     hThread = CreateRemoteThread(hProcess, NULL, 0,
332                                  threadFunc_CloseHandle,
333                                  hRemoteEvent, 0, &tid);
334     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
335     ret = WaitForSingleObject(hThread, 1000);
336     ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
337     CloseHandle(hThread);
338
339     /* create remote thread with entry point SetEvent() */
340     hThread = CreateRemoteThread(hProcess, NULL, 0,
341                                  threadFunc_SetEvent,
342                                  hRemoteEvent, 0, &tid);
343     ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
344
345     /* closed handle, so wait times out */
346     ret = WaitForSingleObject(hEvent, 1000);
347     ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
348
349     /* check that remote SetEvent() failed */
350     ret = GetExitCodeThread(hThread, &exitcode);
351     ok(ret != 0, "GetExitCodeThread failed, err=%u\n", GetLastError());
352     if (ret) ok(exitcode == 0, "SetEvent succeeded, expected to fail\n");
353     CloseHandle(hThread);
354
355 cleanup:
356     TerminateProcess(hProcess, 0);
357     CloseHandle(hEvent);
358     CloseHandle(hProcess);
359 }
360
361 /* Check basic functionality of CreateThread and Tls* functions */
362 static VOID test_CreateThread_basic(void)
363 {
364    HANDLE thread[NUM_THREADS],event[NUM_THREADS];
365    DWORD threadid[NUM_THREADS],curthreadId;
366    DWORD threadmem[NUM_THREADS];
367    DWORD exitCode;
368    t1Struct tstruct[NUM_THREADS];
369    int error;
370    DWORD i,j;
371    DWORD GLE, ret;
372    DWORD tid;
373    BOOL bRet;
374
375    /* lstrlenA contains an exception handler so this makes sure exceptions work in the main thread */
376    ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
377
378 /* Retrieve current Thread ID for later comparisons */
379   curthreadId=GetCurrentThreadId();
380 /* Allocate some local storage */
381   ok((tlsIndex=TlsAlloc())!=TLS_OUT_OF_INDEXES,"TlsAlloc failed\n");
382 /* Create events for thread synchronization */
383   for(i=0;i<NUM_THREADS;i++) {
384     threadmem[i]=0;
385 /* Note that it doesn't matter what type of event we choose here.  This
386    test isn't trying to thoroughly test events
387 */
388     event[i]=CreateEventA(NULL,TRUE,FALSE,NULL);
389     tstruct[i].threadnum=i;
390     tstruct[i].threadmem=threadmem;
391     tstruct[i].event=event;
392   }
393
394 /* Test that passing arguments to threads works okay */
395   for(i=0;i<NUM_THREADS;i++) {
396     thread[i] = CreateThread(NULL,0,threadFunc1,
397                              &tstruct[i],0,&threadid[i]);
398     ok(thread[i]!=NULL,"Create Thread failed\n");
399   }
400 /* Test that the threads actually complete */
401   for(i=0;i<NUM_THREADS;i++) {
402     error=WaitForSingleObject(thread[i],5000);
403     ok(error==WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
404     if(error!=WAIT_OBJECT_0) {
405       TerminateThread(thread[i],i+NUM_THREADS);
406     }
407     ok(GetExitCodeThread(thread[i],&exitCode),"Could not retrieve ext code\n");
408     ok(exitCode==i+NUM_THREADS,"Thread returned an incorrect exit code\n");
409   }
410 /* Test that each thread executed in its parent's address space
411    (it was able to change threadmem and pass that change back to its parent)
412    and that each thread id was independent).  Note that we prove that the
413    threads actually execute concurrently by having them block on each other
414    in threadFunc1
415 */
416   for(i=0;i<NUM_THREADS;i++) {
417     error=0;
418     for(j=i+1;j<NUM_THREADS;j++) {
419       if (threadmem[i]==threadmem[j]) {
420         error=1;
421       }
422     }
423     ok(!error && threadmem[i]==threadid[i] && threadmem[i]!=curthreadId,
424          "Thread did not execute successfully\n");
425     ok(CloseHandle(thread[i])!=0,"CloseHandle failed\n");
426   }
427
428   SetLastError(0xCAFEF00D);
429   bRet = TlsFree(tlsIndex);
430   ok(bRet, "TlsFree failed: %08x\n", GetLastError());
431   ok(GetLastError()==0xCAFEF00D,
432      "GetLastError: expected 0xCAFEF00D, got %08x\n", GetLastError());
433
434   /* Test freeing an already freed TLS index */
435   SetLastError(0xCAFEF00D);
436   ok(TlsFree(tlsIndex)==0,"TlsFree succeeded\n");
437   ok(GetLastError()==ERROR_INVALID_PARAMETER,
438      "GetLastError: expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
439
440   /* Test how passing NULL as a pointer to threadid works */
441   SetLastError(0xFACEaBAD);
442   thread[0] = CreateThread(NULL,0,threadFunc2,NULL,0,&tid);
443   GLE = GetLastError();
444   if (thread[0]) { /* NT */
445     ok(GLE==0xFACEaBAD, "CreateThread set last error to %d, expected 4207848365\n", GLE);
446     ret = WaitForSingleObject(thread[0],100);
447     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
448     ret = GetExitCodeThread(thread[0],&exitCode);
449     ok(ret!=0, "GetExitCodeThread returned %d (expected nonzero)\n", ret);
450     ok(exitCode==99, "threadFunc2 exited with code: %d (expected 99)\n", exitCode);
451     ok(CloseHandle(thread[0])!=0,"Error closing thread handle\n");
452   }
453   else { /* 9x */
454     ok(GLE==ERROR_INVALID_PARAMETER, "CreateThread set last error to %d, expected 87\n", GLE);
455   }
456 }
457
458 /* Check that using the CREATE_SUSPENDED flag works */
459 static VOID test_CreateThread_suspended(void)
460 {
461   HANDLE thread;
462   DWORD threadId;
463   DWORD suspend_count;
464   int error;
465
466   thread = CreateThread(NULL,0,threadFunc2,NULL,
467                         CREATE_SUSPENDED,&threadId);
468   ok(thread!=NULL,"Create Thread failed\n");
469 /* Check that the thread is suspended */
470   ok(SuspendThread(thread)==1,"Thread did not start suspended\n");
471   ok(ResumeThread(thread)==2,"Resume thread returned an invalid value\n");
472 /* Check that resume thread didn't actually start the thread.  I can't think
473    of a better way of checking this than just waiting.  I am not sure if this
474    will work on slow computers.
475 */
476   ok(WaitForSingleObject(thread,1000)==WAIT_TIMEOUT,
477      "ResumeThread should not have actually started the thread\n");
478 /* Now actually resume the thread and make sure that it actually completes*/
479   ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
480   ok((error=WaitForSingleObject(thread,1000))==WAIT_OBJECT_0,
481      "Thread did not resume\n");
482   if(error!=WAIT_OBJECT_0) {
483     TerminateThread(thread,1);
484   }
485
486   suspend_count = SuspendThread(thread);
487   ok(suspend_count == -1, "SuspendThread returned %d, expected -1\n", suspend_count);
488
489   suspend_count = ResumeThread(thread);
490   ok(suspend_count == 0 ||
491      broken(suspend_count == -1), /* win9x */
492      "ResumeThread returned %d, expected 0\n", suspend_count);
493
494   ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
495 }
496
497 /* Check that SuspendThread and ResumeThread work */
498 static VOID test_SuspendThread(void)
499 {
500   HANDLE thread,access_thread;
501   DWORD threadId,exitCode,error;
502   int i;
503
504   thread = CreateThread(NULL,0,threadFunc3,NULL,
505                         0,&threadId);
506   ok(thread!=NULL,"Create Thread failed\n");
507 /* Check that the thread is suspended */
508 /* Note that this is a polling method, and there is a race between
509    SuspendThread being called (in the child, and the loop below timing out,
510    so the test could fail on a heavily loaded or slow computer.
511 */
512   error=0;
513   for(i=0;error==0 && i<100;i++) {
514     error=SuspendThread(thread);
515     ResumeThread(thread);
516     if(error==0) {
517       Sleep(50);
518       i++;
519     }
520   }
521   ok(error==1,"SuspendThread did not work\n");
522 /* check that access restrictions are obeyed */
523   if (pOpenThread) {
524     access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME),
525                            0,threadId);
526     ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
527     if (access_thread!=NULL) {
528       obey_ar(SuspendThread(access_thread)==~0U);
529       obey_ar(ResumeThread(access_thread)==~0U);
530       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
531     }
532   }
533 /* Double check that the thread really is suspended */
534   ok((error=GetExitCodeThread(thread,&exitCode))!=0 && exitCode==STILL_ACTIVE,
535      "Thread did not really suspend\n");
536 /* Resume the thread, and make sure it actually completes */
537   ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
538   ok((error=WaitForSingleObject(thread,1000))==WAIT_OBJECT_0,
539      "Thread did not resume\n");
540   if(error!=WAIT_OBJECT_0) {
541     TerminateThread(thread,1);
542   }
543   /* Trying to suspend a terminated thread should fail */
544   error=SuspendThread(thread);
545   ok(error==~0U, "wrong return code: %d\n", error);
546   ok(GetLastError()==ERROR_ACCESS_DENIED || GetLastError()==ERROR_NO_MORE_ITEMS, "unexpected error code: %d\n", GetLastError());
547
548   ok(CloseHandle(thread)!=0,"CloseHandle Failed\n");
549 }
550
551 /* Check that TerminateThread works properly
552 */
553 static VOID test_TerminateThread(void)
554 {
555   HANDLE thread,access_thread,event;
556   DWORD threadId,exitCode;
557   event=CreateEventA(NULL,TRUE,FALSE,NULL);
558   thread = CreateThread(NULL,0,threadFunc4,event,0,&threadId);
559   ok(thread!=NULL,"Create Thread failed\n");
560 /* TerminateThread has a race condition in Wine.  If the thread is terminated
561    before it starts, it leaves a process behind.  Therefore, we wait for the
562    thread to signal that it has started.  There is no easy way to force the
563    race to occur, so we don't try to find it.
564 */
565   ok(WaitForSingleObject(event,5000)==WAIT_OBJECT_0,
566      "TerminateThread didn't work\n");
567 /* check that access restrictions are obeyed */
568   if (pOpenThread) {
569     access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_TERMINATE),
570                              0,threadId);
571     ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
572     if (access_thread!=NULL) {
573       obey_ar(TerminateThread(access_thread,99)==0);
574       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
575     }
576   }
577 /* terminate a job and make sure it terminates */
578   ok(TerminateThread(thread,99)!=0,"TerminateThread failed\n");
579   ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
580      "TerminateThread didn't work\n");
581   ok(GetExitCodeThread(thread,&exitCode)!=STILL_ACTIVE,
582      "TerminateThread should not leave the thread 'STILL_ACTIVE'\n");
583   ok(exitCode==99, "TerminateThread returned invalid exit code\n");
584   ok(CloseHandle(thread)!=0,"Error Closing thread handle\n");
585 }
586
587 /* Check if CreateThread obeys the specified stack size.  This code does
588    not work properly, and is currently disabled
589 */
590 static VOID test_CreateThread_stack(void)
591 {
592 #if CHECK_STACK
593 /* The only way I know of to test the stack size is to use alloca
594    and __try/__except.  However, this is probably not portable,
595    and I couldn't get it to work under Wine anyhow.  However, here
596    is the code which should allow for testing that CreateThread
597    respects the stack-size limit
598 */
599      HANDLE thread;
600      DWORD threadId,exitCode;
601
602      SYSTEM_INFO sysInfo;
603      sysInfo.dwPageSize=0;
604      GetSystemInfo(&sysInfo);
605      ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
606      thread = CreateThread(NULL,sysInfo.dwPageSize,
607                            threadFunc5,&exitCode,
608                            0,&threadId);
609      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
610         "TerminateThread didn't work\n");
611      ok(exitCode==1,"CreateThread did not obey stack-size-limit\n");
612      ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
613 #endif
614 }
615
616 /* Check whether setting/retrieving thread priorities works */
617 static VOID test_thread_priority(void)
618 {
619    HANDLE curthread,access_thread;
620    DWORD curthreadId,exitCode;
621    int min_priority=-2,max_priority=2;
622    BOOL disabled,rc;
623    int i;
624
625    curthread=GetCurrentThread();
626    curthreadId=GetCurrentThreadId();
627 /* Check thread priority */
628 /* NOTE: on Win2k/XP priority can be from -7 to 6.  All other platforms it
629          is -2 to 2.  However, even on a real Win2k system, using thread
630          priorities beyond the -2 to 2 range does not work.  If you want to try
631          anyway, enable USE_EXTENDED_PRIORITIES
632 */
633    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_NORMAL,
634       "GetThreadPriority Failed\n");
635
636    if (pOpenThread) {
637 /* check that access control is obeyed */
638      access_thread=pOpenThread(THREAD_ALL_ACCESS &
639                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
640                        0,curthreadId);
641      ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
642      if (access_thread!=NULL) {
643        obey_ar(SetThreadPriority(access_thread,1)==0);
644        obey_ar(GetThreadPriority(access_thread)==THREAD_PRIORITY_ERROR_RETURN);
645        obey_ar(GetExitCodeThread(access_thread,&exitCode)==0);
646        ok(CloseHandle(access_thread),"Error Closing thread handle\n");
647      }
648    }
649 #if USE_EXTENDED_PRIORITIES
650    min_priority=-7; max_priority=6;
651 #endif
652    for(i=min_priority;i<=max_priority;i++) {
653      ok(SetThreadPriority(curthread,i)!=0,
654         "SetThreadPriority Failed for priority: %d\n",i);
655      ok(GetThreadPriority(curthread)==i,
656         "GetThreadPriority Failed for priority: %d\n",i);
657    }
658    ok(SetThreadPriority(curthread,THREAD_PRIORITY_TIME_CRITICAL)!=0,
659       "SetThreadPriority Failed\n");
660    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_TIME_CRITICAL,
661       "GetThreadPriority Failed\n");
662    ok(SetThreadPriority(curthread,THREAD_PRIORITY_IDLE)!=0,
663        "SetThreadPriority Failed\n");
664    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_IDLE,
665        "GetThreadPriority Failed\n");
666    ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed\n");
667
668 /* Check that the thread priority is not changed if SetThreadPriority
669    is called with a value outside of the max/min range */
670    SetThreadPriority(curthread,min_priority);
671    SetLastError(0xdeadbeef);
672    rc = SetThreadPriority(curthread,min_priority-1);
673
674    ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
675    ok(GetLastError() == ERROR_INVALID_PARAMETER ||
676       GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
677       "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
678       GetLastError());
679    ok(GetThreadPriority(curthread)==min_priority,
680       "GetThreadPriority didn't return min_priority\n");
681
682    SetThreadPriority(curthread,max_priority);
683    SetLastError(0xdeadbeef);
684    rc = SetThreadPriority(curthread,max_priority+1);
685
686    ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
687    ok(GetLastError() == ERROR_INVALID_PARAMETER ||
688       GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
689       "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
690       GetLastError());
691    ok(GetThreadPriority(curthread)==max_priority,
692       "GetThreadPriority didn't return max_priority\n");
693
694 /* Check thread priority boost */
695    if (!pGetThreadPriorityBoost || !pSetThreadPriorityBoost) 
696      return; /* Win9x */
697
698    SetLastError(0xdeadbeef);
699    rc=pGetThreadPriorityBoost(curthread,&disabled);
700    if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
701    {
702       win_skip("GetThreadPriorityBoost is not implemented on WinME\n");
703       return;
704    }
705
706    ok(rc!=0,"error=%d\n",GetLastError());
707
708    if (pOpenThread) {
709 /* check that access control is obeyed */
710      access_thread=pOpenThread(THREAD_ALL_ACCESS &
711                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
712                        0,curthreadId);
713      ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
714      if (access_thread!=NULL) {
715        obey_ar(pSetThreadPriorityBoost(access_thread,1)==0);
716        todo_wine obey_ar(pGetThreadPriorityBoost(access_thread,&disabled)==0);
717        ok(CloseHandle(access_thread),"Error Closing thread handle\n");
718      }
719    }
720
721    todo_wine {
722      rc = pSetThreadPriorityBoost(curthread,1);
723      ok( rc != 0, "error=%d\n",GetLastError());
724      rc=pGetThreadPriorityBoost(curthread,&disabled);
725      ok(rc!=0 && disabled==1,
726         "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
727
728      rc = pSetThreadPriorityBoost(curthread,0);
729      ok( rc != 0, "error=%d\n",GetLastError());
730    }
731    rc=pGetThreadPriorityBoost(curthread,&disabled);
732    ok(rc!=0 && disabled==0,
733       "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
734 }
735
736 /* check the GetThreadTimes function */
737 static VOID test_GetThreadTimes(void)
738 {
739      HANDLE thread,access_thread=NULL;
740      FILETIME creationTime,exitTime,kernelTime,userTime;
741      DWORD threadId;
742      int error;
743
744      thread = CreateThread(NULL,0,threadFunc2,NULL,
745                            CREATE_SUSPENDED,&threadId);
746
747      ok(thread!=NULL,"Create Thread failed\n");
748 /* check that access control is obeyed */
749      if (pOpenThread) {
750        access_thread=pOpenThread(THREAD_ALL_ACCESS &
751                                    (~THREAD_QUERY_INFORMATION), 0,threadId);
752        ok(access_thread!=NULL,
753           "OpenThread returned an invalid handle\n");
754      }
755      ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
756      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
757         "ResumeThread didn't work\n");
758      creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
759      exitTime.dwLowDateTime=99;     exitTime.dwHighDateTime=99;
760      kernelTime.dwLowDateTime=99;   kernelTime.dwHighDateTime=99;
761      userTime.dwLowDateTime=99;     userTime.dwHighDateTime=99;
762 /* GetThreadTimes should set all of the parameters passed to it */
763      error=GetThreadTimes(thread,&creationTime,&exitTime,
764                           &kernelTime,&userTime);
765
766      if (error == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
767        win_skip("GetThreadTimes is not implemented\n");
768      else {
769        ok(error!=0,"GetThreadTimes failed\n");
770        ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
771           "creationTime was invalid\n");
772        ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
773           "exitTime was invalid\n");
774        ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
775           "kernelTimewas invalid\n");
776        ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
777           "userTime was invalid\n");
778        ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
779        if(access_thread!=NULL)
780        {
781          error=GetThreadTimes(access_thread,&creationTime,&exitTime,
782                               &kernelTime,&userTime);
783          obey_ar(error==0);
784        }
785      }
786      if(access_thread!=NULL) {
787        ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
788      }
789 }
790
791 /* Check the processor affinity functions */
792 /* NOTE: These functions should also be checked that they obey access control
793 */
794 static VOID test_thread_processor(void)
795 {
796    HANDLE curthread,curproc;
797    DWORD_PTR processMask,systemMask,retMask;
798    SYSTEM_INFO sysInfo;
799    int error=0;
800    BOOL is_wow64;
801
802    if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
803
804    sysInfo.dwNumberOfProcessors=0;
805    GetSystemInfo(&sysInfo);
806    ok(sysInfo.dwNumberOfProcessors>0,
807       "GetSystemInfo failed to return a valid # of processors\n");
808 /* Use the current Thread/process for all tests */
809    curthread=GetCurrentThread();
810    ok(curthread!=NULL,"GetCurrentThread failed\n");
811    curproc=GetCurrentProcess();
812    ok(curproc!=NULL,"GetCurrentProcess failed\n");
813 /* Check the Affinity Mask functions */
814    ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
815       "GetProcessAffinityMask failed\n");
816    ok(SetThreadAffinityMask(curthread,processMask)==processMask,
817       "SetThreadAffinityMask failed\n");
818    ok(SetThreadAffinityMask(curthread,processMask+1)==0,
819       "SetThreadAffinityMask passed for an illegal processor\n");
820 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
821    retMask = SetThreadAffinityMask(curthread,~0);
822    ok(broken(retMask==0) || retMask==processMask,
823       "SetThreadAffinityMask(thread,-1) failed to request all processors.\n");
824    if (retMask == processMask && sizeof(ULONG_PTR) > sizeof(ULONG))
825    {
826        /* only the low 32-bits matter */
827        retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0);
828        ok(retMask == processMask, "SetThreadAffinityMask failed\n");
829        retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0 >> 3);
830        ok(retMask == processMask, "SetThreadAffinityMask failed\n");
831        retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)1);
832        ok(retMask == 0, "SetThreadAffinityMask succeeded\n");
833    }
834 /* NOTE: This only works on WinNT/2000/XP) */
835    if (pSetThreadIdealProcessor) {
836      SetLastError(0xdeadbeef);
837      error=pSetThreadIdealProcessor(curthread,0);
838      if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
839      {
840        win_skip("SetThreadIdealProcessor is not implemented\n");
841        return;
842      }
843      ok(error!=-1, "SetThreadIdealProcessor failed\n");
844
845      if (is_wow64)
846      {
847          SetLastError(0xdeadbeef);
848          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
849          todo_wine
850          ok(error!=-1, "SetThreadIdealProcessor failed for %u on Wow64\n", MAXIMUM_PROCESSORS+1);
851
852          SetLastError(0xdeadbeef);
853          error=pSetThreadIdealProcessor(curthread,65);
854          ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
855          ok(GetLastError()==ERROR_INVALID_PARAMETER,
856             "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
857      }
858      else
859      {
860          SetLastError(0xdeadbeef);
861          error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
862          ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
863          ok(GetLastError()==ERROR_INVALID_PARAMETER,
864             "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
865      }
866
867      error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
868      ok(error!=-1, "SetThreadIdealProcessor failed\n");
869    }
870 }
871
872 static VOID test_GetThreadExitCode(void)
873 {
874     DWORD exitCode, threadid;
875     DWORD GLE, ret;
876     HANDLE thread;
877
878     ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
879     ok(ret==0, "GetExitCodeThread returned non zero value: %d\n", ret);
880     GLE = GetLastError();
881     ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %d (expected 6)\n", GLE);
882
883     thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
884     ret = WaitForSingleObject(thread,100);
885     ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
886     ret = GetExitCodeThread(thread,&exitCode);
887     ok(ret==exitCode || ret==1, 
888        "GetExitCodeThread returned %d (expected 1 or %d)\n", ret, exitCode);
889     ok(exitCode==99, "threadFunc2 exited with code %d (expected 99)\n", exitCode);
890     ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
891 }
892
893 #ifdef __i386__
894
895 static int test_value = 0;
896 static HANDLE event;
897
898 static void WINAPI set_test_val( int val )
899 {
900     test_value += val;
901     ExitThread(0);
902 }
903
904 static DWORD WINAPI threadFunc6(LPVOID p)
905 {
906     SetEvent( event );
907     Sleep( 1000 );
908     test_value *= (int)p;
909     return 0;
910 }
911
912 static void test_SetThreadContext(void)
913 {
914     CONTEXT ctx;
915     int *stack;
916     HANDLE thread;
917     DWORD threadid;
918     DWORD prevcount;
919     BOOL ret;
920
921     SetLastError(0xdeadbeef);
922     event = CreateEvent( NULL, TRUE, FALSE, NULL );
923     thread = CreateThread( NULL, 0, threadFunc6, (void *)2, 0, &threadid );
924     ok( thread != NULL, "CreateThread failed : (%d)\n", GetLastError() );
925     if (!thread)
926     {
927         trace("Thread creation failed, skipping rest of test\n");
928         return;
929     }
930     WaitForSingleObject( event, INFINITE );
931     SuspendThread( thread );
932     CloseHandle( event );
933
934     ctx.ContextFlags = CONTEXT_FULL;
935     SetLastError(0xdeadbeef);
936     ret = GetThreadContext( thread, &ctx );
937     ok( ret, "GetThreadContext failed : (%u)\n", GetLastError() );
938
939     if (ret)
940     {
941         /* simulate a call to set_test_val(10) */
942         stack = (int *)ctx.Esp;
943         stack[-1] = 10;
944         stack[-2] = ctx.Eip;
945         ctx.Esp -= 2 * sizeof(int *);
946         ctx.Eip = (DWORD)set_test_val;
947         SetLastError(0xdeadbeef);
948         ret = SetThreadContext( thread, &ctx );
949         ok( ret, "SetThreadContext failed : (%d)\n", GetLastError() );
950     }
951
952     SetLastError(0xdeadbeef);
953     prevcount = ResumeThread( thread );
954     ok ( prevcount == 1, "Previous suspend count (%d) instead of 1, last error : (%d)\n",
955                          prevcount, GetLastError() );
956
957     WaitForSingleObject( thread, INFINITE );
958     ok( test_value == 10, "test_value %d\n", test_value );
959
960     ctx.ContextFlags = CONTEXT_FULL;
961     SetLastError(0xdeadbeef);
962     ret = GetThreadContext( thread, &ctx );
963     ok( !ret, "GetThreadContext succeeded\n" );
964     ok( GetLastError() == ERROR_GEN_FAILURE || broken(GetLastError() == ERROR_INVALID_HANDLE), /* win2k */
965         "wrong error %u\n", GetLastError() );
966
967     SetLastError(0xdeadbeef);
968     ret = SetThreadContext( thread, &ctx );
969     ok( !ret, "SetThreadContext succeeded\n" );
970     ok( GetLastError() == ERROR_GEN_FAILURE || GetLastError() == ERROR_ACCESS_DENIED ||
971         broken(GetLastError() == ERROR_INVALID_HANDLE), /* win2k */
972         "wrong error %u\n", GetLastError() );
973
974     CloseHandle( thread );
975 }
976
977 #endif  /* __i386__ */
978
979 static HANDLE finish_event;
980 static LONG times_executed;
981
982 static DWORD CALLBACK work_function(void *p)
983 {
984     LONG executed = InterlockedIncrement(&times_executed);
985
986     if (executed == 100)
987         SetEvent(finish_event);
988     return 0;
989 }
990
991 static void test_QueueUserWorkItem(void)
992 {
993     INT_PTR i;
994     DWORD wait_result;
995     DWORD before, after;
996
997     /* QueueUserWorkItem not present on win9x */
998     if (!pQueueUserWorkItem) return;
999
1000     finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
1001
1002     before = GetTickCount();
1003
1004     for (i = 0; i < 100; i++)
1005     {
1006         BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
1007         ok(ret, "QueueUserWorkItem failed with error %d\n", GetLastError());
1008     }
1009
1010     wait_result = WaitForSingleObject(finish_event, 10000);
1011
1012     after = GetTickCount();
1013     trace("100 QueueUserWorkItem calls took %dms\n", after - before);
1014     ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%x\n", wait_result);
1015
1016     ok(times_executed == 100, "didn't execute all of the work items\n");
1017 }
1018
1019 static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
1020 {
1021     HANDLE event = p;
1022     SetEvent(event);
1023     ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
1024 }
1025
1026 static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
1027 {
1028     HANDLE event = p;
1029     SetEvent(event);
1030     ok(TimerOrWaitFired, "wait should have timed out\n");
1031 }
1032
1033 static void test_RegisterWaitForSingleObject(void)
1034 {
1035     BOOL ret;
1036     HANDLE wait_handle;
1037     HANDLE handle;
1038     HANDLE complete_event;
1039
1040     if (!pRegisterWaitForSingleObject || !pUnregisterWait)
1041     {
1042         win_skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
1043         return;
1044     }
1045
1046     /* test signaled case */
1047
1048     handle = CreateEvent(NULL, TRUE, TRUE, NULL);
1049     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
1050
1051     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1052     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1053
1054     WaitForSingleObject(complete_event, INFINITE);
1055     /* give worker thread chance to complete */
1056     Sleep(100);
1057
1058     ret = pUnregisterWait(wait_handle);
1059     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1060
1061     /* test cancel case */
1062
1063     ResetEvent(handle);
1064
1065     ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1066     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1067
1068     ret = pUnregisterWait(wait_handle);
1069     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1070
1071     /* test timeout case */
1072
1073     ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
1074     ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1075
1076     WaitForSingleObject(complete_event, INFINITE);
1077     /* give worker thread chance to complete */
1078     Sleep(100);
1079
1080     ret = pUnregisterWait(wait_handle);
1081     ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1082 }
1083
1084 static DWORD TLS_main;
1085 static DWORD TLS_index0, TLS_index1;
1086
1087 static DWORD WINAPI TLS_InheritanceProc(LPVOID p)
1088 {
1089   /* We should NOT inherit the TLS values from our parent or from the
1090      main thread.  */
1091   LPVOID val;
1092
1093   val = TlsGetValue(TLS_main);
1094   ok(val == NULL, "TLS inheritance failed\n");
1095
1096   val = TlsGetValue(TLS_index0);
1097   ok(val == NULL, "TLS inheritance failed\n");
1098
1099   val = TlsGetValue(TLS_index1);
1100   ok(val == NULL, "TLS inheritance failed\n");
1101
1102   return 0;
1103 }
1104
1105 /* Basic TLS usage test.  Make sure we can create slots and the values we
1106    store in them are separate among threads.  Also test TLS value
1107    inheritance with TLS_InheritanceProc.  */
1108 static DWORD WINAPI TLS_ThreadProc(LPVOID p)
1109 {
1110   LONG_PTR id = (LONG_PTR) p;
1111   LPVOID val;
1112   BOOL ret;
1113
1114   if (sync_threads_and_run_one(0, id))
1115   {
1116     TLS_index0 = TlsAlloc();
1117     ok(TLS_index0 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1118   }
1119   resync_after_run();
1120
1121   if (sync_threads_and_run_one(1, id))
1122   {
1123     TLS_index1 = TlsAlloc();
1124     ok(TLS_index1 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1125
1126     /* Slot indices should be different even if created in different
1127        threads.  */
1128     ok(TLS_index0 != TLS_index1, "TlsAlloc failed\n");
1129
1130     /* Both slots should be initialized to NULL */
1131     val = TlsGetValue(TLS_index0);
1132     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1133     ok(val == NULL, "TLS slot not initialized correctly\n");
1134
1135     val = TlsGetValue(TLS_index1);
1136     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1137     ok(val == NULL, "TLS slot not initialized correctly\n");
1138   }
1139   resync_after_run();
1140
1141   if (sync_threads_and_run_one(0, id))
1142   {
1143     val = TlsGetValue(TLS_index0);
1144     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1145     ok(val == NULL, "TLS slot not initialized correctly\n");
1146
1147     val = TlsGetValue(TLS_index1);
1148     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1149     ok(val == NULL, "TLS slot not initialized correctly\n");
1150
1151     ret = TlsSetValue(TLS_index0, (LPVOID) 1);
1152     ok(ret, "TlsSetValue failed\n");
1153
1154     ret = TlsSetValue(TLS_index1, (LPVOID) 2);
1155     ok(ret, "TlsSetValue failed\n");
1156
1157     val = TlsGetValue(TLS_index0);
1158     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1159     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1160
1161     val = TlsGetValue(TLS_index1);
1162     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1163     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1164   }
1165   resync_after_run();
1166
1167   if (sync_threads_and_run_one(1, id))
1168   {
1169     val = TlsGetValue(TLS_index0);
1170     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1171     ok(val == NULL, "TLS slot not initialized correctly\n");
1172
1173     val = TlsGetValue(TLS_index1);
1174     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1175     ok(val == NULL, "TLS slot not initialized correctly\n");
1176
1177     ret = TlsSetValue(TLS_index0, (LPVOID) 3);
1178     ok(ret, "TlsSetValue failed\n");
1179
1180     ret = TlsSetValue(TLS_index1, (LPVOID) 4);
1181     ok(ret, "TlsSetValue failed\n");
1182
1183     val = TlsGetValue(TLS_index0);
1184     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1185     ok(val == (LPVOID) 3, "TLS slot not initialized correctly\n");
1186
1187     val = TlsGetValue(TLS_index1);
1188     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1189     ok(val == (LPVOID) 4, "TLS slot not initialized correctly\n");
1190   }
1191   resync_after_run();
1192
1193   if (sync_threads_and_run_one(0, id))
1194   {
1195     HANDLE thread;
1196     DWORD waitret, tid;
1197
1198     val = TlsGetValue(TLS_index0);
1199     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1200     ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
1201
1202     val = TlsGetValue(TLS_index1);
1203     ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
1204     ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
1205
1206     thread = CreateThread(NULL, 0, TLS_InheritanceProc, 0, 0, &tid);
1207     ok(thread != NULL, "CreateThread failed\n");
1208     waitret = WaitForSingleObject(thread, 60000);
1209     ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1210     CloseHandle(thread);
1211
1212     ret = TlsFree(TLS_index0);
1213     ok(ret, "TlsFree failed\n");
1214   }
1215   resync_after_run();
1216
1217   if (sync_threads_and_run_one(1, id))
1218   {
1219     ret = TlsFree(TLS_index1);
1220     ok(ret, "TlsFree failed\n");
1221   }
1222   resync_after_run();
1223
1224   return 0;
1225 }
1226
1227 static void test_TLS(void)
1228 {
1229   HANDLE threads[2];
1230   LONG_PTR i;
1231   DWORD ret;
1232   BOOL suc;
1233
1234   init_thread_sync_helpers();
1235
1236   /* Allocate a TLS slot in the main thread to test for inheritance.  */
1237   TLS_main = TlsAlloc();
1238   ok(TLS_main != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
1239   suc = TlsSetValue(TLS_main, (LPVOID) 4114);
1240   ok(suc, "TlsSetValue failed\n");
1241
1242   for (i = 0; i < 2; ++i)
1243   {
1244     DWORD tid;
1245
1246     threads[i] = CreateThread(NULL, 0, TLS_ThreadProc, (LPVOID) i, 0, &tid);
1247     ok(threads[i] != NULL, "CreateThread failed\n");
1248   }
1249
1250   ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1251   ok(ret == WAIT_OBJECT_0 || ret == WAIT_OBJECT_0+1 /* nt4 */, "WaitForMultipleObjects failed %u\n",ret);
1252
1253   for (i = 0; i < 2; ++i)
1254     CloseHandle(threads[i]);
1255
1256   suc = TlsFree(TLS_main);
1257   ok(suc, "TlsFree failed\n");
1258   cleanup_thread_sync_helpers();
1259 }
1260
1261 static void test_ThreadErrorMode(void)
1262 {
1263     DWORD oldmode;
1264     DWORD mode;
1265     DWORD rtlmode;
1266     BOOL ret;
1267
1268     if (!pSetThreadErrorMode || !pGetThreadErrorMode)
1269     {
1270         win_skip("SetThreadErrorMode and/or GetThreadErrorMode unavailable (added in Windows 7)\n");
1271         return;
1272     }
1273
1274     if (!pRtlGetThreadErrorMode) {
1275         win_skip("RtlGetThreadErrorMode not available\n");
1276         return;
1277     }
1278
1279     oldmode = pGetThreadErrorMode();
1280
1281     ret = pSetThreadErrorMode(0, &mode);
1282     ok(ret, "SetThreadErrorMode failed\n");
1283     ok(mode == oldmode,
1284        "SetThreadErrorMode returned old mode 0x%x, expected 0x%x\n",
1285        mode, oldmode);
1286     mode = pGetThreadErrorMode();
1287     ok(mode == 0, "GetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1288     rtlmode = pRtlGetThreadErrorMode();
1289     ok(rtlmode == 0,
1290        "RtlGetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1291
1292     ret = pSetThreadErrorMode(SEM_FAILCRITICALERRORS, &mode);
1293     ok(ret, "SetThreadErrorMode failed\n");
1294     ok(mode == 0,
1295        "SetThreadErrorMode returned old mode 0x%x, expected 0\n", mode);
1296     mode = pGetThreadErrorMode();
1297     ok(mode == SEM_FAILCRITICALERRORS,
1298        "GetThreadErrorMode returned mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1299        mode);
1300     rtlmode = pRtlGetThreadErrorMode();
1301     ok(rtlmode == 0x10,
1302        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x10\n", mode);
1303
1304     ret = pSetThreadErrorMode(SEM_NOGPFAULTERRORBOX, &mode);
1305     ok(ret, "SetThreadErrorMode failed\n");
1306     ok(mode == SEM_FAILCRITICALERRORS,
1307        "SetThreadErrorMode returned old mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1308        mode);
1309     mode = pGetThreadErrorMode();
1310     ok(mode == SEM_NOGPFAULTERRORBOX,
1311        "GetThreadErrorMode returned mode 0x%x, expected SEM_NOGPFAULTERRORBOX\n",
1312        mode);
1313     rtlmode = pRtlGetThreadErrorMode();
1314     ok(rtlmode == 0x20,
1315        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x20\n", mode);
1316
1317     ret = pSetThreadErrorMode(SEM_NOOPENFILEERRORBOX, NULL);
1318     ok(ret, "SetThreadErrorMode failed\n");
1319     mode = pGetThreadErrorMode();
1320     ok(mode == SEM_NOOPENFILEERRORBOX,
1321        "GetThreadErrorMode returned mode 0x%x, expected SEM_NOOPENFILEERRORBOX\n",
1322        mode);
1323     rtlmode = pRtlGetThreadErrorMode();
1324     ok(rtlmode == 0x40,
1325        "RtlGetThreadErrorMode returned mode 0x%x, expected 0x40\n", rtlmode);
1326
1327     for (mode = 1; mode; mode <<= 1)
1328     {
1329         ret = pSetThreadErrorMode(mode, NULL);
1330         if (mode & (SEM_FAILCRITICALERRORS |
1331                     SEM_NOGPFAULTERRORBOX |
1332                     SEM_NOOPENFILEERRORBOX))
1333         {
1334             ok(ret,
1335                "SetThreadErrorMode(0x%x,NULL) failed with error %d\n",
1336                mode, GetLastError());
1337         }
1338         else
1339         {
1340             DWORD GLE = GetLastError();
1341             ok(!ret,
1342                "SetThreadErrorMode(0x%x,NULL) succeeded, expected failure\n",
1343                mode);
1344             ok(GLE == ERROR_INVALID_PARAMETER,
1345                "SetThreadErrorMode(0x%x,NULL) failed with %d, "
1346                "expected ERROR_INVALID_PARAMETER\n",
1347                mode, GLE);
1348         }
1349     }
1350
1351     pSetThreadErrorMode(oldmode, NULL);
1352 }
1353
1354 static inline void set_fpu_cw(WORD cw)
1355 {
1356 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1357     __asm__ volatile ("fnclex; fldcw %0" : : "m" (cw));
1358 #endif
1359 }
1360
1361 static inline WORD get_fpu_cw(void)
1362 {
1363     WORD cw = 0;
1364 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1365     __asm__ volatile ("fnstcw %0" : "=m" (cw));
1366 #endif
1367     return cw;
1368 }
1369
1370 struct fpu_thread_ctx
1371 {
1372     WORD cw;
1373     HANDLE finished;
1374 };
1375
1376 static DWORD WINAPI fpu_thread(void *param)
1377 {
1378     struct fpu_thread_ctx *ctx = param;
1379     BOOL ret;
1380
1381     ctx->cw = get_fpu_cw();
1382
1383     ret = SetEvent(ctx->finished);
1384     ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
1385
1386     return 0;
1387 }
1388
1389 static WORD get_thread_fpu_cw(void)
1390 {
1391     struct fpu_thread_ctx ctx;
1392     DWORD tid, res;
1393     HANDLE thread;
1394
1395     ctx.finished = CreateEvent(NULL, FALSE, FALSE, NULL);
1396     ok(!!ctx.finished, "Failed to create event, last error %#x.\n", GetLastError());
1397
1398     thread = CreateThread(NULL, 0, fpu_thread, &ctx, 0, &tid);
1399     ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
1400
1401     res = WaitForSingleObject(ctx.finished, INFINITE);
1402     ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1403
1404     res = CloseHandle(ctx.finished);
1405     ok(!!res, "Failed to close event handle, last error %#x.\n", GetLastError());
1406
1407     return ctx.cw;
1408 }
1409
1410 static void test_thread_fpu_cw(void)
1411 {
1412     WORD initial_cw, cw;
1413
1414     initial_cw = get_fpu_cw();
1415     ok(initial_cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", initial_cw);
1416
1417     cw = get_thread_fpu_cw();
1418     ok(cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", cw);
1419
1420     set_fpu_cw(0xf60);
1421     cw = get_fpu_cw();
1422     ok(cw == 0xf60, "Expected FPU control word 0xf60, got %#x.\n", cw);
1423
1424     cw = get_thread_fpu_cw();
1425     ok(cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", cw);
1426
1427     cw = get_fpu_cw();
1428     ok(cw == 0xf60, "Expected FPU control word 0xf60, got %#x.\n", cw);
1429
1430     set_fpu_cw(initial_cw);
1431     cw = get_fpu_cw();
1432     ok(cw == initial_cw, "Expected FPU control word %#x, got %#x.\n", initial_cw, cw);
1433 }
1434
1435 START_TEST(thread)
1436 {
1437    HINSTANCE lib;
1438    HINSTANCE ntdll;
1439    int argc;
1440    char **argv;
1441    argc = winetest_get_mainargs( &argv );
1442 /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
1443    so that the compile passes
1444 */
1445    lib=GetModuleHandleA("kernel32.dll");
1446    ok(lib!=NULL,"Couldn't get a handle for kernel32.dll\n");
1447    pGetThreadPriorityBoost=(void *)GetProcAddress(lib,"GetThreadPriorityBoost");
1448    pOpenThread=(void *)GetProcAddress(lib,"OpenThread");
1449    pQueueUserWorkItem=(void *)GetProcAddress(lib,"QueueUserWorkItem");
1450    pSetThreadIdealProcessor=(void *)GetProcAddress(lib,"SetThreadIdealProcessor");
1451    pSetThreadPriorityBoost=(void *)GetProcAddress(lib,"SetThreadPriorityBoost");
1452    pRegisterWaitForSingleObject=(void *)GetProcAddress(lib,"RegisterWaitForSingleObject");
1453    pUnregisterWait=(void *)GetProcAddress(lib,"UnregisterWait");
1454    pIsWow64Process=(void *)GetProcAddress(lib,"IsWow64Process");
1455    pSetThreadErrorMode=(void *)GetProcAddress(lib,"SetThreadErrorMode");
1456    pGetThreadErrorMode=(void *)GetProcAddress(lib,"GetThreadErrorMode");
1457
1458    ntdll=GetModuleHandleA("ntdll.dll");
1459    if (ntdll)
1460    {
1461        pRtlGetThreadErrorMode=(void *)GetProcAddress(ntdll,"RtlGetThreadErrorMode");
1462    }
1463
1464    if (argc >= 3)
1465    {
1466        if (!strcmp(argv[2], "sleep"))
1467        {
1468            HANDLE hAddrEvents[2];
1469            create_function_addr_events(hAddrEvents);
1470            SetEvent(hAddrEvents[0]);
1471            SetEvent(hAddrEvents[1]);
1472            Sleep(5000); /* spawned process runs for at most 5 seconds */
1473            return;
1474        }
1475        while (1)
1476        {
1477            HANDLE hThread;
1478            DWORD tid;
1479            hThread = CreateThread(NULL, 0, threadFunc2, NULL, 0, &tid);
1480            ok(hThread != NULL, "CreateThread failed, error %u\n",
1481               GetLastError());
1482            ok(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0,
1483               "Thread did not exit in time\n");
1484            if (hThread == NULL) break;
1485            CloseHandle(hThread);
1486        }
1487        return;
1488    }
1489
1490    test_CreateRemoteThread();
1491    test_CreateThread_basic();
1492    test_CreateThread_suspended();
1493    test_SuspendThread();
1494    test_TerminateThread();
1495    test_CreateThread_stack();
1496    test_thread_priority();
1497    test_GetThreadTimes();
1498    test_thread_processor();
1499    test_GetThreadExitCode();
1500 #ifdef __i386__
1501    test_SetThreadContext();
1502 #endif
1503    test_QueueUserWorkItem();
1504    test_RegisterWaitForSingleObject();
1505    test_TLS();
1506    test_ThreadErrorMode();
1507 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1508    test_thread_fpu_cw();
1509 #endif
1510 }