Fossil SCM
Improve Win32 error handling in the backoffice module and fix a compiler warning.
Commit
3c0848797d1c7e1eb89b7c8f387c53ad75d675f2a8598c3b4ca53d5e73df1b43
Parent
e285341f0cf0773…
1 file changed
+21
-5
+21
-5
| --- src/backoffice.c | ||
| +++ src/backoffice.c | ||
| @@ -283,21 +283,38 @@ | ||
| 283 | 283 | fossil_panic("backoffice timeout (%d seconds)", x); |
| 284 | 284 | } |
| 285 | 285 | #if defined(_WIN32) |
| 286 | 286 | static void *threadHandle = NULL; |
| 287 | 287 | static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */ |
| 288 | -static void backofficeWin32ThreadCleanup(){ | |
| 288 | +static void backofficeWin32ThreadCleanup(int bStrict){ | |
| 289 | 289 | if( threadHandle!=NULL ){ |
| 290 | 290 | /* Queue no-op asynchronous procedure call to the sleeping |
| 291 | 291 | * thread. This will cause it to wake up with a non-zero |
| 292 | 292 | * return value. */ |
| 293 | 293 | if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){ |
| 294 | 294 | /* Wait for the thread to wake up and then exit. */ |
| 295 | 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 | + } | |
| 296 | 309 | } |
| 297 | 310 | CloseHandle(threadHandle); |
| 298 | 311 | threadHandle = NULL; |
| 312 | + }else if(bStrict){ | |
| 313 | + fossil_panic( | |
| 314 | + "backofficeWin32ThreadCleanup: no timeout thread handle" | |
| 315 | + ); | |
| 299 | 316 | } |
| 300 | 317 | } |
| 301 | 318 | static unsigned __stdcall backofficeWin32SigalrmThreadProc( |
| 302 | 319 | void *pArg /* IN: Pointer to integer number of whole seconds. */ |
| 303 | 320 | ){ |
| @@ -309,11 +326,11 @@ | ||
| 309 | 326 | return 0; /* NOT REACHED */ |
| 310 | 327 | } |
| 311 | 328 | #endif |
| 312 | 329 | static void backofficeTimeout(int x){ |
| 313 | 330 | #if defined(_WIN32) |
| 314 | - backofficeWin32ThreadCleanup(); | |
| 331 | + backofficeWin32ThreadCleanup(0); | |
| 315 | 332 | threadHandle = (void*)_beginthreadex( |
| 316 | 333 | 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0 |
| 317 | 334 | ); |
| 318 | 335 | #else |
| 319 | 336 | signal(SIGALRM, backofficeSigalrmHandler); |
| @@ -480,12 +497,11 @@ | ||
| 480 | 497 | break; |
| 481 | 498 | } |
| 482 | 499 | } |
| 483 | 500 | } |
| 484 | 501 | #if defined(_WIN32) |
| 485 | - assert( threadHandle!=NULL ); | |
| 486 | - backofficeWin32ThreadCleanup(); | |
| 502 | + backofficeWin32ThreadCleanup(1); | |
| 487 | 503 | #endif |
| 488 | 504 | return; |
| 489 | 505 | } |
| 490 | 506 | |
| 491 | 507 | /* |
| @@ -545,11 +561,11 @@ | ||
| 545 | 561 | argv[1] = "backoffice"; |
| 546 | 562 | argv[2] = "-R"; |
| 547 | 563 | argv[3] = backofficeDb; |
| 548 | 564 | ax[4] = 0; |
| 549 | 565 | 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); | |
| 551 | 567 | for(i=0; i<=3; i++) fossil_unicode_free(ax[i]); |
| 552 | 568 | if( g.fAnyTrace ){ |
| 553 | 569 | fprintf(stderr, |
| 554 | 570 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 555 | 571 | GETPID(), (int)x); |
| 556 | 572 |
| --- 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 |