2 * Synchronization tests
4 * Copyright 2005 Mike McCormack for CodeWeavers
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.
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.
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
27 #include "wine/test.h"
29 static void test_signalandwait(void)
31 DWORD (WINAPI
*pSignalObjectAndWait
)(HANDLE
, HANDLE
, DWORD
, BOOL
);
35 HANDLE event
[2], maxevents
[MAXIMUM_WAIT_OBJECTS
], semaphore
[2], file
;
37 kernel32
= GetModuleHandle("kernel32");
38 pSignalObjectAndWait
= (void*) GetProcAddress(kernel32
, "SignalObjectAndWait");
40 if (!pSignalObjectAndWait
)
43 /* invalid parameters */
44 r
= pSignalObjectAndWait(NULL
, NULL
, 0, 0);
45 if (r
== ERROR_INVALID_FUNCTION
)
47 trace("SignalObjectAndWait not implemented, skipping tests\n");
48 return; /* Win98/ME */
50 ok( r
== WAIT_FAILED
, "should fail\n");
52 event
[0] = CreateEvent(NULL
, 0, 0, NULL
);
53 event
[1] = CreateEvent(NULL
, 1, 1, NULL
);
55 ok( event
[0] && event
[1], "failed to create event flags\n");
57 r
= pSignalObjectAndWait(event
[0], NULL
, 0, FALSE
);
58 ok( r
== WAIT_FAILED
, "should fail\n");
60 r
= pSignalObjectAndWait(NULL
, event
[0], 0, FALSE
);
61 ok( r
== WAIT_FAILED
, "should fail\n");
64 /* valid parameters */
65 r
= pSignalObjectAndWait(event
[0], event
[1], 0, FALSE
);
66 ok( r
== WAIT_OBJECT_0
, "should succeed\n");
68 /* event[0] is now signalled */
69 r
= pSignalObjectAndWait(event
[0], event
[0], 0, FALSE
);
70 ok( r
== WAIT_OBJECT_0
, "should succeed\n");
72 /* event[0] is not signalled */
73 r
= WaitForSingleObject(event
[0], 0);
74 ok( r
== WAIT_TIMEOUT
, "event was signalled\n");
76 r
= pSignalObjectAndWait(event
[0], event
[0], 0, FALSE
);
77 ok( r
== WAIT_OBJECT_0
, "should succeed\n");
79 /* clear event[1] and check for a timeout */
80 ok(ResetEvent(event
[1]), "failed to clear event[1]\n");
81 r
= pSignalObjectAndWait(event
[0], event
[1], 0, FALSE
);
82 ok( r
== WAIT_TIMEOUT
, "should timeout\n");
84 CloseHandle(event
[0]);
85 CloseHandle(event
[1]);
87 /* create the maximum number of events and make sure
88 * we can wait on that many */
89 for (i
=0; i
<MAXIMUM_WAIT_OBJECTS
; i
++)
91 maxevents
[i
] = CreateEvent(NULL
, 1, 1, NULL
);
92 ok( maxevents
[i
] != 0, "should create enough events\n");
94 r
= WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS
, maxevents
, 0, 0);
95 ok( r
!= WAIT_FAILED
&& r
!= WAIT_TIMEOUT
, "should succeed\n");
97 for (i
=0; i
<MAXIMUM_WAIT_OBJECTS
; i
++)
98 if (maxevents
[i
]) CloseHandle(maxevents
[i
]);
101 semaphore
[0] = CreateSemaphore( NULL
, 0, 1, NULL
);
102 semaphore
[1] = CreateSemaphore( NULL
, 1, 1, NULL
);
103 ok( semaphore
[0] && semaphore
[1], "failed to create semaphore\n");
105 r
= pSignalObjectAndWait(semaphore
[0], semaphore
[1], 0, FALSE
);
106 ok( r
== WAIT_OBJECT_0
, "should succeed\n");
108 r
= pSignalObjectAndWait(semaphore
[0], semaphore
[1], 0, FALSE
);
109 ok( r
== WAIT_FAILED
, "should fail\n");
111 r
= ReleaseSemaphore(semaphore
[0],1,NULL
);
112 ok( r
== FALSE
, "should fail\n");
114 r
= ReleaseSemaphore(semaphore
[1],1,NULL
);
115 ok( r
== TRUE
, "should succeed\n");
117 CloseHandle(semaphore
[0]);
118 CloseHandle(semaphore
[1]);
120 /* try a registry key */
121 file
= CreateFile("x", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
122 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_DELETE_ON_CLOSE
, NULL
);
123 r
= pSignalObjectAndWait(file
, file
, 0, FALSE
);
124 ok( r
== WAIT_FAILED
, "should fail\n");
125 ok( ERROR_INVALID_HANDLE
== GetLastError(), "should return invalid handle error\n");
129 static void test_mutex(void)
136 hCreated
= CreateMutex(NULL
, FALSE
, "WineTestMutex");
137 ok(hCreated
!= NULL
, "CreateMutex failed with error %ld\n", GetLastError());
138 wait_ret
= WaitForSingleObject(hCreated
, INFINITE
);
139 ok(wait_ret
== WAIT_OBJECT_0
, "WaitForSingleObject failed with error 0x%08lx\n", wait_ret
);
141 /* yes, opening with just READ_CONTROL access allows us to successfully
142 * call ReleaseMutex */
143 hOpened
= OpenMutex(READ_CONTROL
, FALSE
, "WineTestMutex");
144 ok(hOpened
!= NULL
, "OpenMutex failed with error %ld\n", GetLastError());
145 ret
= ReleaseMutex(hOpened
);
146 todo_wine
ok(ret
, "ReleaseMutex failed with error %ld\n", GetLastError());
147 ret
= ReleaseMutex(hCreated
);
148 todo_wine
ok(!ret
&& (GetLastError() == ERROR_NOT_OWNER
),
149 "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %ld\n", GetLastError());
151 CloseHandle(hOpened
);
152 CloseHandle(hCreated
);
157 test_signalandwait();