Fossil SCM
Merge changes from the previous two check-ins.
Commit
300682604f7540c7bc06d928745e45535d79ca6b1c008c1c048668718c1edbc1
Parent
12c487c46f1f36b…
1 file changed
+28
-8
+28
-8
| --- src/backoffice.c | ||
| +++ src/backoffice.c | ||
| @@ -62,10 +62,13 @@ | ||
| 62 | 62 | #include <time.h> |
| 63 | 63 | #if defined(_WIN32) |
| 64 | 64 | # include <windows.h> |
| 65 | 65 | # include <stdio.h> |
| 66 | 66 | # include <process.h> |
| 67 | +# if defined(__MINGW32__) | |
| 68 | +# include <wchar.h> | |
| 69 | +# endif | |
| 67 | 70 | # define GETPID (int)GetCurrentProcessId |
| 68 | 71 | #else |
| 69 | 72 | # include <unistd.h> |
| 70 | 73 | # include <sys/types.h> |
| 71 | 74 | # include <signal.h> |
| @@ -280,21 +283,38 @@ | ||
| 280 | 283 | fossil_panic("backoffice timeout (%d seconds)", x); |
| 281 | 284 | } |
| 282 | 285 | #if defined(_WIN32) |
| 283 | 286 | static void *threadHandle = NULL; |
| 284 | 287 | static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */ |
| 285 | -static void backofficeWin32ThreadCleanup(){ | |
| 288 | +static void backofficeWin32ThreadCleanup(int bStrict){ | |
| 286 | 289 | if( threadHandle!=NULL ){ |
| 287 | 290 | /* Queue no-op asynchronous procedure call to the sleeping |
| 288 | 291 | * thread. This will cause it to wake up with a non-zero |
| 289 | 292 | * return value. */ |
| 290 | 293 | if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){ |
| 291 | 294 | /* Wait for the thread to wake up and then exit. */ |
| 292 | 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 | + } | |
| 293 | 309 | } |
| 294 | 310 | CloseHandle(threadHandle); |
| 295 | 311 | threadHandle = NULL; |
| 312 | + }else if(bStrict){ | |
| 313 | + fossil_panic( | |
| 314 | + "backofficeWin32ThreadCleanup: no timeout thread handle" | |
| 315 | + ); | |
| 296 | 316 | } |
| 297 | 317 | } |
| 298 | 318 | static unsigned __stdcall backofficeWin32SigalrmThreadProc( |
| 299 | 319 | void *pArg /* IN: Pointer to integer number of whole seconds. */ |
| 300 | 320 | ){ |
| @@ -306,11 +326,11 @@ | ||
| 306 | 326 | return 0; /* NOT REACHED */ |
| 307 | 327 | } |
| 308 | 328 | #endif |
| 309 | 329 | static void backofficeTimeout(int x){ |
| 310 | 330 | #if defined(_WIN32) |
| 311 | - backofficeWin32ThreadCleanup(); | |
| 331 | + backofficeWin32ThreadCleanup(0); | |
| 312 | 332 | threadHandle = (void*)_beginthreadex( |
| 313 | 333 | 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0 |
| 314 | 334 | ); |
| 315 | 335 | #else |
| 316 | 336 | signal(SIGALRM, backofficeSigalrmHandler); |
| @@ -477,11 +497,11 @@ | ||
| 477 | 497 | break; |
| 478 | 498 | } |
| 479 | 499 | } |
| 480 | 500 | } |
| 481 | 501 | #if defined(_WIN32) |
| 482 | - backofficeWin32ThreadCleanup(); | |
| 502 | + backofficeWin32ThreadCleanup(1); | |
| 483 | 503 | #endif |
| 484 | 504 | return; |
| 485 | 505 | } |
| 486 | 506 | |
| 487 | 507 | /* |
| @@ -495,11 +515,11 @@ | ||
| 495 | 515 | char *zLog = db_get("backoffice-logfile",0); |
| 496 | 516 | if( zLog && zLog[0] ){ |
| 497 | 517 | FILE *pLog = fossil_fopen(zLog, "a"); |
| 498 | 518 | if( pLog ){ |
| 499 | 519 | char *zDate = db_text(0, "SELECT datetime('now');"); |
| 500 | - fprintf(pLog, "%s (%d) backoffice running\n", zDate, getpid()); | |
| 520 | + fprintf(pLog, "%s (%d) backoffice running\n", zDate, GETPID()); | |
| 501 | 521 | fclose(pLog); |
| 502 | 522 | } |
| 503 | 523 | } |
| 504 | 524 | |
| 505 | 525 | /* Here is where the actual work of the backoffice happens */ |
| @@ -541,16 +561,16 @@ | ||
| 541 | 561 | argv[1] = "backoffice"; |
| 542 | 562 | argv[2] = "-R"; |
| 543 | 563 | argv[3] = backofficeDb; |
| 544 | 564 | ax[4] = 0; |
| 545 | 565 | for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]); |
| 546 | - x = _wspawnv(_P_NOWAIT, ax[0], ax); | |
| 566 | + x = _wspawnv(_P_NOWAIT, ax[0], (const wchar_t * const *)ax); | |
| 547 | 567 | for(i=0; i<=3; i++) fossil_unicode_free(ax[i]); |
| 548 | 568 | if( g.fAnyTrace ){ |
| 549 | 569 | fprintf(stderr, |
| 550 | 570 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 551 | - getpid(), (int)x); | |
| 571 | + GETPID(), (int)x); | |
| 552 | 572 | } |
| 553 | 573 | if( x>=0 ) return; |
| 554 | 574 | } |
| 555 | 575 | #else /* unix */ |
| 556 | 576 | { |
| @@ -558,11 +578,11 @@ | ||
| 558 | 578 | if( pid>0 ){ |
| 559 | 579 | /* This is the parent in a successful fork(). Return immediately. */ |
| 560 | 580 | if( g.fAnyTrace ){ |
| 561 | 581 | fprintf(stderr, |
| 562 | 582 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 563 | - getpid(), (int)pid); | |
| 583 | + GETPID(), (int)pid); | |
| 564 | 584 | } |
| 565 | 585 | return; |
| 566 | 586 | } |
| 567 | 587 | if( pid==0 ){ |
| 568 | 588 | /* This is the child of a successful fork(). Run backoffice. */ |
| @@ -570,11 +590,11 @@ | ||
| 570 | 590 | db_open_repository(backofficeDb); |
| 571 | 591 | backofficeDb = "x"; |
| 572 | 592 | backoffice_thread(); |
| 573 | 593 | db_close(1); |
| 574 | 594 | if( g.fAnyTrace ){ |
| 575 | - fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid()); | |
| 595 | + fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", GETPID()); | |
| 576 | 596 | } |
| 577 | 597 | exit(0); |
| 578 | 598 | } |
| 579 | 599 | } |
| 580 | 600 | #endif |
| 581 | 601 |
| --- src/backoffice.c | |
| +++ src/backoffice.c | |
| @@ -62,10 +62,13 @@ | |
| 62 | #include <time.h> |
| 63 | #if defined(_WIN32) |
| 64 | # include <windows.h> |
| 65 | # include <stdio.h> |
| 66 | # include <process.h> |
| 67 | # define GETPID (int)GetCurrentProcessId |
| 68 | #else |
| 69 | # include <unistd.h> |
| 70 | # include <sys/types.h> |
| 71 | # include <signal.h> |
| @@ -280,21 +283,38 @@ | |
| 280 | fossil_panic("backoffice timeout (%d seconds)", x); |
| 281 | } |
| 282 | #if defined(_WIN32) |
| 283 | static void *threadHandle = NULL; |
| 284 | static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */ |
| 285 | static void backofficeWin32ThreadCleanup(){ |
| 286 | if( threadHandle!=NULL ){ |
| 287 | /* Queue no-op asynchronous procedure call to the sleeping |
| 288 | * thread. This will cause it to wake up with a non-zero |
| 289 | * return value. */ |
| 290 | if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){ |
| 291 | /* Wait for the thread to wake up and then exit. */ |
| 292 | WaitForSingleObject(threadHandle, INFINITE); |
| 293 | } |
| 294 | CloseHandle(threadHandle); |
| 295 | threadHandle = NULL; |
| 296 | } |
| 297 | } |
| 298 | static unsigned __stdcall backofficeWin32SigalrmThreadProc( |
| 299 | void *pArg /* IN: Pointer to integer number of whole seconds. */ |
| 300 | ){ |
| @@ -306,11 +326,11 @@ | |
| 306 | return 0; /* NOT REACHED */ |
| 307 | } |
| 308 | #endif |
| 309 | static void backofficeTimeout(int x){ |
| 310 | #if defined(_WIN32) |
| 311 | backofficeWin32ThreadCleanup(); |
| 312 | threadHandle = (void*)_beginthreadex( |
| 313 | 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0 |
| 314 | ); |
| 315 | #else |
| 316 | signal(SIGALRM, backofficeSigalrmHandler); |
| @@ -477,11 +497,11 @@ | |
| 477 | break; |
| 478 | } |
| 479 | } |
| 480 | } |
| 481 | #if defined(_WIN32) |
| 482 | backofficeWin32ThreadCleanup(); |
| 483 | #endif |
| 484 | return; |
| 485 | } |
| 486 | |
| 487 | /* |
| @@ -495,11 +515,11 @@ | |
| 495 | char *zLog = db_get("backoffice-logfile",0); |
| 496 | if( zLog && zLog[0] ){ |
| 497 | FILE *pLog = fossil_fopen(zLog, "a"); |
| 498 | if( pLog ){ |
| 499 | char *zDate = db_text(0, "SELECT datetime('now');"); |
| 500 | fprintf(pLog, "%s (%d) backoffice running\n", zDate, getpid()); |
| 501 | fclose(pLog); |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | /* Here is where the actual work of the backoffice happens */ |
| @@ -541,16 +561,16 @@ | |
| 541 | argv[1] = "backoffice"; |
| 542 | argv[2] = "-R"; |
| 543 | argv[3] = backofficeDb; |
| 544 | ax[4] = 0; |
| 545 | for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]); |
| 546 | x = _wspawnv(_P_NOWAIT, ax[0], ax); |
| 547 | for(i=0; i<=3; i++) fossil_unicode_free(ax[i]); |
| 548 | if( g.fAnyTrace ){ |
| 549 | fprintf(stderr, |
| 550 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 551 | getpid(), (int)x); |
| 552 | } |
| 553 | if( x>=0 ) return; |
| 554 | } |
| 555 | #else /* unix */ |
| 556 | { |
| @@ -558,11 +578,11 @@ | |
| 558 | if( pid>0 ){ |
| 559 | /* This is the parent in a successful fork(). Return immediately. */ |
| 560 | if( g.fAnyTrace ){ |
| 561 | fprintf(stderr, |
| 562 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 563 | getpid(), (int)pid); |
| 564 | } |
| 565 | return; |
| 566 | } |
| 567 | if( pid==0 ){ |
| 568 | /* This is the child of a successful fork(). Run backoffice. */ |
| @@ -570,11 +590,11 @@ | |
| 570 | db_open_repository(backofficeDb); |
| 571 | backofficeDb = "x"; |
| 572 | backoffice_thread(); |
| 573 | db_close(1); |
| 574 | if( g.fAnyTrace ){ |
| 575 | fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid()); |
| 576 | } |
| 577 | exit(0); |
| 578 | } |
| 579 | } |
| 580 | #endif |
| 581 |
| --- src/backoffice.c | |
| +++ src/backoffice.c | |
| @@ -62,10 +62,13 @@ | |
| 62 | #include <time.h> |
| 63 | #if defined(_WIN32) |
| 64 | # include <windows.h> |
| 65 | # include <stdio.h> |
| 66 | # include <process.h> |
| 67 | # if defined(__MINGW32__) |
| 68 | # include <wchar.h> |
| 69 | # endif |
| 70 | # define GETPID (int)GetCurrentProcessId |
| 71 | #else |
| 72 | # include <unistd.h> |
| 73 | # include <sys/types.h> |
| 74 | # include <signal.h> |
| @@ -280,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 | ){ |
| @@ -306,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); |
| @@ -477,11 +497,11 @@ | |
| 497 | break; |
| 498 | } |
| 499 | } |
| 500 | } |
| 501 | #if defined(_WIN32) |
| 502 | backofficeWin32ThreadCleanup(1); |
| 503 | #endif |
| 504 | return; |
| 505 | } |
| 506 | |
| 507 | /* |
| @@ -495,11 +515,11 @@ | |
| 515 | char *zLog = db_get("backoffice-logfile",0); |
| 516 | if( zLog && zLog[0] ){ |
| 517 | FILE *pLog = fossil_fopen(zLog, "a"); |
| 518 | if( pLog ){ |
| 519 | char *zDate = db_text(0, "SELECT datetime('now');"); |
| 520 | fprintf(pLog, "%s (%d) backoffice running\n", zDate, GETPID()); |
| 521 | fclose(pLog); |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | /* Here is where the actual work of the backoffice happens */ |
| @@ -541,16 +561,16 @@ | |
| 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 | } |
| 573 | if( x>=0 ) return; |
| 574 | } |
| 575 | #else /* unix */ |
| 576 | { |
| @@ -558,11 +578,11 @@ | |
| 578 | if( pid>0 ){ |
| 579 | /* This is the parent in a successful fork(). Return immediately. */ |
| 580 | if( g.fAnyTrace ){ |
| 581 | fprintf(stderr, |
| 582 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 583 | GETPID(), (int)pid); |
| 584 | } |
| 585 | return; |
| 586 | } |
| 587 | if( pid==0 ){ |
| 588 | /* This is the child of a successful fork(). Run backoffice. */ |
| @@ -570,11 +590,11 @@ | |
| 590 | db_open_repository(backofficeDb); |
| 591 | backofficeDb = "x"; |
| 592 | backoffice_thread(); |
| 593 | db_close(1); |
| 594 | if( g.fAnyTrace ){ |
| 595 | fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", GETPID()); |
| 596 | } |
| 597 | exit(0); |
| 598 | } |
| 599 | } |
| 600 | #endif |
| 601 |