2 * Win32 process and thread synchronisation
4 * Copyright 1997 Alexandre Julliard
20 /***********************************************************************
23 * Call outstanding APCs.
25 static void call_apcs(void)
29 void *buffer
[MAX_APCS
* 2];
30 struct get_apcs_request
*req
= get_req_buffer();
32 if (server_call( REQ_GET_APCS
) || !req
->count
) return;
33 assert( req
->count
<= MAX_APCS
);
34 memcpy( buffer
, req
->apcs
, req
->count
* 2 * sizeof(req
->apcs
[0]) );
35 for (i
= 0; i
< req
->count
* 2; i
+= 2)
37 PAPCFUNC func
= (PAPCFUNC
)req
->apcs
[i
];
38 if (func
) func( (ULONG_PTR
)req
->apcs
[i
+1] );
42 /***********************************************************************
43 * Sleep (KERNEL32.679)
45 VOID WINAPI
Sleep( DWORD timeout
)
47 WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, FALSE
);
50 /******************************************************************************
51 * SleepEx (KERNEL32.680)
53 DWORD WINAPI
SleepEx( DWORD timeout
, BOOL alertable
)
55 DWORD ret
= WaitForMultipleObjectsEx( 0, NULL
, FALSE
, timeout
, alertable
);
56 if (ret
!= WAIT_IO_COMPLETION
) ret
= 0;
61 /***********************************************************************
62 * WaitForSingleObject (KERNEL32.723)
64 DWORD WINAPI
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
66 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
70 /***********************************************************************
71 * WaitForSingleObjectEx (KERNEL32.724)
73 DWORD WINAPI
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
,
76 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
80 /***********************************************************************
81 * WaitForMultipleObjects (KERNEL32.721)
83 DWORD WINAPI
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
84 BOOL wait_all
, DWORD timeout
)
86 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
90 /***********************************************************************
91 * WaitForMultipleObjectsEx (KERNEL32.722)
93 DWORD WINAPI
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
94 BOOL wait_all
, DWORD timeout
,
97 struct select_request
*req
= get_req_buffer();
100 if (count
> MAXIMUM_WAIT_OBJECTS
)
102 SetLastError( ERROR_INVALID_PARAMETER
);
106 /* FIXME: This is extremely ugly, but needed to avoid endless
107 * recursion due to EVENT_Synchronize itself using
108 * EnterCriticalSection( &X11DRV_CritSection ) ...
110 if ( count
== 0 || handles
[0] != X11DRV_CritSection
.LockSemaphore
)
112 /* Before we might possibly block, we need to push outstanding
113 * graphics output to the X server ... This needs to be done
114 * here so that it also works with native USER.
117 EVENT_Synchronize( FALSE
);
122 req
->timeout
= timeout
;
123 for (i
= 0; i
< count
; i
++) req
->handles
[i
] = handles
[i
];
125 if (wait_all
) req
->flags
|= SELECT_ALL
;
126 if (alertable
) req
->flags
|= SELECT_ALERTABLE
;
127 if (timeout
!= INFINITE
) req
->flags
|= SELECT_TIMEOUT
;
129 server_call( REQ_SELECT
);
130 if ((ret
= req
->signaled
) == STATUS_USER_APC
) call_apcs();
135 /***********************************************************************
136 * WIN16_WaitForSingleObject (KERNEL.460)
138 DWORD WINAPI
WIN16_WaitForSingleObject( HANDLE handle
, DWORD timeout
)
142 SYSLEVEL_ReleaseWin16Lock();
143 retval
= WaitForSingleObject( handle
, timeout
);
144 SYSLEVEL_RestoreWin16Lock();
149 /***********************************************************************
150 * WIN16_WaitForMultipleObjects (KERNEL.461)
152 DWORD WINAPI
WIN16_WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
153 BOOL wait_all
, DWORD timeout
)
157 SYSLEVEL_ReleaseWin16Lock();
158 retval
= WaitForMultipleObjects( count
, handles
, wait_all
, timeout
);
159 SYSLEVEL_RestoreWin16Lock();
164 /***********************************************************************
165 * WIN16_WaitForMultipleObjectsEx (KERNEL.495)
167 DWORD WINAPI
WIN16_WaitForMultipleObjectsEx( DWORD count
,
168 const HANDLE
*handles
,
169 BOOL wait_all
, DWORD timeout
,
174 SYSLEVEL_ReleaseWin16Lock();
175 retval
= WaitForMultipleObjectsEx( count
, handles
,
176 wait_all
, timeout
, alertable
);
177 SYSLEVEL_RestoreWin16Lock();