Re-implemented using a real semaphore.
[wine/multimedia.git] / scheduler / synchro.c
blobf2f4560085142ebb46446ea9522a8ccc027b1935
1 /*
2 * Win32 process and thread synchronisation
4 * Copyright 1997 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <signal.h>
9 #include <sys/time.h>
10 #include <unistd.h>
11 #include "k32obj.h"
12 #include "heap.h"
13 #include "process.h"
14 #include "thread.h"
15 #include "winerror.h"
16 #include "syslevel.h"
17 #include "server.h"
18 #include "debug.h"
20 /***********************************************************************
21 * SYNC_BuildWaitStruct
23 static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
24 BOOL32 wait_all, BOOL32 wait_msg,
25 WAIT_STRUCT *wait )
27 DWORD i;
28 K32OBJ **ptr;
30 SYSTEM_LOCK();
31 wait->count = count;
32 wait->signaled = WAIT_FAILED;
33 wait->wait_all = wait_all;
34 wait->wait_msg = wait_msg;
35 for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
37 if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
38 K32OBJ_UNKNOWN, SYNCHRONIZE,
39 &wait->server[i] )))
41 ERR(win32, "Bad handle %08x\n", handles[i]);
42 break;
44 if (wait->server[i] == -1)
45 WARN(win32,"No server handle for %08x (type %d)\n",
46 handles[i], (*ptr)->type );
49 if (i != count)
51 /* There was an error */
52 wait->wait_msg = FALSE;
53 while (i--) K32OBJ_DecCount( wait->objs[i] );
55 SYSTEM_UNLOCK();
56 return (i == count);
60 /***********************************************************************
61 * SYNC_FreeWaitStruct
63 static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
65 DWORD i;
66 K32OBJ **ptr;
67 SYSTEM_LOCK();
68 wait->wait_msg = FALSE;
69 for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
70 K32OBJ_DecCount( *ptr );
71 SYSTEM_UNLOCK();
75 /***********************************************************************
76 * SYNC_DoWait
78 DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
79 BOOL32 wait_all, DWORD timeout,
80 BOOL32 alertable, BOOL32 wait_msg )
82 WAIT_STRUCT *wait = &THREAD_Current()->wait_struct;
84 if (count > MAXIMUM_WAIT_OBJECTS)
86 SetLastError( ERROR_INVALID_PARAMETER );
87 return WAIT_FAILED;
90 if (alertable)
91 FIXME(win32, "alertable not implemented\n" );
93 if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait_msg, wait ))
94 wait->signaled = WAIT_FAILED;
95 else
97 int flags = 0;
98 if (wait_all) flags |= SELECT_ALL;
99 if (alertable) flags |= SELECT_ALERTABLE;
100 if (wait_msg) flags |= SELECT_MSG;
101 if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
102 wait->signaled = CLIENT_Select( count, wait->server, flags, timeout );
103 SYNC_FreeWaitStruct( wait );
105 return wait->signaled;
108 /***********************************************************************
109 * Sleep (KERNEL32.679)
111 VOID WINAPI Sleep( DWORD timeout )
113 SYNC_DoWait( 0, NULL, FALSE, timeout, FALSE, FALSE );
116 /******************************************************************************
117 * SleepEx (KERNEL32.680)
119 DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
121 DWORD ret = SYNC_DoWait( 0, NULL, FALSE, timeout, alertable, FALSE );
122 if (ret != WAIT_IO_COMPLETION) ret = 0;
123 return ret;
127 /***********************************************************************
128 * WaitForSingleObject (KERNEL32.723)
130 DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
132 return SYNC_DoWait( 1, &handle, FALSE, timeout, FALSE, FALSE );
136 /***********************************************************************
137 * WaitForSingleObjectEx (KERNEL32.724)
139 DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout,
140 BOOL32 alertable )
142 return SYNC_DoWait( 1, &handle, FALSE, timeout, alertable, FALSE );
146 /***********************************************************************
147 * WaitForMultipleObjects (KERNEL32.721)
149 DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
150 BOOL32 wait_all, DWORD timeout )
152 return SYNC_DoWait( count, handles, wait_all, timeout, FALSE, FALSE );
156 /***********************************************************************
157 * WaitForMultipleObjectsEx (KERNEL32.722)
159 DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE32 *handles,
160 BOOL32 wait_all, DWORD timeout,
161 BOOL32 alertable )
163 return SYNC_DoWait( count, handles, wait_all, timeout, alertable, FALSE );
167 /***********************************************************************
168 * WIN16_WaitForSingleObject (KERNEL.460)
170 DWORD WINAPI WIN16_WaitForSingleObject( HANDLE32 handle, DWORD timeout )
172 DWORD retval;
174 SYSLEVEL_ReleaseWin16Lock();
175 retval = WaitForSingleObject( handle, timeout );
176 SYSLEVEL_RestoreWin16Lock();
178 return retval;
181 /***********************************************************************
182 * WIN16_WaitForMultipleObjects (KERNEL.461)
184 DWORD WINAPI WIN16_WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
185 BOOL32 wait_all, DWORD timeout )
187 DWORD retval;
189 SYSLEVEL_ReleaseWin16Lock();
190 retval = WaitForMultipleObjects( count, handles, wait_all, timeout );
191 SYSLEVEL_RestoreWin16Lock();
193 return retval;