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 TRACE(win32
,"handle %i is %08x\n",i
,handles
[i
]);
35 if (!(*ptr
= HANDLE_GetObjPtr( PROCESS_Current(), handles
[i
],
36 K32OBJ_UNKNOWN
, SYNCHRONIZE
,
39 ERR(win32
, "Bad handle %08x\n", handles
[i
]);
42 if (wait
->server
[i
] == -1)
43 WARN(win32
,"No server handle for %08x (type %d)\n",
44 handles
[i
], (*ptr
)->type
);
49 /* There was an error */
50 while (i
--) K32OBJ_DecCount( wait
->objs
[i
] );
57 /***********************************************************************
60 static void SYNC_FreeWaitStruct( WAIT_STRUCT
*wait
)
65 for (i
= 0, ptr
= wait
->objs
; i
< wait
->count
; i
++, ptr
++)
66 K32OBJ_DecCount( *ptr
);
70 /***********************************************************************
71 * Sleep (KERNEL32.679)
73 VOID WINAPI
Sleep( DWORD timeout
)
75 WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, FALSE
);
78 /******************************************************************************
79 * SleepEx (KERNEL32.680)
81 DWORD WINAPI
SleepEx( DWORD timeout
, BOOL32 alertable
)
83 DWORD ret
= WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, alertable
);
84 if (ret
!= WAIT_IO_COMPLETION
) ret
= 0;
89 /***********************************************************************
90 * WaitForSingleObject (KERNEL32.723)
92 DWORD WINAPI
WaitForSingleObject( HANDLE32 handle
, DWORD timeout
)
94 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
98 /***********************************************************************
99 * WaitForSingleObjectEx (KERNEL32.724)
101 DWORD WINAPI
WaitForSingleObjectEx( HANDLE32 handle
, DWORD timeout
,
104 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
108 /***********************************************************************
109 * WaitForMultipleObjects (KERNEL32.721)
111 DWORD WINAPI
WaitForMultipleObjects( DWORD count
, const HANDLE32
*handles
,
112 BOOL32 wait_all
, DWORD timeout
)
114 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
118 /***********************************************************************
119 * WaitForMultipleObjectsEx (KERNEL32.722)
121 DWORD WINAPI
WaitForMultipleObjectsEx( DWORD count
, const HANDLE32
*handles
,
122 BOOL32 wait_all
, DWORD timeout
,
125 WAIT_STRUCT
*wait
= &THREAD_Current()->wait_struct
;
126 struct select_request req
;
127 struct select_reply reply
;
131 if (count
> MAXIMUM_WAIT_OBJECTS
)
133 SetLastError( ERROR_INVALID_PARAMETER
);
137 if (!SYNC_BuildWaitStruct( count
, handles
, wait_all
, wait
))
142 req
.timeout
= timeout
;
144 if (wait_all
) req
.flags
|= SELECT_ALL
;
145 if (alertable
) req
.flags
|= SELECT_ALERTABLE
;
146 if (timeout
!= INFINITE32
) req
.flags
|= SELECT_TIMEOUT
;
148 CLIENT_SendRequest( REQ_SELECT
, -1, 2,
150 wait
->server
, count
* sizeof(int) );
151 CLIENT_WaitReply( &len
, NULL
, 2, &reply
, sizeof(reply
),
153 if ((reply
.signaled
== STATUS_USER_APC
) && (len
> sizeof(reply
)))
156 len
-= sizeof(reply
);
157 for (i
= 0; i
< len
/ sizeof(void*); i
+= 2)
159 PAPCFUNC func
= (PAPCFUNC
)apc
[i
];
160 func( (ULONG_PTR
)apc
[i
+1] );
163 SYNC_FreeWaitStruct( wait
);
164 return reply
.signaled
;
168 /***********************************************************************
169 * WIN16_WaitForSingleObject (KERNEL.460)
171 DWORD WINAPI
WIN16_WaitForSingleObject( HANDLE32 handle
, DWORD timeout
)
175 SYSLEVEL_ReleaseWin16Lock();
176 retval
= WaitForSingleObject( handle
, timeout
);
177 SYSLEVEL_RestoreWin16Lock();
182 /***********************************************************************
183 * WIN16_WaitForMultipleObjects (KERNEL.461)
185 DWORD WINAPI
WIN16_WaitForMultipleObjects( DWORD count
, const HANDLE32
*handles
,
186 BOOL32 wait_all
, DWORD timeout
)
190 SYSLEVEL_ReleaseWin16Lock();
191 retval
= WaitForMultipleObjects( count
, handles
, wait_all
, timeout
);
192 SYSLEVEL_RestoreWin16Lock();
197 /***********************************************************************
198 * WIN16_WaitForMultipleObjectsEx (KERNEL.495)
200 DWORD WINAPI
WIN16_WaitForMultipleObjectsEx( DWORD count
,
201 const HANDLE32
*handles
,
202 BOOL32 wait_all
, DWORD timeout
,
207 SYSLEVEL_ReleaseWin16Lock();
208 retval
= WaitForMultipleObjectsEx( count
, handles
,
209 wait_all
, timeout
, alertable
);
210 SYSLEVEL_RestoreWin16Lock();