Improve internal threading API. Introduce win32/win32thread.[ch]
[perl.git] / win32 / win32thread.h
1 /*typedef CRITICAL_SECTION perl_mutex;*/
2 typedef HANDLE perl_mutex;
3 typedef HANDLE perl_cond;
4 typedef DWORD perl_key;
5 typedef HANDLE perl_thread;
6
7 /* XXX Critical Sections used instead of mutexes: lightweight,
8  * but can't be communicated to child processes, and can't get
9  * HANDLE to it for use elsewhere
10  */
11 /*
12 #define MUTEX_INIT(m) InitializeCriticalSection(m)
13 #define MUTEX_LOCK(m) EnterCriticalSection(m)
14 #define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
15 #define MUTEX_DESTROY(m) DeleteCriticalSection(m)
16 */
17
18 #define MUTEX_INIT(m) \
19     STMT_START {                                                \
20         if ((*(m) = CreateMutex(NULL,FALSE,NULL)) == NULL)      \
21             croak("panic: MUTEX_INIT");                         \
22     } STMT_END
23 #define MUTEX_LOCK(m) \
24     STMT_START {                                                \
25         if (WaitForSingleObject(*(m),INFINITE) == WAIT_FAILED)  \
26             croak("panic: MUTEX_LOCK");                         \
27     } STMT_END
28 #define MUTEX_UNLOCK(m) \
29     STMT_START {                                                \
30         if (ReleaseMutex(*(m)) == 0)                            \
31             croak("panic: MUTEX_UNLOCK");                       \
32     } STMT_END
33 #define MUTEX_DESTROY(m) \
34     STMT_START {                                                \
35         if (CloseHandle(*(m)) == 0)                             \
36             croak("panic: MUTEX_DESTROY");                      \
37     } STMT_END
38
39 #define COND_INIT(c) \
40     STMT_START {                                                \
41         if ((*(c) = CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL) \
42             croak("panic: COND_INIT");                          \
43     } STMT_END
44 #define COND_SIGNAL(c) \
45     STMT_START {                                                \
46         if (PulseEvent(*(c)) == 0)                              \
47             croak("panic: COND_SIGNAL (%ld)",GetLastError());   \
48     } STMT_END
49 #define COND_BROADCAST(c) \
50     STMT_START {                                                \
51         if (PulseEvent(*(c)) == 0)                              \
52             croak("panic: COND_BROADCAST");                     \
53     } STMT_END
54 /* #define COND_WAIT(c, m) \
55     STMT_START {                                                \
56         if (WaitForSingleObject(*(c),INFINITE) == WAIT_FAILED)  \
57             croak("panic: COND_WAIT");                          \
58     } STMT_END
59 */
60 #define COND_WAIT(c, m) \
61     STMT_START {                                                \
62         if (SignalObjectAndWait(*(m),*(c),INFINITE,FALSE) == WAIT_FAILED)\
63             croak("panic: COND_WAIT");                          \
64         else                                                    \
65             MUTEX_LOCK(m);                                      \
66     } STMT_END
67 #define COND_DESTROY(c) \
68     STMT_START {                                                \
69         if (CloseHandle(*(c)) == 0)                             \
70             croak("panic: COND_DESTROY");                       \
71     } STMT_END
72
73 #define DETACH(t) \
74     STMT_START {                                                \
75         if (CloseHandle((t)->Tself) == 0) {                     \
76             MUTEX_UNLOCK(&(t)->mutex);                          \
77             croak("panic: DETACH");                             \
78         }                                                       \
79     } STMT_END
80
81 #define THR ((struct thread *) TlsGetValue(thr_key))
82
83 #define HAVE_THREAD_INTERN
84
85 #define JOIN(t, avp)                                                    \
86     STMT_START {                                                        \
87         if ((WaitForSingleObject((t)->Tself,INFINITE) == WAIT_FAILED)   \
88              || (GetExitCodeThread((t)->Tself,(LPDWORD)(avp)) == 0))    \
89             croak("panic: JOIN");                                       \
90     } STMT_END
91
92 #define SET_THR(t)                                      \
93     STMT_START {                                        \
94         if (TlsSetValue(thr_key, (void *) (t)) == 0)    \
95             croak("panic: TlsSetValue");                \
96     } STMT_END
97
98 #define THREAD_CREATE(t, f)     thread_create(t, f)
99 #define THREAD_POST_CREATE(t)   NOOP
100 #define THREAD_RET_TYPE         DWORD WINAPI
101 #define THREAD_RET_CAST(p)      ((DWORD)(p))
102 #define YIELD                   Sleep(0)