/* * Synchronization tests * * Copyright 2005 Mike McCormack for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include "wine/test.h" static void test_signalandwait(void) { DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL); HMODULE kernel32; DWORD r; int i; HANDLE event[2], maxevents[MAXIMUM_WAIT_OBJECTS], semaphore[2], file; kernel32 = GetModuleHandle("kernel32"); pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait"); if (!pSignalObjectAndWait) return; /* invalid parameters */ r = pSignalObjectAndWait(NULL, NULL, 0, 0); if (r == ERROR_INVALID_FUNCTION) { trace("SignalObjectAndWait not implemented, skipping tests\n"); return; /* Win98/ME */ } ok( r == WAIT_FAILED, "should fail\n"); event[0] = CreateEvent(NULL, 0, 0, NULL); event[1] = CreateEvent(NULL, 1, 1, NULL); ok( event[0] && event[1], "failed to create event flags\n"); r = pSignalObjectAndWait(event[0], NULL, 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); r = pSignalObjectAndWait(NULL, event[0], 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); /* valid parameters */ r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); ok( r == WAIT_OBJECT_0, "should succeed\n"); /* event[0] is now signalled */ r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); ok( r == WAIT_OBJECT_0, "should succeed\n"); /* event[0] is not signalled */ r = WaitForSingleObject(event[0], 0); ok( r == WAIT_TIMEOUT, "event was signalled\n"); r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); ok( r == WAIT_OBJECT_0, "should succeed\n"); /* clear event[1] and check for a timeout */ ok(ResetEvent(event[1]), "failed to clear event[1]\n"); r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); ok( r == WAIT_TIMEOUT, "should timeout\n"); CloseHandle(event[0]); CloseHandle(event[1]); /* create the maximum number of events and make sure * we can wait on that many */ for (i=0; ivalue == 1, "previous entry in slist wasn't the one added\n"); } size = pQueryDepthSList(&slist_header); ok(size == 2, "slist with 2 items has size %d\n", size); item3.value = 3; entry = pInterlockedPushEntrySList(&slist_header, &item3.entry); ok(entry != NULL, "previous entry in non-empty slist was NULL\n"); if (entry != NULL) { pitem = (struct item*) entry; ok(pitem->value == 2, "previous entry in slist wasn't the one added\n"); } size = pQueryDepthSList(&slist_header); ok(size == 3, "slist with 3 items has size %d\n", size); entry = pInterlockedPopEntrySList(&slist_header); ok(entry != NULL, "entry shouldn't be NULL\n"); if (entry != NULL) { pitem = (struct item*) entry; ok(pitem->value == 3, "unexpected entry removed\n"); } size = pQueryDepthSList(&slist_header); ok(size == 2, "slist with 2 items has size %d\n", size); entry = pInterlockedFlushSList(&slist_header); size = pQueryDepthSList(&slist_header); ok(size == 0, "flushed slist should be empty, size is %d\n", size); if (size == 0) { ok(pInterlockedPopEntrySList(&slist_header) == NULL, "popping empty slist didn't return NULL\n"); } ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n"); ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n"); } START_TEST(sync) { test_signalandwait(); test_mutex(); test_slist(); }