Fossil SCM
Fix the separate-process backoffice so that it works smoothly on linux. Still work to be done on Windows.
Commit
af7d67c6a25f5af06284b2e0dbc8296bca9338631053ba2e207181394d4de867
Parent
a4b59c320796b31…
5 files changed
+16
-2
+2
-12
+1
+2
+1
-1
+16
-2
| --- src/backoffice.c | ||
| +++ src/backoffice.c | ||
| @@ -91,10 +91,23 @@ | ||
| 91 | 91 | */ |
| 92 | 92 | static char *backofficeDb = 0; |
| 93 | 93 | |
| 94 | 94 | /* End of state variables |
| 95 | 95 | ****************************************************************************/ |
| 96 | + | |
| 97 | +/* | |
| 98 | +** Do not allow backoffice processes to sleep waiting on a timeslot. | |
| 99 | +** They must either do their work immediately or exit. | |
| 100 | +** | |
| 101 | +** In a perfect world, this interface would not exist, as there would | |
| 102 | +** never be a problem with waiting backoffice threads. But in some cases | |
| 103 | +** a backoffice will delay a UI thread, so we don't want them to run for | |
| 104 | +** longer than needed. | |
| 105 | +*/ | |
| 106 | +void backoffice_no_delay(void){ | |
| 107 | + backofficeNoDelay = 1; | |
| 108 | +} | |
| 96 | 109 | |
| 97 | 110 | /* |
| 98 | 111 | ** Parse a unsigned 64-bit integer from a string. Return a pointer |
| 99 | 112 | ** to the character of z[] that occurs after the integer. |
| 100 | 113 | */ |
| @@ -375,12 +388,13 @@ | ||
| 375 | 388 | { |
| 376 | 389 | pid_t pid = fork(); |
| 377 | 390 | if( pid>0 ){ |
| 378 | 391 | /* This is the parent in a successful fork(). Return immediately. */ |
| 379 | 392 | if( g.fAnyTrace ){ |
| 380 | - fprintf(stderr, "/***** Backoffice Child Creates as %d *****/\n", | |
| 381 | - (int)pid); | |
| 393 | + fprintf(stderr, | |
| 394 | + "/***** Subprocess %d creates backoffice child %d *****/\n", | |
| 395 | + getpid(), (int)pid); | |
| 382 | 396 | } |
| 383 | 397 | return; |
| 384 | 398 | } |
| 385 | 399 | if( pid==0 ){ |
| 386 | 400 | /* This is the child of a successful fork(). Run backoffice. */ |
| 387 | 401 |
| --- src/backoffice.c | |
| +++ src/backoffice.c | |
| @@ -91,10 +91,23 @@ | |
| 91 | */ |
| 92 | static char *backofficeDb = 0; |
| 93 | |
| 94 | /* End of state variables |
| 95 | ****************************************************************************/ |
| 96 | |
| 97 | /* |
| 98 | ** Parse a unsigned 64-bit integer from a string. Return a pointer |
| 99 | ** to the character of z[] that occurs after the integer. |
| 100 | */ |
| @@ -375,12 +388,13 @@ | |
| 375 | { |
| 376 | pid_t pid = fork(); |
| 377 | if( pid>0 ){ |
| 378 | /* This is the parent in a successful fork(). Return immediately. */ |
| 379 | if( g.fAnyTrace ){ |
| 380 | fprintf(stderr, "/***** Backoffice Child Creates as %d *****/\n", |
| 381 | (int)pid); |
| 382 | } |
| 383 | return; |
| 384 | } |
| 385 | if( pid==0 ){ |
| 386 | /* This is the child of a successful fork(). Run backoffice. */ |
| 387 |
| --- src/backoffice.c | |
| +++ src/backoffice.c | |
| @@ -91,10 +91,23 @@ | |
| 91 | */ |
| 92 | static char *backofficeDb = 0; |
| 93 | |
| 94 | /* End of state variables |
| 95 | ****************************************************************************/ |
| 96 | |
| 97 | /* |
| 98 | ** Do not allow backoffice processes to sleep waiting on a timeslot. |
| 99 | ** They must either do their work immediately or exit. |
| 100 | ** |
| 101 | ** In a perfect world, this interface would not exist, as there would |
| 102 | ** never be a problem with waiting backoffice threads. But in some cases |
| 103 | ** a backoffice will delay a UI thread, so we don't want them to run for |
| 104 | ** longer than needed. |
| 105 | */ |
| 106 | void backoffice_no_delay(void){ |
| 107 | backofficeNoDelay = 1; |
| 108 | } |
| 109 | |
| 110 | /* |
| 111 | ** Parse a unsigned 64-bit integer from a string. Return a pointer |
| 112 | ** to the character of z[] that occurs after the integer. |
| 113 | */ |
| @@ -375,12 +388,13 @@ | |
| 388 | { |
| 389 | pid_t pid = fork(); |
| 390 | if( pid>0 ){ |
| 391 | /* This is the parent in a successful fork(). Return immediately. */ |
| 392 | if( g.fAnyTrace ){ |
| 393 | fprintf(stderr, |
| 394 | "/***** Subprocess %d creates backoffice child %d *****/\n", |
| 395 | getpid(), (int)pid); |
| 396 | } |
| 397 | return; |
| 398 | } |
| 399 | if( pid==0 ){ |
| 400 | /* This is the child of a successful fork(). Run backoffice. */ |
| 401 |
+2
-12
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -344,22 +344,12 @@ | ||
| 344 | 344 | |
| 345 | 345 | /* After the webpage has been sent, do any useful background |
| 346 | 346 | ** processing. |
| 347 | 347 | */ |
| 348 | 348 | g.cgiOutput = 2; |
| 349 | - if( g.db!=0 && iReplyStatus==200 && !g.fSshClient ){ | |
| 350 | - fclose(g.httpOut); | |
| 351 | -#ifdef _WIN32 | |
| 352 | - g.httpOut = fossil_fopen("NUL", "wb"); | |
| 353 | -#else | |
| 354 | - g.httpOut = fossil_fopen("/dev/null", "wb"); | |
| 355 | -#endif | |
| 356 | - if( g.httpOut==0 ){ | |
| 357 | - fossil_warning("failed ot open /dev/null"); | |
| 358 | - }else{ | |
| 359 | - backoffice_check_if_needed(); | |
| 360 | - } | |
| 349 | + if( g.db!=0 && iReplyStatus==200 ){ | |
| 350 | + backoffice_check_if_needed(); | |
| 361 | 351 | } |
| 362 | 352 | } |
| 363 | 353 | |
| 364 | 354 | /* |
| 365 | 355 | ** Do a redirect request to the URL given in the argument. |
| 366 | 356 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -344,22 +344,12 @@ | |
| 344 | |
| 345 | /* After the webpage has been sent, do any useful background |
| 346 | ** processing. |
| 347 | */ |
| 348 | g.cgiOutput = 2; |
| 349 | if( g.db!=0 && iReplyStatus==200 && !g.fSshClient ){ |
| 350 | fclose(g.httpOut); |
| 351 | #ifdef _WIN32 |
| 352 | g.httpOut = fossil_fopen("NUL", "wb"); |
| 353 | #else |
| 354 | g.httpOut = fossil_fopen("/dev/null", "wb"); |
| 355 | #endif |
| 356 | if( g.httpOut==0 ){ |
| 357 | fossil_warning("failed ot open /dev/null"); |
| 358 | }else{ |
| 359 | backoffice_check_if_needed(); |
| 360 | } |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | /* |
| 365 | ** Do a redirect request to the URL given in the argument. |
| 366 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -344,22 +344,12 @@ | |
| 344 | |
| 345 | /* After the webpage has been sent, do any useful background |
| 346 | ** processing. |
| 347 | */ |
| 348 | g.cgiOutput = 2; |
| 349 | if( g.db!=0 && iReplyStatus==200 ){ |
| 350 | backoffice_check_if_needed(); |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | /* |
| 355 | ** Do a redirect request to the URL given in the argument. |
| 356 |
+1
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -944,7 +944,8 @@ | ||
| 944 | 944 | @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a> |
| 945 | 945 | @ </tr> |
| 946 | 946 | fossil_free(zAge); |
| 947 | 947 | } |
| 948 | 948 | @ </table></div> |
| 949 | + db_finalize(&q); | |
| 949 | 950 | style_footer(); |
| 950 | 951 | } |
| 951 | 952 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -944,7 +944,8 @@ | |
| 944 | @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a> |
| 945 | @ </tr> |
| 946 | fossil_free(zAge); |
| 947 | } |
| 948 | @ </table></div> |
| 949 | style_footer(); |
| 950 | } |
| 951 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -944,7 +944,8 @@ | |
| 944 | @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a> |
| 945 | @ </tr> |
| 946 | fossil_free(zAge); |
| 947 | } |
| 948 | @ </table></div> |
| 949 | db_finalize(&q); |
| 950 | style_footer(); |
| 951 | } |
| 952 |
+2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -2297,10 +2297,11 @@ | ||
| 2297 | 2297 | ** --host NAME specify hostname of the server |
| 2298 | 2298 | ** --https signal a request coming in via https |
| 2299 | 2299 | ** --in FILE Take input from FILE instead of standard input |
| 2300 | 2300 | ** --ipaddr ADDR Assume the request comes from the given IP address |
| 2301 | 2301 | ** --nocompress do not compress HTTP replies |
| 2302 | +** --nodelay omit backoffice processing if it would delay process exit | |
| 2302 | 2303 | ** --nojail drop root privilege but do not enter the chroot jail |
| 2303 | 2304 | ** --nossl signal that no SSL connections are available |
| 2304 | 2305 | ** --notfound URL use URL as "HTTP 404, object not found" page. |
| 2305 | 2306 | ** --out FILE write results to FILE instead of to standard output |
| 2306 | 2307 | ** --repolist If REPOSITORY is directory, URL "/" lists all repos |
| @@ -2363,10 +2364,11 @@ | ||
| 2363 | 2364 | g.httpOut = stdout; |
| 2364 | 2365 | } |
| 2365 | 2366 | zIpAddr = find_option("ipaddr",0,1); |
| 2366 | 2367 | useSCGI = find_option("scgi", 0, 0)!=0; |
| 2367 | 2368 | zAltBase = find_option("baseurl", 0, 1); |
| 2369 | + if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay(); | |
| 2368 | 2370 | if( zAltBase ) set_base_url(zAltBase); |
| 2369 | 2371 | if( find_option("https",0,0)!=0 ){ |
| 2370 | 2372 | zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ |
| 2371 | 2373 | cgi_replace_parameter("HTTPS","on"); |
| 2372 | 2374 | } |
| 2373 | 2375 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2297,10 +2297,11 @@ | |
| 2297 | ** --host NAME specify hostname of the server |
| 2298 | ** --https signal a request coming in via https |
| 2299 | ** --in FILE Take input from FILE instead of standard input |
| 2300 | ** --ipaddr ADDR Assume the request comes from the given IP address |
| 2301 | ** --nocompress do not compress HTTP replies |
| 2302 | ** --nojail drop root privilege but do not enter the chroot jail |
| 2303 | ** --nossl signal that no SSL connections are available |
| 2304 | ** --notfound URL use URL as "HTTP 404, object not found" page. |
| 2305 | ** --out FILE write results to FILE instead of to standard output |
| 2306 | ** --repolist If REPOSITORY is directory, URL "/" lists all repos |
| @@ -2363,10 +2364,11 @@ | |
| 2363 | g.httpOut = stdout; |
| 2364 | } |
| 2365 | zIpAddr = find_option("ipaddr",0,1); |
| 2366 | useSCGI = find_option("scgi", 0, 0)!=0; |
| 2367 | zAltBase = find_option("baseurl", 0, 1); |
| 2368 | if( zAltBase ) set_base_url(zAltBase); |
| 2369 | if( find_option("https",0,0)!=0 ){ |
| 2370 | zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ |
| 2371 | cgi_replace_parameter("HTTPS","on"); |
| 2372 | } |
| 2373 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2297,10 +2297,11 @@ | |
| 2297 | ** --host NAME specify hostname of the server |
| 2298 | ** --https signal a request coming in via https |
| 2299 | ** --in FILE Take input from FILE instead of standard input |
| 2300 | ** --ipaddr ADDR Assume the request comes from the given IP address |
| 2301 | ** --nocompress do not compress HTTP replies |
| 2302 | ** --nodelay omit backoffice processing if it would delay process exit |
| 2303 | ** --nojail drop root privilege but do not enter the chroot jail |
| 2304 | ** --nossl signal that no SSL connections are available |
| 2305 | ** --notfound URL use URL as "HTTP 404, object not found" page. |
| 2306 | ** --out FILE write results to FILE instead of to standard output |
| 2307 | ** --repolist If REPOSITORY is directory, URL "/" lists all repos |
| @@ -2363,10 +2364,11 @@ | |
| 2364 | g.httpOut = stdout; |
| 2365 | } |
| 2366 | zIpAddr = find_option("ipaddr",0,1); |
| 2367 | useSCGI = find_option("scgi", 0, 0)!=0; |
| 2368 | zAltBase = find_option("baseurl", 0, 1); |
| 2369 | if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay(); |
| 2370 | if( zAltBase ) set_base_url(zAltBase); |
| 2371 | if( find_option("https",0,0)!=0 ){ |
| 2372 | zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ |
| 2373 | cgi_replace_parameter("HTTPS","on"); |
| 2374 | } |
| 2375 |
+1
-1
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -1081,11 +1081,11 @@ | ||
| 1081 | 1081 | static int once = 0; |
| 1082 | 1082 | |
| 1083 | 1083 | if( once ) exit(1); |
| 1084 | 1084 | once = 1; |
| 1085 | 1085 | mainInFatalError = 1; |
| 1086 | - db_force_rollback(); | |
| 1086 | + /* db_force_rollback(); */ | |
| 1087 | 1087 | va_start(ap, zFormat); |
| 1088 | 1088 | sqlite3_vsnprintf(sizeof(z),z,zFormat, ap); |
| 1089 | 1089 | va_end(ap); |
| 1090 | 1090 | if( g.fAnyTrace ){ |
| 1091 | 1091 | fprintf(stderr, "/***** panic on %d *****/\n", getpid()); |
| 1092 | 1092 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -1081,11 +1081,11 @@ | |
| 1081 | static int once = 0; |
| 1082 | |
| 1083 | if( once ) exit(1); |
| 1084 | once = 1; |
| 1085 | mainInFatalError = 1; |
| 1086 | db_force_rollback(); |
| 1087 | va_start(ap, zFormat); |
| 1088 | sqlite3_vsnprintf(sizeof(z),z,zFormat, ap); |
| 1089 | va_end(ap); |
| 1090 | if( g.fAnyTrace ){ |
| 1091 | fprintf(stderr, "/***** panic on %d *****/\n", getpid()); |
| 1092 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -1081,11 +1081,11 @@ | |
| 1081 | static int once = 0; |
| 1082 | |
| 1083 | if( once ) exit(1); |
| 1084 | once = 1; |
| 1085 | mainInFatalError = 1; |
| 1086 | /* db_force_rollback(); */ |
| 1087 | va_start(ap, zFormat); |
| 1088 | sqlite3_vsnprintf(sizeof(z),z,zFormat, ap); |
| 1089 | va_end(ap); |
| 1090 | if( g.fAnyTrace ){ |
| 1091 | fprintf(stderr, "/***** panic on %d *****/\n", getpid()); |
| 1092 |