Fossil

Check-in [af7d67c6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix the separate-process backoffice so that it works smoothly on linux. Still work to be done on Windows.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | fork-backoffice
Files: files | file ages | folders
SHA3-256: af7d67c6a25f5af06284b2e0dbc8296bca9338631053ba2e207181394d4de867
User & Date: drh 2018-08-07 17:48:56.598
Context
2018-08-07
18:28
Improvements to comments. No code changes. ... (Closed-Leaf check-in: 1b54dd79 user: drh tags: fork-backoffice)
17:48
Fix the separate-process backoffice so that it works smoothly on linux. Still work to be done on Windows. ... (check-in: af7d67c6 user: drh tags: fork-backoffice)
15:50
Use the fork() system call (when available) to start backoffice, in an attempt to avoid unseemly delays in upstream. ... (check-in: a4b59c32 user: drh tags: fork-backoffice)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/backoffice.c.
89
90
91
92
93
94
95













96
97
98
99
100
101
102
** backoffice_run_if_needed() will consult this variable to see if it
** should be a no-op.
*/
static char *backofficeDb = 0;

/* End of state variables
****************************************************************************/














/*
** Parse a unsigned 64-bit integer from a string.  Return a pointer
** to the character of z[] that occurs after the integer.
*/
static const char *backofficeParseInt(const char *z, sqlite3_uint64 *pVal){
  *pVal = 0;







>
>
>
>
>
>
>
>
>
>
>
>
>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
** backoffice_run_if_needed() will consult this variable to see if it
** should be a no-op.
*/
static char *backofficeDb = 0;

/* End of state variables
****************************************************************************/

/*
** Do not allow backoffice processes to sleep waiting on a timeslot.
** They must either do their work immediately or exit.
**
** In a perfect world, this interface would not exist, as there would
** never be a problem with waiting backoffice threads.  But in some cases
** a backoffice will delay a UI thread, so we don't want them to run for
** longer than needed.
*/
void backoffice_no_delay(void){
  backofficeNoDelay = 1;
}

/*
** Parse a unsigned 64-bit integer from a string.  Return a pointer
** to the character of z[] that occurs after the integer.
*/
static const char *backofficeParseInt(const char *z, sqlite3_uint64 *pVal){
  *pVal = 0;
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
  if( g.repositoryOpen ) return;
#if !defined(_WIN32)
  {
    pid_t pid = fork();
    if( pid>0 ){
      /* This is the parent in a successful fork().  Return immediately. */
      if( g.fAnyTrace ){
        fprintf(stderr, "/***** Backoffice Child Creates as %d *****/\n",

                        (int)pid);
      }
      return;
    }
    if( pid==0 ){
      /* This is the child of a successful fork().  Run backoffice. */
      db_open_repository(backofficeDb);
      backofficeDb = "x";







|
>
|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  if( g.repositoryOpen ) return;
#if !defined(_WIN32)
  {
    pid_t pid = fork();
    if( pid>0 ){
      /* This is the parent in a successful fork().  Return immediately. */
      if( g.fAnyTrace ){
        fprintf(stderr, 
          "/***** Subprocess %d creates backoffice child %d *****/\n",
          getpid(), (int)pid);
      }
      return;
    }
    if( pid==0 ){
      /* This is the child of a successful fork().  Run backoffice. */
      db_open_repository(backofficeDb);
      backofficeDb = "x";
Changes to src/cgi.c.
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  fflush(g.httpOut);
  CGIDEBUG(("DONE\n"));

  /* After the webpage has been sent, do any useful background
  ** processing.
  */
  g.cgiOutput = 2;
  if( g.db!=0 && iReplyStatus==200 && !g.fSshClient ){
    fclose(g.httpOut);
#ifdef _WIN32
    g.httpOut = fossil_fopen("NUL", "wb");
#else
    g.httpOut = fossil_fopen("/dev/null", "wb");
#endif
    if( g.httpOut==0 ){
      fossil_warning("failed ot open /dev/null");
    }else{
      backoffice_check_if_needed();
    }
  }
}

/*
** Do a redirect request to the URL given in the argument.
**
** The URL must be relative to the base of the fossil server.







|
<
<
<
<
<
<
<
<
<
|
<







342
343
344
345
346
347
348
349









350

351
352
353
354
355
356
357
  fflush(g.httpOut);
  CGIDEBUG(("DONE\n"));

  /* After the webpage has been sent, do any useful background
  ** processing.
  */
  g.cgiOutput = 2;
  if( g.db!=0 && iReplyStatus==200 ){









    backoffice_check_if_needed();

  }
}

/*
** Do a redirect request to the URL given in the argument.
**
** The URL must be relative to the base of the fossil server.
Changes to src/forum.c.
942
943
944
945
946
947
948

949
950
    const char *zTitle = db_column_text(&q, 2);
    @ <tr><td>%h(zAge) ago</td>
    @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a>
    @ </tr>
    fossil_free(zAge);
  }
  @ </table></div>

  style_footer();
}







>


942
943
944
945
946
947
948
949
950
951
    const char *zTitle = db_column_text(&q, 2);
    @ <tr><td>%h(zAge) ago</td>
    @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a>
    @ </tr>
    fossil_free(zAge);
  }
  @ </table></div>
  db_finalize(&q);
  style_footer();
}
Changes to src/main.c.
2295
2296
2297
2298
2299
2300
2301

2302
2303
2304
2305
2306
2307
2308
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --localauth      enable automatic login for local connections
**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --in FILE        Take input from FILE instead of standard input
**   --ipaddr ADDR    Assume the request comes from the given IP address
**   --nocompress     do not compress HTTP replies

**   --nojail         drop root privilege but do not enter the chroot jail
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --out FILE       write results to FILE instead of to standard output
**   --repolist       If REPOSITORY is directory, URL "/" lists all repos
**   --scgi           Interpret input as SCGI rather than HTTP
**   --skin LABEL     Use override skin LABEL







>







2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --localauth      enable automatic login for local connections
**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --in FILE        Take input from FILE instead of standard input
**   --ipaddr ADDR    Assume the request comes from the given IP address
**   --nocompress     do not compress HTTP replies
**   --nodelay        omit backoffice processing if it would delay process exit
**   --nojail         drop root privilege but do not enter the chroot jail
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --out FILE       write results to FILE instead of to standard output
**   --repolist       If REPOSITORY is directory, URL "/" lists all repos
**   --scgi           Interpret input as SCGI rather than HTTP
**   --skin LABEL     Use override skin LABEL
2361
2362
2363
2364
2365
2366
2367

2368
2369
2370
2371
2372
2373
2374
    if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
  }else{
    g.httpOut = stdout;
  }
  zIpAddr = find_option("ipaddr",0,1);
  useSCGI = find_option("scgi", 0, 0)!=0;
  zAltBase = find_option("baseurl", 0, 1);

  if( zAltBase ) set_base_url(zAltBase);
  if( find_option("https",0,0)!=0 ){
    zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
    cgi_replace_parameter("HTTPS","on");
  }
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);







>







2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
    if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
  }else{
    g.httpOut = stdout;
  }
  zIpAddr = find_option("ipaddr",0,1);
  useSCGI = find_option("scgi", 0, 0)!=0;
  zAltBase = find_option("baseurl", 0, 1);
  if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
  if( zAltBase ) set_base_url(zAltBase);
  if( find_option("https",0,0)!=0 ){
    zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
    cgi_replace_parameter("HTTPS","on");
  }
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
Changes to src/printf.c.
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
  int rc = 1;
  char z[1000];
  static int once = 0;

  if( once ) exit(1);
  once = 1;
  mainInFatalError = 1;
  db_force_rollback();
  va_start(ap, zFormat);
  sqlite3_vsnprintf(sizeof(z),z,zFormat, ap);
  va_end(ap);
  if( g.fAnyTrace ){
    fprintf(stderr, "/***** panic on %d *****/\n", getpid());
  }
  fossil_errorlog("panic: %s", z);







|







1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
  int rc = 1;
  char z[1000];
  static int once = 0;

  if( once ) exit(1);
  once = 1;
  mainInFatalError = 1;
  /* db_force_rollback(); */
  va_start(ap, zFormat);
  sqlite3_vsnprintf(sizeof(z),z,zFormat, ap);
  va_end(ap);
  if( g.fAnyTrace ){
    fprintf(stderr, "/***** panic on %d *****/\n", getpid());
  }
  fossil_errorlog("panic: %s", z);