Cleaned up debug channels a bit.
[wine] / scheduler / synchro.c
1 /*
2  * Win32 process and thread synchronisation
3  *
4  * Copyright 1997 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <signal.h>
9 #include <sys/time.h>
10 #include <unistd.h>
11 #include "heap.h"
12 #include "process.h"
13 #include "thread.h"
14 #include "winerror.h"
15 #include "syslevel.h"
16 #include "message.h"
17 #include "x11drv.h"
18 #include "server.h"
19
20 /***********************************************************************
21  *              call_apcs
22  *
23  * Call outstanding APCs.
24  */
25 static void call_apcs(void)
26 {
27 #define MAX_APCS 16
28     int i;
29     void *buffer[MAX_APCS * 2];
30     struct get_apcs_request *req = get_req_buffer();
31
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)
36     {
37         PAPCFUNC func = (PAPCFUNC)req->apcs[i];
38         if (func) func( (ULONG_PTR)req->apcs[i+1] );
39     }
40 }
41
42 /***********************************************************************
43  *              Sleep  (KERNEL32.679)
44  */
45 VOID WINAPI Sleep( DWORD timeout )
46 {
47     WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, FALSE );
48 }
49
50 /******************************************************************************
51  *              SleepEx   (KERNEL32.680)
52  */
53 DWORD WINAPI SleepEx( DWORD timeout, BOOL alertable )
54 {
55     DWORD ret = WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, alertable );
56     if (ret != WAIT_IO_COMPLETION) ret = 0;
57     return ret;
58 }
59
60
61 /***********************************************************************
62  *           WaitForSingleObject   (KERNEL32.723)
63  */
64 DWORD WINAPI WaitForSingleObject( HANDLE handle, DWORD timeout )
65 {
66     return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, FALSE );
67 }
68
69
70 /***********************************************************************
71  *           WaitForSingleObjectEx   (KERNEL32.724)
72  */
73 DWORD WINAPI WaitForSingleObjectEx( HANDLE handle, DWORD timeout,
74                                     BOOL alertable )
75 {
76     return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, alertable );
77 }
78
79
80 /***********************************************************************
81  *           WaitForMultipleObjects   (KERNEL32.721)
82  */
83 DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles,
84                                      BOOL wait_all, DWORD timeout )
85 {
86     return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE );
87 }
88
89
90 /***********************************************************************
91  *           WaitForMultipleObjectsEx   (KERNEL32.722)
92  */
93 DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
94                                        BOOL wait_all, DWORD timeout,
95                                        BOOL alertable )
96 {
97     struct select_request *req = get_req_buffer();
98     int i, ret;
99
100     if (count > MAXIMUM_WAIT_OBJECTS)
101     {
102         SetLastError( ERROR_INVALID_PARAMETER );
103         return WAIT_FAILED;
104     }
105
106     req->count   = count;
107     req->flags   = 0;
108     req->timeout = timeout;
109     for (i = 0; i < count; i++) req->handles[i] = handles[i];
110
111     if (wait_all) req->flags |= SELECT_ALL;
112     if (alertable) req->flags |= SELECT_ALERTABLE;
113     if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT;
114
115     server_call( REQ_SELECT );
116     if ((ret = req->signaled) == STATUS_USER_APC) call_apcs();
117     return ret;
118 }
119
120
121 /***********************************************************************
122  *           WIN16_WaitForSingleObject   (KERNEL.460)
123  */
124 DWORD WINAPI WIN16_WaitForSingleObject( HANDLE handle, DWORD timeout )
125 {
126     DWORD retval;
127
128     SYSLEVEL_ReleaseWin16Lock();
129     retval = WaitForSingleObject( handle, timeout );
130     SYSLEVEL_RestoreWin16Lock();
131
132     return retval;
133 }
134
135 /***********************************************************************
136  *           WIN16_WaitForMultipleObjects   (KERNEL.461)
137  */
138 DWORD WINAPI WIN16_WaitForMultipleObjects( DWORD count, const HANDLE *handles,
139                                            BOOL wait_all, DWORD timeout )
140 {
141     DWORD retval;
142
143     SYSLEVEL_ReleaseWin16Lock();
144     retval = WaitForMultipleObjects( count, handles, wait_all, timeout );
145     SYSLEVEL_RestoreWin16Lock();
146
147     return retval;
148 }
149
150 /***********************************************************************
151  *           WIN16_WaitForMultipleObjectsEx   (KERNEL.495)
152  */
153 DWORD WINAPI WIN16_WaitForMultipleObjectsEx( DWORD count, 
154                                              const HANDLE *handles,
155                                              BOOL wait_all, DWORD timeout,
156                                              BOOL alertable )
157 {
158     DWORD retval;
159
160     SYSLEVEL_ReleaseWin16Lock();
161     retval = WaitForMultipleObjectsEx( count, handles, 
162                                        wait_all, timeout, alertable );
163     SYSLEVEL_RestoreWin16Lock();
164
165     return retval;
166 }
167