initial load of upstream version 1.06.32
[xmlrpc-c] / lib / abyss / src / thread_windows.c
1 #include <process.h>
2 #include <windows.h>
3
4 #include "xmlrpc_config.h"
5
6 #include "mallocvar.h"
7 #include "xmlrpc-c/string_int.h"
8
9 #include "xmlrpc-c/abyss.h"
10
11 #include "thread.h"
12
13
14
15 struct abyss_thread {
16     HANDLE          handle;
17     void *          userHandle;
18     TThreadDoneFn * threadDone;
19 };
20
21 #define  THREAD_STACK_SIZE (16*1024L)
22
23
24 typedef uint32_t (WINAPI WinThreadProc)(void *);
25
26
27 void
28 ThreadCreate(TThread **      const threadPP,
29              void *          const userHandle,
30              TThreadProc   * const func,
31              TThreadDoneFn * const threadDone,
32              abyss_bool      const useSigchld,
33              const char **   const errorP) {
34
35     DWORD z;
36     TThread * threadP;
37
38     MALLOCVAR(threadP);
39
40     if (threadP == NULL)
41         xmlrpc_asprintf(errorP,
42                         "Can't allocate memory for thread descriptor.");
43     else {
44         threadP->userHandle = userHandle;
45         threadP->threadDone = threadDone;
46         threadP->handle = (HANDLE)_beginthreadex(NULL, THREAD_STACK_SIZE, func,
47                                          userHandle,
48                                          CREATE_SUSPENDED, &z);
49         if (threadP->handle == NULL)
50             xmlrpc_asprintf(errorP, "_beginthreadex() failed.");
51         else {
52             *errorP = NULL;
53             *threadPP = threadP;
54         }
55         if (*errorP)
56             free(threadP);
57     }
58 }
59
60
61
62 abyss_bool
63 ThreadRun(TThread * const threadP) {
64     return (ResumeThread(threadP->handle) != 0xFFFFFFFF);
65 }
66
67
68
69 abyss_bool
70 ThreadStop(TThread * const threadP) {
71
72     return (SuspendThread(threadP->handle) != 0xFFFFFFFF);
73 }
74
75
76
77 abyss_bool
78 ThreadKill(TThread * const threadP) {
79     return (TerminateThread(threadP->handle, 0) != 0);
80 }
81
82
83
84 void
85 ThreadWaitAndRelease(TThread * const threadP) {
86
87     ThreadRelease(threadP);
88
89     if (threadP->threadDone)
90         threadP->threadDone(threadP->userHandle);
91
92     free(threadP);
93 }
94
95
96
97 void
98 ThreadExit(int const retValue) {
99
100     _endthreadex(retValue);
101 }
102
103
104
105 void
106 ThreadRelease(TThread * const threadP) {
107
108     CloseHandle(threadP->handle);
109 }
110
111
112
113 abyss_bool
114 ThreadForks(void) {
115
116     return FALSE;
117 }
118
119
120
121 void
122 ThreadUpdateStatus(TThread * const threadP ATTR_UNUSED) {
123
124     /* Threads keep their own statuses up to date, so there's nothing
125        to do here.
126     */
127 }
128
129
130
131 abyss_bool
132 MutexCreate(TMutex * const mutexP) {
133
134     *mutexP = CreateMutex(NULL, FALSE, NULL);
135
136     return (*mutexP != NULL);
137 }
138
139
140
141 abyss_bool
142 MutexLock(TMutex * const mutexP) {
143
144     return (WaitForSingleObject(*mutexP, INFINITE) != WAIT_TIMEOUT);
145 }
146
147
148
149 abyss_bool
150 MutexUnlock(TMutex * const mutexP) {
151     return ReleaseMutex(*mutexP);
152 }
153
154
155
156 abyss_bool
157 MutexTryLock(TMutex * const mutexP) {
158     return (WaitForSingleObject(*mutexP, 0) != WAIT_TIMEOUT);
159 }
160
161
162
163 void
164 MutexFree(TMutex * const mutexP) {
165     CloseHandle(*mutexP);
166 }
167