2 * Win32 process and thread synchronisation
4 * Copyright 1997 Alexandre Julliard
20 /***********************************************************************
21 * SYNC_BuildWaitStruct
23 static BOOL32
SYNC_BuildWaitStruct( DWORD count
, const HANDLE32
*handles
,
24 BOOL32 wait_all
, WAIT_STRUCT
*wait
)
31 wait
->wait_all
= wait_all
;
32 for (i
= 0, ptr
= wait
->objs
; i
< count
; i
++, ptr
++)
34 if (!(*ptr
= HANDLE_GetObjPtr( PROCESS_Current(), handles
[i
],
35 K32OBJ_UNKNOWN
, SYNCHRONIZE
,
38 ERR(win32
, "Bad handle %08x\n", handles
[i
]);
41 if (wait
->server
[i
] == -1)
42 WARN(win32
,"No server handle for %08x (type %d)\n",
43 handles
[i
], (*ptr
)->type
);
48 /* There was an error */
49 while (i
--) K32OBJ_DecCount( wait
->objs
[i
] );
56 /***********************************************************************
59 static void SYNC_FreeWaitStruct( WAIT_STRUCT
*wait
)
64 for (i
= 0, ptr
= wait
->objs
; i
< wait
->count
; i
++, ptr
++)
65 K32OBJ_DecCount( *ptr
);
69 /***********************************************************************
70 * Sleep (KERNEL32.679)
72 VOID WINAPI
Sleep( DWORD timeout
)
74 WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, FALSE
);
77 /******************************************************************************
78 * SleepEx (KERNEL32.680)
80 DWORD WINAPI
SleepEx( DWORD timeout
, BOOL32 alertable
)
82 DWORD ret
= WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, alertable
);
83 if (ret
!= WAIT_IO_COMPLETION
) ret
= 0;
88 /***********************************************************************
89 * WaitForSingleObject (KERNEL32.723)
91 DWORD WINAPI
WaitForSingleObject( HANDLE32 handle
, DWORD timeout
)
93 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
97 /***********************************************************************
98 * WaitForSingleObjectEx (KERNEL32.724)
100 DWORD WINAPI
WaitForSingleObjectEx( HANDLE32 handle
, DWORD timeout
,
103 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
107 /***********************************************************************
108 * WaitForMultipleObjects (KERNEL32.721)
110 DWORD WINAPI
WaitForMultipleObjects( DWORD count
, const HANDLE32
*handles
,
111 BOOL32 wait_all
, DWORD timeout
)
113 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
117 /***********************************************************************
118 * WaitForMultipleObjectsEx (KERNEL32.722)
120 DWORD WINAPI
WaitForMultipleObjectsEx( DWORD count
, const HANDLE32
*handles
,
121 BOOL32 wait_all
, DWORD timeout
,
124 WAIT_STRUCT
*wait
= &THREAD_Current()->wait_struct
;
125 struct select_request req
;
126 struct select_reply reply
;
130 if (count
> MAXIMUM_WAIT_OBJECTS
)
132 SetLastError( ERROR_INVALID_PARAMETER
);
136 if (!SYNC_BuildWaitStruct( count
, handles
, wait_all
, wait
))
141 req
.timeout
= timeout
;
143 if (wait_all
) req
.flags
|= SELECT_ALL
;
144 if (alertable
) req
.flags
|= SELECT_ALERTABLE
;
145 if (timeout
!= INFINITE32
) req
.flags
|= SELECT_TIMEOUT
;
147 CLIENT_SendRequest( REQ_SELECT
, -1, 2,
149 wait
->server
, count
* sizeof(int) );
150 CLIENT_WaitReply( &len
, NULL
, 2, &reply
, sizeof(reply
),
152 if ((reply
.signaled
== STATUS_USER_APC
) && (len
> sizeof(reply
)))
155 len
-= sizeof(reply
);
156 for (i
= 0; i
< len
/ sizeof(void*); i
+= 2)
158 PAPCFUNC func
= (PAPCFUNC
)apc
[i
];
159 func( (ULONG_PTR
)apc
[i
+1] );
162 SYNC_FreeWaitStruct( wait
);
163 return reply
.signaled
;
167 /***********************************************************************
168 * WIN16_WaitForSingleObject (KERNEL.460)
170 DWORD WINAPI
WIN16_WaitForSingleObject( HANDLE32 handle
, DWORD timeout
)
174 SYSLEVEL_ReleaseWin16Lock();
175 retval
= WaitForSingleObject( handle
, timeout
);
176 SYSLEVEL_RestoreWin16Lock();
181 /***********************************************************************
182 * WIN16_WaitForMultipleObjects (KERNEL.461)
184 DWORD WINAPI
WIN16_WaitForMultipleObjects( DWORD count
, const HANDLE32
*handles
,
185 BOOL32 wait_all
, DWORD timeout
)
189 SYSLEVEL_ReleaseWin16Lock();
190 retval
= WaitForMultipleObjects( count
, handles
, wait_all
, timeout
);
191 SYSLEVEL_RestoreWin16Lock();
196 /***********************************************************************
197 * WIN16_WaitForMultipleObjectsEx (KERNEL.495)
199 DWORD WINAPI
WIN16_WaitForMultipleObjectsEx( DWORD count
,
200 const HANDLE32
*handles
,
201 BOOL32 wait_all
, DWORD timeout
,
206 SYSLEVEL_ReleaseWin16Lock();
207 retval
= WaitForMultipleObjectsEx( count
, handles
,
208 wait_all
, timeout
, alertable
);
209 SYSLEVEL_RestoreWin16Lock();