Use the normal environment routines to build the env db of the initial
[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 /***********************************************************************
22  *              Sleep  (KERNEL32.679)
23  */
24 VOID WINAPI Sleep( DWORD timeout )
25 {
26     WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, FALSE );
27 }
28
29 /******************************************************************************
30  *              SleepEx   (KERNEL32.680)
31  */
32 DWORD WINAPI SleepEx( DWORD timeout, BOOL alertable )
33 {
34     DWORD ret = WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, alertable );
35     if (ret != WAIT_IO_COMPLETION) ret = 0;
36     return ret;
37 }
38
39
40 /***********************************************************************
41  *           WaitForSingleObject   (KERNEL32.723)
42  */
43 DWORD WINAPI WaitForSingleObject( HANDLE handle, DWORD timeout )
44 {
45     return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, FALSE );
46 }
47
48
49 /***********************************************************************
50  *           WaitForSingleObjectEx   (KERNEL32.724)
51  */
52 DWORD WINAPI WaitForSingleObjectEx( HANDLE handle, DWORD timeout,
53                                     BOOL alertable )
54 {
55     return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, alertable );
56 }
57
58
59 /***********************************************************************
60  *           WaitForMultipleObjects   (KERNEL32.721)
61  */
62 DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles,
63                                      BOOL wait_all, DWORD timeout )
64 {
65     return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE );
66 }
67
68
69 /***********************************************************************
70  *           WaitForMultipleObjectsEx   (KERNEL32.722)
71  */
72 DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
73                                        BOOL wait_all, DWORD timeout,
74                                        BOOL alertable )
75 {
76     struct select_request req;
77     struct select_reply reply;
78     int server_handle[MAXIMUM_WAIT_OBJECTS];
79     void *apc[32];
80     int i, len;
81
82     if (count > MAXIMUM_WAIT_OBJECTS)
83     {
84         SetLastError( ERROR_INVALID_PARAMETER );
85         return WAIT_FAILED;
86     }
87
88     /* FIXME: This is extremely ugly, but needed to avoid endless
89      *        recursion due to EVENT_Synchronize itself using 
90      *        EnterCriticalSection( &X11DRV_CritSection ) ...
91      */ 
92     if ( count == 0 || handles[0] != X11DRV_CritSection.LockSemaphore )
93     {
94         /* Before we might possibly block, we need to push outstanding
95          * graphics output to the X server ...  This needs to be done
96          * here so that it also works with native USER.
97          */
98         if ( timeout != 0 )
99             EVENT_Synchronize( FALSE );
100     }
101
102     for (i = 0; i < count; i++) server_handle[i] = handles[i];
103
104     req.count   = count;
105     req.flags   = 0;
106     req.timeout = timeout;
107
108     if (wait_all) req.flags |= SELECT_ALL;
109     if (alertable) req.flags |= SELECT_ALERTABLE;
110     if (timeout != INFINITE) req.flags |= SELECT_TIMEOUT;
111
112     CLIENT_SendRequest( REQ_SELECT, -1, 2,
113                         &req, sizeof(req),
114                         server_handle, count * sizeof(int) );
115     CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
116                       apc, sizeof(apc) );
117     if ((reply.signaled == STATUS_USER_APC) && (len > sizeof(reply)))
118     {
119         int i;
120         len -= sizeof(reply);
121         for (i = 0; i < len / sizeof(void*); i += 2)
122         {
123             PAPCFUNC func = (PAPCFUNC)apc[i];
124             if ( func ) func( (ULONG_PTR)apc[i+1] );
125         }
126     }
127     return reply.signaled;
128 }
129
130
131 /***********************************************************************
132  *           WIN16_WaitForSingleObject   (KERNEL.460)
133  */
134 DWORD WINAPI WIN16_WaitForSingleObject( HANDLE handle, DWORD timeout )
135 {
136     DWORD retval;
137
138     SYSLEVEL_ReleaseWin16Lock();
139     retval = WaitForSingleObject( handle, timeout );
140     SYSLEVEL_RestoreWin16Lock();
141
142     return retval;
143 }
144
145 /***********************************************************************
146  *           WIN16_WaitForMultipleObjects   (KERNEL.461)
147  */
148 DWORD WINAPI WIN16_WaitForMultipleObjects( DWORD count, const HANDLE *handles,
149                                            BOOL wait_all, DWORD timeout )
150 {
151     DWORD retval;
152
153     SYSLEVEL_ReleaseWin16Lock();
154     retval = WaitForMultipleObjects( count, handles, wait_all, timeout );
155     SYSLEVEL_RestoreWin16Lock();
156
157     return retval;
158 }
159
160 /***********************************************************************
161  *           WIN16_WaitForMultipleObjectsEx   (KERNEL.495)
162  */
163 DWORD WINAPI WIN16_WaitForMultipleObjectsEx( DWORD count, 
164                                              const HANDLE *handles,
165                                              BOOL wait_all, DWORD timeout,
166                                              BOOL alertable )
167 {
168     DWORD retval;
169
170     SYSLEVEL_ReleaseWin16Lock();
171     retval = WaitForMultipleObjectsEx( count, handles, 
172                                        wait_all, timeout, alertable );
173     SYSLEVEL_RestoreWin16Lock();
174
175     return retval;
176 }
177