2 * Win32 process and thread synchronisation
4 * Copyright 1997 Alexandre Julliard
12 #include "file.h" /* for DOSFS_UnixTimeToFileTime */
18 /***********************************************************************
21 inline static void get_timeout( struct timeval
*when
, int timeout
)
23 gettimeofday( when
, 0 );
26 long sec
= timeout
/ 1000;
27 if ((when
->tv_usec
+= (timeout
- 1000*sec
) * 1000) >= 1000000)
29 when
->tv_usec
-= 1000000;
37 /***********************************************************************
40 * Call outstanding APCs.
42 static void call_apcs( BOOL alertable
)
53 struct get_apc_request
*req
= server_alloc_req( sizeof(*req
), sizeof(args
) );
54 req
->alertable
= alertable
;
55 if (!server_call( REQ_GET_APC
))
59 memcpy( args
, server_data_ptr(req
), server_data_size(req
) );
67 return; /* no more APCs */
75 /* convert sec/usec to NT time */
76 DOSFS_UnixTimeToFileTime( (time_t)args
[0], &ft
, (DWORD
)args
[1] * 10 );
77 proc( args
[2], ft
.dwLowDateTime
, ft
.dwHighDateTime
);
80 server_protocol_error( "get_apc_request: bad type %d\n", type
);
86 /***********************************************************************
87 * Sleep (KERNEL32.679)
89 VOID WINAPI
Sleep( DWORD timeout
)
91 WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, FALSE
);
94 /******************************************************************************
95 * SleepEx (KERNEL32.680)
97 DWORD WINAPI
SleepEx( DWORD timeout
, BOOL alertable
)
99 DWORD ret
= WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, alertable
);
100 if (ret
!= WAIT_IO_COMPLETION
) ret
= 0;
105 /***********************************************************************
106 * WaitForSingleObject (KERNEL32.723)
108 DWORD WINAPI
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
110 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
114 /***********************************************************************
115 * WaitForSingleObjectEx (KERNEL32.724)
117 DWORD WINAPI
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
,
120 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
124 /***********************************************************************
125 * WaitForMultipleObjects (KERNEL32.721)
127 DWORD WINAPI
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
128 BOOL wait_all
, DWORD timeout
)
130 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
134 /***********************************************************************
135 * WaitForMultipleObjectsEx (KERNEL32.722)
137 DWORD WINAPI
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
138 BOOL wait_all
, DWORD timeout
,
144 if (count
> MAXIMUM_WAIT_OBJECTS
)
146 SetLastError( ERROR_INVALID_PARAMETER
);
150 if (timeout
== INFINITE
) tv
.tv_sec
= tv
.tv_usec
= 0;
151 else get_timeout( &tv
, timeout
);
157 struct select_request
*req
= server_alloc_req( sizeof(*req
), count
* sizeof(int) );
158 int *data
= server_data_ptr( req
);
160 req
->flags
= SELECT_INTERRUPTIBLE
;
161 req
->sec
= tv
.tv_sec
;
162 req
->usec
= tv
.tv_usec
;
163 for (i
= 0; i
< count
; i
++) data
[i
] = handles
[i
];
165 if (wait_all
) req
->flags
|= SELECT_ALL
;
166 if (alertable
) req
->flags
|= SELECT_ALERTABLE
;
167 if (timeout
!= INFINITE
) req
->flags
|= SELECT_TIMEOUT
;
169 server_call( REQ_SELECT
);
173 if (ret
!= STATUS_USER_APC
) break;
174 call_apcs( alertable
);
175 if (alertable
) break;
181 /***********************************************************************
182 * WIN16_WaitForSingleObject (KERNEL.460)
184 DWORD WINAPI
WIN16_WaitForSingleObject( HANDLE handle
, DWORD timeout
)
186 DWORD retval
, mutex_count
;
188 ReleaseThunkLock( &mutex_count
);
189 retval
= WaitForSingleObject( handle
, timeout
);
190 RestoreThunkLock( mutex_count
);
194 /***********************************************************************
195 * WIN16_WaitForMultipleObjects (KERNEL.461)
197 DWORD WINAPI
WIN16_WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
198 BOOL wait_all
, DWORD timeout
)
200 DWORD retval
, mutex_count
;
202 ReleaseThunkLock( &mutex_count
);
203 retval
= WaitForMultipleObjects( count
, handles
, wait_all
, timeout
);
204 RestoreThunkLock( mutex_count
);
208 /***********************************************************************
209 * WIN16_WaitForMultipleObjectsEx (KERNEL.495)
211 DWORD WINAPI
WIN16_WaitForMultipleObjectsEx( DWORD count
,
212 const HANDLE
*handles
,
213 BOOL wait_all
, DWORD timeout
,
216 DWORD retval
, mutex_count
;
218 ReleaseThunkLock( &mutex_count
);
219 retval
= WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, alertable
);
220 RestoreThunkLock( mutex_count
);