BOOLEAN InitThreads() { /* Create a LL hook that drops any physical keyboard and mouse action and prevent the user from interfering with the test results */ if(!IsDebuggerPresent()) { hMouseHookLL = SetWindowsHookExW(WH_MOUSE_LL, MouseLLHookProc, GetModuleHandleW( NULL ), 0); ok(hMouseHookLL!=NULL,"failed to set hook\n"); hKbdHookLL = SetWindowsHookExW(WH_KEYBOARD_LL, KbdLLHookProc, GetModuleHandleW( NULL ), 0); ok(hKbdHookLL!=NULL,"failed to set hook\n"); } /* create test clases */ RegisterSimpleClass(TestProc, L"TestClass"); memset(&data[0], 0, sizeof(data[0])); data[0].tid = GetCurrentThreadId(); /* create test window */ data[0].hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, 0, NULL); if(!data[0].hWnd) { win_skip("CreateWindowW failed\n"); return FALSE; } /* create thread1(same desktop) */ if(!CreateTestThread(1, NULL)) return FALSE; /* create thread2(same desktop) */ if(!CreateTestThread(2, NULL)) return FALSE; /* ugly ros hack to bypass desktop crapiness */ if(!CreateTestThread(6, L"ThreadTestDesktop")) return FALSE; /* create thread3(different desktop) */ if(!CreateTestThread(3, L"ThreadTestDesktop")) return FALSE; /* create thread4(different desktop) */ if(!CreateTestThread(4, L"ThreadTestDesktop")) return FALSE; return TRUE; }
void CondVarMixedTest(void *_arg) { PRInt32 arg = (PRInt32)_arg; PRInt32 index, loops; threadinfo *list; PRLock *sharedlock; PRCondVar *sharedcvar; PRLock *exitlock; PRCondVar *exitcvar; PRInt32 *ptcount; exitcount=0; tcount=0; list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4)); sharedlock = PR_NewLock(); sharedcvar = PR_NewCondVar(sharedlock); exitlock = PR_NewLock(); exitcvar = PR_NewCondVar(exitlock); /* Create the threads */ for(index=0; index<arg*4; ) { CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_MillisecondsToInterval(50), &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_LOCAL_THREAD); index++; CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_MillisecondsToInterval(50), &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_GLOBAL_THREAD); index++; list[index].lock = PR_NewLock(); list[index].cvar = PR_NewCondVar(list[index].lock); CreateTestThread(&list[index], index, list[index].lock, list[index].cvar, count, PR_MillisecondsToInterval(50), ptcount, exitlock, exitcvar, &exitcount, PR_FALSE, PR_LOCAL_THREAD); index++; ptcount++; list[index].lock = PR_NewLock(); list[index].cvar = PR_NewCondVar(list[index].lock); CreateTestThread(&list[index], index, list[index].lock, list[index].cvar, count, PR_MillisecondsToInterval(50), ptcount, exitlock, exitcvar, &exitcount, PR_FALSE, PR_GLOBAL_THREAD); index++; ptcount++; } /* Notify every 3rd thread */ for (loops = 0; loops < count; loops++) { /* Notify the threads */ for(index=0; index<(arg*4); index+=3) { PR_Lock(list[index].lock); *list[index].tcount++; PR_NotifyCondVar(list[index].cvar); PR_Unlock(list[index].lock); } /* Wait for threads to finish */ PR_Lock(exitlock); while(exitcount < arg*4) PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60)); PR_ASSERT(exitcount >= arg*4); exitcount -= arg*4; PR_Unlock(exitlock); } /* Join all the threads */ for(index=0; index<(arg*4); index++) { PR_JoinThread(list[index].thread); if (list[index].internal) { PR_Lock(list[index].lock); PR_DestroyCondVar(list[index].cvar); PR_Unlock(list[index].lock); PR_DestroyLock(list[index].lock); } } PR_DestroyCondVar(sharedcvar); PR_DestroyLock(sharedlock); PR_DELETE(list); }
void CondVarTest(void *_arg) { PRInt32 arg = (PRInt32)_arg; PRInt32 index, loops; threadinfo *list; PRLock *sharedlock; PRCondVar *sharedcvar; PRLock *exitlock; PRCondVar *exitcvar; PRInt32 *ptcount, *saved_ptcount; exitcount=0; tcount=0; list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); saved_ptcount = ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4)); sharedlock = PR_NewLock(); sharedcvar = PR_NewCondVar(sharedlock); exitlock = PR_NewLock(); exitcvar = PR_NewCondVar(exitlock); /* Create the threads */ for(index=0; index<arg*4; ) { CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_INTERVAL_NO_TIMEOUT, &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_LOCAL_THREAD); index++; CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_INTERVAL_NO_TIMEOUT, &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_GLOBAL_THREAD); index++; list[index].lock = PR_NewLock(); list[index].cvar = PR_NewCondVar(list[index].lock); CreateTestThread(&list[index], index, list[index].lock, list[index].cvar, count, PR_INTERVAL_NO_TIMEOUT, ptcount, exitlock, exitcvar, &exitcount, PR_FALSE, PR_LOCAL_THREAD); index++; ptcount++; list[index].lock = PR_NewLock(); list[index].cvar = PR_NewCondVar(list[index].lock); CreateTestThread(&list[index], index, list[index].lock, list[index].cvar, count, PR_INTERVAL_NO_TIMEOUT, ptcount, exitlock, exitcvar, &exitcount, PR_FALSE, PR_GLOBAL_THREAD); index++; ptcount++; } for (loops = 0; loops < count; loops++) { /* Notify the threads */ for(index=0; index<(arg*4); index++) { PR_Lock(list[index].lock); (*list[index].tcount)++; PR_NotifyCondVar(list[index].cvar); PR_Unlock(list[index].lock); } #if 0 printf("wait for threads done\n"); #endif /* Wait for threads to finish */ PR_Lock(exitlock); while(exitcount < arg*4) PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60)); PR_ASSERT(exitcount >= arg*4); exitcount -= arg*4; PR_Unlock(exitlock); #if 0 printf("threads ready\n"); #endif } /* Join all the threads */ for(index=0; index<(arg*4); index++) { PR_JoinThread(list[index].thread); if (list[index].internal) { PR_Lock(list[index].lock); PR_DestroyCondVar(list[index].cvar); PR_Unlock(list[index].lock); PR_DestroyLock(list[index].lock); } } PR_DestroyCondVar(sharedcvar); PR_DestroyLock(sharedlock); PR_DestroyCondVar(exitcvar); PR_DestroyLock(exitlock); PR_DELETE(list); PR_DELETE(saved_ptcount); }
void CondVarTestPUU(void *_arg) { PRInt32 arg = (PRInt32)_arg; PRInt32 index, loops; threadinfo *list; PRLock *sharedlock; PRCondVar *sharedcvar; PRLock *exitlock; PRCondVar *exitcvar; PRInt32 *tcount, *saved_tcount; exitcount=0; list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4)); sharedlock = PR_NewLock(); sharedcvar = PR_NewCondVar(sharedlock); exitlock = PR_NewLock(); exitcvar = PR_NewCondVar(exitlock); /* Create the threads */ for(index=0; index<arg; ) { list[index].lock = PR_NewLock(); list[index].cvar = PR_NewCondVar(list[index].lock); CreateTestThread(&list[index], index, list[index].lock, list[index].cvar, count, PR_INTERVAL_NO_TIMEOUT, tcount, exitlock, exitcvar, &exitcount, PR_FALSE, PR_LOCAL_THREAD); DPRINTF(("CondVarTestPUU: created thread 0x%lx\n",list[index].thread)); index++; tcount++; } for (loops = 0; loops < count; loops++) { /* Notify the threads */ for(index=0; index<(arg); index++) { PR_Lock(list[index].lock); (*list[index].tcount)++; PR_NotifyCondVar(list[index].cvar); PR_Unlock(list[index].lock); } PR_Lock(exitlock); /* Wait for threads to finish */ while(exitcount < arg) { DPRINTF(("CondVarTestPUU: thread 0x%lx waiting on exitcvar = 0x%lx cnt = %ld\n", PR_GetCurrentThread(), exitcvar, exitcount)); PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60)); } PR_ASSERT(exitcount >= arg); exitcount -= arg; PR_Unlock(exitlock); } /* Join all the threads */ for(index=0; index<(arg); index++) { DPRINTF(("CondVarTestPUU: joining thread 0x%lx\n",list[index].thread)); PR_JoinThread(list[index].thread); if (list[index].internal) { PR_Lock(list[index].lock); PR_DestroyCondVar(list[index].cvar); PR_Unlock(list[index].lock); PR_DestroyLock(list[index].lock); } } PR_DestroyCondVar(sharedcvar); PR_DestroyLock(sharedlock); PR_DestroyCondVar(exitcvar); PR_DestroyLock(exitlock); PR_DELETE(list); PR_DELETE(saved_tcount); }
void CondVarTestSUU(void *_arg) { PRInt32 arg = (PRInt32)_arg; PRInt32 index, loops; threadinfo *list; PRLock *sharedlock; PRCondVar *sharedcvar; PRLock *exitlock; PRCondVar *exitcvar; exitcount=0; tcount=0; list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); sharedlock = PR_NewLock(); sharedcvar = PR_NewCondVar(sharedlock); exitlock = PR_NewLock(); exitcvar = PR_NewCondVar(exitlock); /* Create the threads */ for(index=0; index<arg; ) { CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_INTERVAL_NO_TIMEOUT, &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_LOCAL_THREAD); index++; DPRINTF(("CondVarTestSUU: created thread 0x%lx\n",list[index].thread)); } for (loops = 0; loops < count; loops++) { /* Notify the threads */ for(index=0; index<(arg); index++) { PR_Lock(list[index].lock); (*list[index].tcount)++; PR_NotifyCondVar(list[index].cvar); PR_Unlock(list[index].lock); DPRINTF(("PrivateCondVarThread: thread 0x%lx notified cvar = 0x%lx\n", PR_GetCurrentThread(), list[index].cvar)); } /* Wait for threads to finish */ PR_Lock(exitlock); while(exitcount < arg) PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60)); PR_ASSERT(exitcount >= arg); exitcount -= arg; PR_Unlock(exitlock); } /* Join all the threads */ for(index=0; index<(arg); index++) PR_JoinThread(list[index].thread); PR_DestroyCondVar(sharedcvar); PR_DestroyLock(sharedlock); PR_DestroyCondVar(exitcvar); PR_DestroyLock(exitlock); PR_DELETE(list); }
void Test_SimpleParameters() { BOOL ret; /* FIXME: acording to msdn xp doesn't set last error but vista+ does*/ /* test wrong thread */ ret = AttachThreadInput( 0, 1, TRUE); ok(ret==0, "expected AttachThreadInput to fail\n"); /* test same thread */ ret = AttachThreadInput( data[1].tid, data[1].tid, TRUE); ok(ret==0, "expected AttachThreadInput to fail\n"); /* try to attach to a thread on another desktop*/ ret = AttachThreadInput( data[2].tid,data[3].tid, TRUE); ok(ret==0, "expected AttachThreadInput to fail\n"); if(ret == 1 ) AttachThreadInput( data[2].tid,data[3].tid, FALSE); /* test other desktop to this */ ret = AttachThreadInput( data[3].tid,data[2].tid, TRUE); ok(ret==0, "expected AttachThreadInput to fail\n"); if(ret == 1 ) AttachThreadInput( data[3].tid,data[2].tid, FALSE); /* attach two threads that are both in ThreadTestDesktop */ { /* Attach thread 3 and 4 */ ret = AttachThreadInput( data[3].tid,data[4].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); /* cleanup previous attachment */ ret = AttachThreadInput( data[3].tid,data[4].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); } { /* Attach thread 1 and 2 */ ret = AttachThreadInput( data[1].tid,data[2].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); /* attach already attached*/ ret = AttachThreadInput( data[1].tid,data[2].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); /* attach in the opposite order */ ret = AttachThreadInput( data[2].tid,data[1].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); /* Now try to detach 0 from 1 */ ret = AttachThreadInput( data[0].tid,data[1].tid, FALSE); ok(ret==0, "expected AttachThreadInput to fail\n"); /* also try to detach 3 from 2 */ ret = AttachThreadInput( data[3].tid,data[2].tid, FALSE); ok(ret==0, "expected AttachThreadInput to fail\n"); /* cleanup previous attachment */ ret = AttachThreadInput( data[1].tid,data[2].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[2].tid,data[1].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[1].tid,data[2].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); } /* test triple attach */ { ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); /* try to detach 2 and 0 */ ret = AttachThreadInput( data[0].tid, data[2].tid, FALSE); ok(ret==0, "expected AttachThreadInput to fail\n"); ret = AttachThreadInput( data[2].tid, data[0].tid, FALSE); ok(ret==0, "expected AttachThreadInput to fail\n"); /* try to to attach 0 to 2. it works! */ ret = AttachThreadInput( data[0].tid, data[2].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[0].tid, data[2].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); /* detach in inverse order */ ret = AttachThreadInput( data[0].tid, data[1].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[1].tid, data[2].tid, FALSE); ok(ret==1, "expected AttachThreadInput to succeed\n"); } /* test detaching in thread cleanup */ { ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); TerminateThread(data[1].hThread, 0); ret = AttachThreadInput( data[0].tid, data[1].tid, FALSE); ok(ret==0, "expected AttachThreadInput to fail\n"); ret = AttachThreadInput( data[1].tid, data[2].tid, FALSE); ok(ret==0, "expected AttachThreadInput to fail\n"); /* Create Thread1 again */ CreateTestThread(1, NULL); } }