2 * Win32 process and thread synchronisation
4 * Copyright 1997 Alexandre Julliard
12 #include "file.h" /* for DOSFS_UnixTimeToFileTime */
19 /***********************************************************************
22 * Call outstanding APCs.
24 static void call_apcs(void)
35 struct get_apc_request
*req
= server_alloc_req( sizeof(*req
), sizeof(args
) );
36 if (!server_call( REQ_GET_APC
))
40 memcpy( args
, server_data_ptr(req
), server_data_size(req
) );
48 return; /* no more APCs */
53 /* convert sec/usec to NT time */
54 DOSFS_UnixTimeToFileTime( (time_t)args
[0], &ft
, (DWORD
)args
[1] * 10 );
55 proc( args
[2], ft
.dwLowDateTime
, ft
.dwHighDateTime
);
58 server_protocol_error( "get_apc_request: bad type %d\n", type
);
64 /***********************************************************************
65 * Sleep (KERNEL32.679)
67 VOID WINAPI
Sleep( DWORD timeout
)
69 WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, FALSE
);
72 /******************************************************************************
73 * SleepEx (KERNEL32.680)
75 DWORD WINAPI
SleepEx( DWORD timeout
, BOOL alertable
)
77 DWORD ret
= WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, alertable
);
78 if (ret
!= WAIT_IO_COMPLETION
) ret
= 0;
83 /***********************************************************************
84 * WaitForSingleObject (KERNEL32.723)
86 DWORD WINAPI
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
88 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
92 /***********************************************************************
93 * WaitForSingleObjectEx (KERNEL32.724)
95 DWORD WINAPI
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
,
98 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
102 /***********************************************************************
103 * WaitForMultipleObjects (KERNEL32.721)
105 DWORD WINAPI
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
106 BOOL wait_all
, DWORD timeout
)
108 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
112 /***********************************************************************
113 * WaitForMultipleObjectsEx (KERNEL32.722)
115 DWORD WINAPI
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
116 BOOL wait_all
, DWORD timeout
,
121 if (count
> MAXIMUM_WAIT_OBJECTS
)
123 SetLastError( ERROR_INVALID_PARAMETER
);
129 struct select_request
*req
= server_alloc_req( sizeof(*req
), count
* sizeof(int) );
130 int *data
= server_data_ptr( req
);
133 req
->timeout
= timeout
;
134 for (i
= 0; i
< count
; i
++) data
[i
] = handles
[i
];
136 if (wait_all
) req
->flags
|= SELECT_ALL
;
137 if (alertable
) req
->flags
|= SELECT_ALERTABLE
;
138 if (timeout
!= INFINITE
) req
->flags
|= SELECT_TIMEOUT
;
140 server_call( REQ_SELECT
);
144 if (ret
== STATUS_USER_APC
) call_apcs();
149 /***********************************************************************
150 * WIN16_WaitForSingleObject (KERNEL.460)
152 DWORD WINAPI
WIN16_WaitForSingleObject( HANDLE handle
, DWORD timeout
)
156 SYSLEVEL_ReleaseWin16Lock();
157 retval
= WaitForSingleObject( handle
, timeout
);
158 SYSLEVEL_RestoreWin16Lock();
163 /***********************************************************************
164 * WIN16_WaitForMultipleObjects (KERNEL.461)
166 DWORD WINAPI
WIN16_WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
167 BOOL wait_all
, DWORD timeout
)
171 SYSLEVEL_ReleaseWin16Lock();
172 retval
= WaitForMultipleObjects( count
, handles
, wait_all
, timeout
);
173 SYSLEVEL_RestoreWin16Lock();
178 /***********************************************************************
179 * WIN16_WaitForMultipleObjectsEx (KERNEL.495)
181 DWORD WINAPI
WIN16_WaitForMultipleObjectsEx( DWORD count
,
182 const HANDLE
*handles
,
183 BOOL wait_all
, DWORD timeout
,
188 SYSLEVEL_ReleaseWin16Lock();
189 retval
= WaitForMultipleObjectsEx( count
, handles
,
190 wait_all
, timeout
, alertable
);
191 SYSLEVEL_RestoreWin16Lock();