Fossil SCM

Improve Win32 error handling in the backoffice module and fix a compiler warning.

mistachkin 2018-08-07 23:08 trunk
Commit 3c0848797d1c7e1eb89b7c8f387c53ad75d675f2a8598c3b4ca53d5e73df1b43
1 file changed +21 -5
+21 -5
--- src/backoffice.c
+++ src/backoffice.c
@@ -283,21 +283,38 @@
283283
fossil_panic("backoffice timeout (%d seconds)", x);
284284
}
285285
#if defined(_WIN32)
286286
static void *threadHandle = NULL;
287287
static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */
288
-static void backofficeWin32ThreadCleanup(){
288
+static void backofficeWin32ThreadCleanup(int bStrict){
289289
if( threadHandle!=NULL ){
290290
/* Queue no-op asynchronous procedure call to the sleeping
291291
* thread. This will cause it to wake up with a non-zero
292292
* return value. */
293293
if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){
294294
/* Wait for the thread to wake up and then exit. */
295295
WaitForSingleObject(threadHandle, INFINITE);
296
+ }else if(bStrict){
297
+ DWORD dwLastError = GetLastError();
298
+ fossil_errorlog(
299
+ "backofficeWin32ThreadCleanup: QueueUserAPC failed, code %lu",
300
+ dwLastError
301
+ );
302
+ if( !TerminateThread(threadHandle, dwLastError) ){
303
+ dwLastError = GetLastError();
304
+ fossil_panic(
305
+ "backofficeWin32ThreadCleanup: TerminateThread failed, code %lu",
306
+ dwLastError
307
+ );
308
+ }
296309
}
297310
CloseHandle(threadHandle);
298311
threadHandle = NULL;
312
+ }else if(bStrict){
313
+ fossil_panic(
314
+ "backofficeWin32ThreadCleanup: no timeout thread handle"
315
+ );
299316
}
300317
}
301318
static unsigned __stdcall backofficeWin32SigalrmThreadProc(
302319
void *pArg /* IN: Pointer to integer number of whole seconds. */
303320
){
@@ -309,11 +326,11 @@
309326
return 0; /* NOT REACHED */
310327
}
311328
#endif
312329
static void backofficeTimeout(int x){
313330
#if defined(_WIN32)
314
- backofficeWin32ThreadCleanup();
331
+ backofficeWin32ThreadCleanup(0);
315332
threadHandle = (void*)_beginthreadex(
316333
0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0
317334
);
318335
#else
319336
signal(SIGALRM, backofficeSigalrmHandler);
@@ -480,12 +497,11 @@
480497
break;
481498
}
482499
}
483500
}
484501
#if defined(_WIN32)
485
- assert( threadHandle!=NULL );
486
- backofficeWin32ThreadCleanup();
502
+ backofficeWin32ThreadCleanup(1);
487503
#endif
488504
return;
489505
}
490506
491507
/*
@@ -545,11 +561,11 @@
545561
argv[1] = "backoffice";
546562
argv[2] = "-R";
547563
argv[3] = backofficeDb;
548564
ax[4] = 0;
549565
for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]);
550
- x = _wspawnv(_P_NOWAIT, ax[0], ax);
566
+ x = _wspawnv(_P_NOWAIT, ax[0], (const wchar_t * const *)ax);
551567
for(i=0; i<=3; i++) fossil_unicode_free(ax[i]);
552568
if( g.fAnyTrace ){
553569
fprintf(stderr,
554570
"/***** Subprocess %d creates backoffice child %d *****/\n",
555571
GETPID(), (int)x);
556572
--- src/backoffice.c
+++ src/backoffice.c
@@ -283,21 +283,38 @@
283 fossil_panic("backoffice timeout (%d seconds)", x);
284 }
285 #if defined(_WIN32)
286 static void *threadHandle = NULL;
287 static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */
288 static void backofficeWin32ThreadCleanup(){
289 if( threadHandle!=NULL ){
290 /* Queue no-op asynchronous procedure call to the sleeping
291 * thread. This will cause it to wake up with a non-zero
292 * return value. */
293 if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){
294 /* Wait for the thread to wake up and then exit. */
295 WaitForSingleObject(threadHandle, INFINITE);
 
 
 
 
 
 
 
 
 
 
 
 
 
296 }
297 CloseHandle(threadHandle);
298 threadHandle = NULL;
 
 
 
 
299 }
300 }
301 static unsigned __stdcall backofficeWin32SigalrmThreadProc(
302 void *pArg /* IN: Pointer to integer number of whole seconds. */
303 ){
@@ -309,11 +326,11 @@
309 return 0; /* NOT REACHED */
310 }
311 #endif
312 static void backofficeTimeout(int x){
313 #if defined(_WIN32)
314 backofficeWin32ThreadCleanup();
315 threadHandle = (void*)_beginthreadex(
316 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0
317 );
318 #else
319 signal(SIGALRM, backofficeSigalrmHandler);
@@ -480,12 +497,11 @@
480 break;
481 }
482 }
483 }
484 #if defined(_WIN32)
485 assert( threadHandle!=NULL );
486 backofficeWin32ThreadCleanup();
487 #endif
488 return;
489 }
490
491 /*
@@ -545,11 +561,11 @@
545 argv[1] = "backoffice";
546 argv[2] = "-R";
547 argv[3] = backofficeDb;
548 ax[4] = 0;
549 for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]);
550 x = _wspawnv(_P_NOWAIT, ax[0], ax);
551 for(i=0; i<=3; i++) fossil_unicode_free(ax[i]);
552 if( g.fAnyTrace ){
553 fprintf(stderr,
554 "/***** Subprocess %d creates backoffice child %d *****/\n",
555 GETPID(), (int)x);
556
--- src/backoffice.c
+++ src/backoffice.c
@@ -283,21 +283,38 @@
283 fossil_panic("backoffice timeout (%d seconds)", x);
284 }
285 #if defined(_WIN32)
286 static void *threadHandle = NULL;
287 static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */
288 static void backofficeWin32ThreadCleanup(int bStrict){
289 if( threadHandle!=NULL ){
290 /* Queue no-op asynchronous procedure call to the sleeping
291 * thread. This will cause it to wake up with a non-zero
292 * return value. */
293 if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){
294 /* Wait for the thread to wake up and then exit. */
295 WaitForSingleObject(threadHandle, INFINITE);
296 }else if(bStrict){
297 DWORD dwLastError = GetLastError();
298 fossil_errorlog(
299 "backofficeWin32ThreadCleanup: QueueUserAPC failed, code %lu",
300 dwLastError
301 );
302 if( !TerminateThread(threadHandle, dwLastError) ){
303 dwLastError = GetLastError();
304 fossil_panic(
305 "backofficeWin32ThreadCleanup: TerminateThread failed, code %lu",
306 dwLastError
307 );
308 }
309 }
310 CloseHandle(threadHandle);
311 threadHandle = NULL;
312 }else if(bStrict){
313 fossil_panic(
314 "backofficeWin32ThreadCleanup: no timeout thread handle"
315 );
316 }
317 }
318 static unsigned __stdcall backofficeWin32SigalrmThreadProc(
319 void *pArg /* IN: Pointer to integer number of whole seconds. */
320 ){
@@ -309,11 +326,11 @@
326 return 0; /* NOT REACHED */
327 }
328 #endif
329 static void backofficeTimeout(int x){
330 #if defined(_WIN32)
331 backofficeWin32ThreadCleanup(0);
332 threadHandle = (void*)_beginthreadex(
333 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0
334 );
335 #else
336 signal(SIGALRM, backofficeSigalrmHandler);
@@ -480,12 +497,11 @@
497 break;
498 }
499 }
500 }
501 #if defined(_WIN32)
502 backofficeWin32ThreadCleanup(1);
 
503 #endif
504 return;
505 }
506
507 /*
@@ -545,11 +561,11 @@
561 argv[1] = "backoffice";
562 argv[2] = "-R";
563 argv[3] = backofficeDb;
564 ax[4] = 0;
565 for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]);
566 x = _wspawnv(_P_NOWAIT, ax[0], (const wchar_t * const *)ax);
567 for(i=0; i<=3; i++) fossil_unicode_free(ax[i]);
568 if( g.fAnyTrace ){
569 fprintf(stderr,
570 "/***** Subprocess %d creates backoffice child %d *****/\n",
571 GETPID(), (int)x);
572

Keyboard Shortcuts

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