Fossil SCM

Use a thread to implement the backoffice for Win32.

mistachkin 2018-07-31 00:10 UTC trunk
Commit a9578f7870ced30545f987a324b1bfb87bd9e9e6a9af85adfc5ae63331e97e69
1 file changed +37 -3
+37 -3
--- src/backoffice.c
+++ src/backoffice.c
@@ -40,10 +40,11 @@
4040
*/
4141
#include "config.h"
4242
#include "backoffice.h"
4343
#include <time.h>
4444
#if defined(_WIN32)
45
+# include <process.h>
4546
# include <windows.h>
4647
#else
4748
# include <unistd.h>
4849
# include <sys/types.h>
4950
# include <signal.h>
@@ -171,17 +172,47 @@
171172
/*
172173
** Set an alarm to cause the process to exit after "x" seconds. This
173174
** prevents any kind of bug from keeping a backoffice process running
174175
** indefinitely.
175176
*/
176
-#if !defined(_WIN32)
177177
static void backofficeSigalrmHandler(int x){
178
- fossil_panic("backoffice timeout");
178
+ fossil_panic("backoffice timeout (%d seconds)", x);
179
+}
180
+#if defined(_WIN32)
181
+static void *threadHandle = NULL;
182
+static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */
183
+static void backofficeWin32ThreadCleanup(){
184
+ if( threadHandle!=NULL ){
185
+ /* Queue no-op asynchronous procedure call to the sleeping
186
+ * thread. This will cause it to wake up with a non-zero
187
+ * return value. */
188
+ if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){
189
+ /* Wait for the thread to wake up and then exit. */
190
+ WaitForSingleObject(threadHandle, INFINITE);
191
+ }
192
+ CloseHandle(threadHandle);
193
+ threadHandle = NULL;
194
+ }
195
+}
196
+static unsigned __stdcall backofficeWin32SigalrmThreadProc(
197
+ void *pArg /* IN: Pointer to integer number of whole seconds. */
198
+){
199
+ int seconds = FOSSIL_PTR_TO_INT(pArg);
200
+ if( SleepEx((DWORD)seconds * 1000, TRUE)==0 ){
201
+ backofficeSigalrmHandler(seconds);
202
+ }
203
+ _endthreadex(0);
204
+ return 0; /* NOT REACHED */
179205
}
180206
#endif
181207
static void backofficeTimeout(int x){
182
-#if !defined(_WIN32)
208
+#if defined(_WIN32)
209
+ if( threadHandle!=NULL ) return;
210
+ threadHandle = (void*)_beginthreadex(
211
+ 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0
212
+ );
213
+#else
183214
signal(SIGALRM, backofficeSigalrmHandler);
184215
alarm(x);
185216
#endif
186217
}
187218
@@ -293,10 +324,13 @@
293324
warningDelay *= 2;
294325
}
295326
sqlite3_sleep(1000);
296327
}
297328
}
329
+#if defined(_WIN32)
330
+ backofficeWin32ThreadCleanup();
331
+#endif
298332
return;
299333
}
300334
301335
/*
302336
** This routine runs to do the backoffice processing. When adding new
303337
--- src/backoffice.c
+++ src/backoffice.c
@@ -40,10 +40,11 @@
40 */
41 #include "config.h"
42 #include "backoffice.h"
43 #include <time.h>
44 #if defined(_WIN32)
 
45 # include <windows.h>
46 #else
47 # include <unistd.h>
48 # include <sys/types.h>
49 # include <signal.h>
@@ -171,17 +172,47 @@
171 /*
172 ** Set an alarm to cause the process to exit after "x" seconds. This
173 ** prevents any kind of bug from keeping a backoffice process running
174 ** indefinitely.
175 */
176 #if !defined(_WIN32)
177 static void backofficeSigalrmHandler(int x){
178 fossil_panic("backoffice timeout");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179 }
180 #endif
181 static void backofficeTimeout(int x){
182 #if !defined(_WIN32)
 
 
 
 
 
183 signal(SIGALRM, backofficeSigalrmHandler);
184 alarm(x);
185 #endif
186 }
187
@@ -293,10 +324,13 @@
293 warningDelay *= 2;
294 }
295 sqlite3_sleep(1000);
296 }
297 }
 
 
 
298 return;
299 }
300
301 /*
302 ** This routine runs to do the backoffice processing. When adding new
303
--- src/backoffice.c
+++ src/backoffice.c
@@ -40,10 +40,11 @@
40 */
41 #include "config.h"
42 #include "backoffice.h"
43 #include <time.h>
44 #if defined(_WIN32)
45 # include <process.h>
46 # include <windows.h>
47 #else
48 # include <unistd.h>
49 # include <sys/types.h>
50 # include <signal.h>
@@ -171,17 +172,47 @@
172 /*
173 ** Set an alarm to cause the process to exit after "x" seconds. This
174 ** prevents any kind of bug from keeping a backoffice process running
175 ** indefinitely.
176 */
 
177 static void backofficeSigalrmHandler(int x){
178 fossil_panic("backoffice timeout (%d seconds)", x);
179 }
180 #if defined(_WIN32)
181 static void *threadHandle = NULL;
182 static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */
183 static void backofficeWin32ThreadCleanup(){
184 if( threadHandle!=NULL ){
185 /* Queue no-op asynchronous procedure call to the sleeping
186 * thread. This will cause it to wake up with a non-zero
187 * return value. */
188 if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){
189 /* Wait for the thread to wake up and then exit. */
190 WaitForSingleObject(threadHandle, INFINITE);
191 }
192 CloseHandle(threadHandle);
193 threadHandle = NULL;
194 }
195 }
196 static unsigned __stdcall backofficeWin32SigalrmThreadProc(
197 void *pArg /* IN: Pointer to integer number of whole seconds. */
198 ){
199 int seconds = FOSSIL_PTR_TO_INT(pArg);
200 if( SleepEx((DWORD)seconds * 1000, TRUE)==0 ){
201 backofficeSigalrmHandler(seconds);
202 }
203 _endthreadex(0);
204 return 0; /* NOT REACHED */
205 }
206 #endif
207 static void backofficeTimeout(int x){
208 #if defined(_WIN32)
209 if( threadHandle!=NULL ) return;
210 threadHandle = (void*)_beginthreadex(
211 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0
212 );
213 #else
214 signal(SIGALRM, backofficeSigalrmHandler);
215 alarm(x);
216 #endif
217 }
218
@@ -293,10 +324,13 @@
324 warningDelay *= 2;
325 }
326 sqlite3_sleep(1000);
327 }
328 }
329 #if defined(_WIN32)
330 backofficeWin32ThreadCleanup();
331 #endif
332 return;
333 }
334
335 /*
336 ** This routine runs to do the backoffice processing. When adding new
337

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button