Fossil SCM

Use the fork() system call (when available) to start backoffice, in an attempt to avoid unseemly delays in upstream.

drh 2018-08-07 15:50 UTC trunk
Commit a4b59c320796b31166851b6ea5e3d5505f23ce15bd55f9e87caa2e27e961d4ff
+121 -32
--- src/backoffice.c
+++ src/backoffice.c
@@ -71,23 +71,30 @@
7171
sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
7272
sqlite3_uint64 tmNext; /* Expiration of the next lease */
7373
};
7474
#endif
7575
76
-/*
77
-** Set to prevent backoffice processing from every entering sleep or
76
+/***************************************************************************
77
+** Local state variables
78
+**
79
+** Set to prevent backoffice processing from ever entering sleep or
7880
** otherwise taking a long time to complete. Set this when a user-visible
7981
** process might need to wait for backoffice to complete.
8082
*/
8183
static int backofficeNoDelay = 0;
8284
83
-/*
84
-** Disable the backoffice
85
+/* This variable is set to the name of a database on which backoffice
86
+** should run if backoffice process is needed. It is set by the
87
+** backoffice_check_if_needed() routine which must be run while the database
88
+** file is open. Later, after the database is closed, the
89
+** backoffice_run_if_needed() will consult this variable to see if it
90
+** should be a no-op.
8591
*/
86
-void backoffice_no_delay(void){
87
- backofficeNoDelay = 1;
88
-}
92
+static char *backofficeDb = 0;
93
+
94
+/* End of state variables
95
+****************************************************************************/
8996
9097
/*
9198
** Parse a unsigned 64-bit integer from a string. Return a pointer
9299
** to the character of z[] that occurs after the integer.
93100
*/
@@ -205,36 +212,72 @@
205212
x, backofficeProcessExists(x),
206213
backofficeProcessDone(x));
207214
}
208215
}
209216
210
-/* This is the main public interface to the backoffice. A process invokes this
211
-** routine in an attempt to become the backoffice. If another process is
212
-** already working as the backoffice, this routine returns very quickly
213
-** without doing any work - allowing the other process to continue. But
214
-** if no other processes are currently operating as the backoffice, this
215
-** routine enters a loop to do background work periodically.
217
+/*
218
+** If backoffice processing is needed set the backofficeDb value to the
219
+** name of the database file. If no backoffice processing is needed,
220
+** this routine makes no changes to state.
216221
*/
217
-void backoffice_run(void){
222
+void backoffice_check_if_needed(void){
218223
Lease x;
219224
sqlite3_uint64 tmNow;
220
- sqlite3_uint64 idSelf;
221
- int lastWarning = 0;
222
- int warningDelay = 30;
223
- static int once = 0;
224
-
225
- if( once ){
226
- fossil_panic("multiple calls to backoffice_run()");
227
- }
228
- once = 1;
225
+
226
+ if( backofficeDb ) return;
227
+ if( g.zRepositoryName==0 ) return;
228
+ if( g.db==0 ) return;
229
+ tmNow = time(0);
230
+ backofficeReadLease(&x);
231
+ if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
232
+ /* Another backoffice process is already queued up to run. This
233
+ ** process does not need to do any backoffice work. */
234
+ return;
235
+ }else{
236
+ /* We need to run backup to be (at a minimum) on-deck */
237
+ backofficeDb = fossil_strdup(g.zRepositoryName);
238
+ }
239
+}
240
+
241
+/*
242
+** Check for errors prior to running backoffice_thread() or backoffice_run().
243
+*/
244
+static void backoffice_error_check_one(int *pOnce){
245
+ if( *pOnce ){
246
+ fossil_panic("multiple calls to backoffice()");
247
+ }
248
+ *pOnce = 1;
229249
if( g.db==0 ){
230250
fossil_panic("database not open for backoffice processing");
231251
}
232252
if( db_transaction_nesting_depth()!=0 ){
233253
fossil_panic("transaction %s not closed prior to backoffice processing",
234254
db_transaction_start_point());
235255
}
256
+}
257
+
258
+/* This is the main loop for backoffice processing.
259
+**
260
+** If others process is already working as the current backoffice and
261
+** the on-deck backoffice, then this routine returns very quickly
262
+** without doing any work.
263
+**
264
+** If no backoffice processes are running at all, this routine becomes
265
+** the main backoffice.
266
+**
267
+** If a primary backoffice is running, but a on-deck backoffice is
268
+** needed, this routine becomes that backoffice.
269
+*/
270
+static void backoffice_thread(void){
271
+ Lease x;
272
+ sqlite3_uint64 tmNow;
273
+ sqlite3_uint64 idSelf;
274
+ int lastWarning = 0;
275
+ int warningDelay = 30;
276
+ static int once = 0;
277
+
278
+ backoffice_error_check_one(&once);
236279
backofficeTimeout(BKOFCE_LEASE_TIME*2);
237280
idSelf = backofficeProcessId();
238281
while(1){
239282
tmNow = time(0);
240283
db_begin_write();
@@ -303,15 +346,61 @@
303346
void backoffice_work(void){
304347
email_backoffice(0);
305348
}
306349
307350
/*
308
-** COMMAND: test-backoffice
309
-**
310
-** Usage: test-backoffice
311
-**
312
-** Run backoffice processing
313
-*/
314
-void test_backoffice_command(void){
315
- db_find_and_open_repository(0,0);
316
- backoffice_run();
351
+** COMMAND: backoffice
352
+**
353
+** Usage: backoffice [-R repository]
354
+**
355
+** Run backoffice processing. This might be done by a cron job or
356
+** similar to make sure backoffice processing happens periodically.
357
+*/
358
+void backoffice_command(void){
359
+ verify_all_options();
360
+ db_find_and_open_repository(0,0);
361
+ backoffice_thread();
362
+}
363
+
364
+/*
365
+** This is the main interface to backoffice from the rest of the system.
366
+** This routine launches either backoffice_thread() directly or as a
367
+** subprocess.
368
+*/
369
+void backoffice_run_if_needed(void){
370
+ if( backofficeDb==0 ) return;
371
+ if( strcmp(backofficeDb,"x")==0 ) return;
372
+ if( g.db ) return;
373
+ if( g.repositoryOpen ) return;
374
+#if !defined(_WIN32)
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
+ db_open_repository(backofficeDb);
388
+ backofficeDb = "x";
389
+ backoffice_thread();
390
+ db_close(1);
391
+ if( g.fAnyTrace ){
392
+ fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid());
393
+ }
394
+ exit(0);
395
+ }
396
+ }
397
+#endif
398
+ /* Fork() failed or is unavailable. Run backoffice in this process, but
399
+ ** do so with the no-delay setting.
400
+ */
401
+ backofficeNoDelay = 1;
402
+ db_open_repository(backofficeDb);
403
+ backofficeDb = "x";
404
+ backoffice_thread();
405
+ db_close(1);
317406
}
318407
--- src/backoffice.c
+++ src/backoffice.c
@@ -71,23 +71,30 @@
71 sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
72 sqlite3_uint64 tmNext; /* Expiration of the next lease */
73 };
74 #endif
75
76 /*
77 ** Set to prevent backoffice processing from every entering sleep or
 
 
78 ** otherwise taking a long time to complete. Set this when a user-visible
79 ** process might need to wait for backoffice to complete.
80 */
81 static int backofficeNoDelay = 0;
82
83 /*
84 ** Disable the backoffice
 
 
 
 
85 */
86 void backoffice_no_delay(void){
87 backofficeNoDelay = 1;
88 }
 
89
90 /*
91 ** Parse a unsigned 64-bit integer from a string. Return a pointer
92 ** to the character of z[] that occurs after the integer.
93 */
@@ -205,36 +212,72 @@
205 x, backofficeProcessExists(x),
206 backofficeProcessDone(x));
207 }
208 }
209
210 /* This is the main public interface to the backoffice. A process invokes this
211 ** routine in an attempt to become the backoffice. If another process is
212 ** already working as the backoffice, this routine returns very quickly
213 ** without doing any work - allowing the other process to continue. But
214 ** if no other processes are currently operating as the backoffice, this
215 ** routine enters a loop to do background work periodically.
216 */
217 void backoffice_run(void){
218 Lease x;
219 sqlite3_uint64 tmNow;
220 sqlite3_uint64 idSelf;
221 int lastWarning = 0;
222 int warningDelay = 30;
223 static int once = 0;
224
225 if( once ){
226 fossil_panic("multiple calls to backoffice_run()");
227 }
228 once = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229 if( g.db==0 ){
230 fossil_panic("database not open for backoffice processing");
231 }
232 if( db_transaction_nesting_depth()!=0 ){
233 fossil_panic("transaction %s not closed prior to backoffice processing",
234 db_transaction_start_point());
235 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236 backofficeTimeout(BKOFCE_LEASE_TIME*2);
237 idSelf = backofficeProcessId();
238 while(1){
239 tmNow = time(0);
240 db_begin_write();
@@ -303,15 +346,61 @@
303 void backoffice_work(void){
304 email_backoffice(0);
305 }
306
307 /*
308 ** COMMAND: test-backoffice
309 **
310 ** Usage: test-backoffice
311 **
312 ** Run backoffice processing
313 */
314 void test_backoffice_command(void){
315 db_find_and_open_repository(0,0);
316 backoffice_run();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317 }
318
--- src/backoffice.c
+++ src/backoffice.c
@@ -71,23 +71,30 @@
71 sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
72 sqlite3_uint64 tmNext; /* Expiration of the next lease */
73 };
74 #endif
75
76 /***************************************************************************
77 ** Local state variables
78 **
79 ** Set to prevent backoffice processing from ever entering sleep or
80 ** otherwise taking a long time to complete. Set this when a user-visible
81 ** process might need to wait for backoffice to complete.
82 */
83 static int backofficeNoDelay = 0;
84
85 /* This variable is set to the name of a database on which backoffice
86 ** should run if backoffice process is needed. It is set by the
87 ** backoffice_check_if_needed() routine which must be run while the database
88 ** file is open. Later, after the database is closed, the
89 ** backoffice_run_if_needed() will consult this variable to see if it
90 ** should be a no-op.
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 */
@@ -205,36 +212,72 @@
212 x, backofficeProcessExists(x),
213 backofficeProcessDone(x));
214 }
215 }
216
217 /*
218 ** If backoffice processing is needed set the backofficeDb value to the
219 ** name of the database file. If no backoffice processing is needed,
220 ** this routine makes no changes to state.
 
 
221 */
222 void backoffice_check_if_needed(void){
223 Lease x;
224 sqlite3_uint64 tmNow;
225
226 if( backofficeDb ) return;
227 if( g.zRepositoryName==0 ) return;
228 if( g.db==0 ) return;
229 tmNow = time(0);
230 backofficeReadLease(&x);
231 if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
232 /* Another backoffice process is already queued up to run. This
233 ** process does not need to do any backoffice work. */
234 return;
235 }else{
236 /* We need to run backup to be (at a minimum) on-deck */
237 backofficeDb = fossil_strdup(g.zRepositoryName);
238 }
239 }
240
241 /*
242 ** Check for errors prior to running backoffice_thread() or backoffice_run().
243 */
244 static void backoffice_error_check_one(int *pOnce){
245 if( *pOnce ){
246 fossil_panic("multiple calls to backoffice()");
247 }
248 *pOnce = 1;
249 if( g.db==0 ){
250 fossil_panic("database not open for backoffice processing");
251 }
252 if( db_transaction_nesting_depth()!=0 ){
253 fossil_panic("transaction %s not closed prior to backoffice processing",
254 db_transaction_start_point());
255 }
256 }
257
258 /* This is the main loop for backoffice processing.
259 **
260 ** If others process is already working as the current backoffice and
261 ** the on-deck backoffice, then this routine returns very quickly
262 ** without doing any work.
263 **
264 ** If no backoffice processes are running at all, this routine becomes
265 ** the main backoffice.
266 **
267 ** If a primary backoffice is running, but a on-deck backoffice is
268 ** needed, this routine becomes that backoffice.
269 */
270 static void backoffice_thread(void){
271 Lease x;
272 sqlite3_uint64 tmNow;
273 sqlite3_uint64 idSelf;
274 int lastWarning = 0;
275 int warningDelay = 30;
276 static int once = 0;
277
278 backoffice_error_check_one(&once);
279 backofficeTimeout(BKOFCE_LEASE_TIME*2);
280 idSelf = backofficeProcessId();
281 while(1){
282 tmNow = time(0);
283 db_begin_write();
@@ -303,15 +346,61 @@
346 void backoffice_work(void){
347 email_backoffice(0);
348 }
349
350 /*
351 ** COMMAND: backoffice
352 **
353 ** Usage: backoffice [-R repository]
354 **
355 ** Run backoffice processing. This might be done by a cron job or
356 ** similar to make sure backoffice processing happens periodically.
357 */
358 void backoffice_command(void){
359 verify_all_options();
360 db_find_and_open_repository(0,0);
361 backoffice_thread();
362 }
363
364 /*
365 ** This is the main interface to backoffice from the rest of the system.
366 ** This routine launches either backoffice_thread() directly or as a
367 ** subprocess.
368 */
369 void backoffice_run_if_needed(void){
370 if( backofficeDb==0 ) return;
371 if( strcmp(backofficeDb,"x")==0 ) return;
372 if( g.db ) return;
373 if( g.repositoryOpen ) return;
374 #if !defined(_WIN32)
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 db_open_repository(backofficeDb);
388 backofficeDb = "x";
389 backoffice_thread();
390 db_close(1);
391 if( g.fAnyTrace ){
392 fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid());
393 }
394 exit(0);
395 }
396 }
397 #endif
398 /* Fork() failed or is unavailable. Run backoffice in this process, but
399 ** do so with the no-delay setting.
400 */
401 backofficeNoDelay = 1;
402 db_open_repository(backofficeDb);
403 backofficeDb = "x";
404 backoffice_thread();
405 db_close(1);
406 }
407
+121 -32
--- src/backoffice.c
+++ src/backoffice.c
@@ -71,23 +71,30 @@
7171
sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
7272
sqlite3_uint64 tmNext; /* Expiration of the next lease */
7373
};
7474
#endif
7575
76
-/*
77
-** Set to prevent backoffice processing from every entering sleep or
76
+/***************************************************************************
77
+** Local state variables
78
+**
79
+** Set to prevent backoffice processing from ever entering sleep or
7880
** otherwise taking a long time to complete. Set this when a user-visible
7981
** process might need to wait for backoffice to complete.
8082
*/
8183
static int backofficeNoDelay = 0;
8284
83
-/*
84
-** Disable the backoffice
85
+/* This variable is set to the name of a database on which backoffice
86
+** should run if backoffice process is needed. It is set by the
87
+** backoffice_check_if_needed() routine which must be run while the database
88
+** file is open. Later, after the database is closed, the
89
+** backoffice_run_if_needed() will consult this variable to see if it
90
+** should be a no-op.
8591
*/
86
-void backoffice_no_delay(void){
87
- backofficeNoDelay = 1;
88
-}
92
+static char *backofficeDb = 0;
93
+
94
+/* End of state variables
95
+****************************************************************************/
8996
9097
/*
9198
** Parse a unsigned 64-bit integer from a string. Return a pointer
9299
** to the character of z[] that occurs after the integer.
93100
*/
@@ -205,36 +212,72 @@
205212
x, backofficeProcessExists(x),
206213
backofficeProcessDone(x));
207214
}
208215
}
209216
210
-/* This is the main public interface to the backoffice. A process invokes this
211
-** routine in an attempt to become the backoffice. If another process is
212
-** already working as the backoffice, this routine returns very quickly
213
-** without doing any work - allowing the other process to continue. But
214
-** if no other processes are currently operating as the backoffice, this
215
-** routine enters a loop to do background work periodically.
217
+/*
218
+** If backoffice processing is needed set the backofficeDb value to the
219
+** name of the database file. If no backoffice processing is needed,
220
+** this routine makes no changes to state.
216221
*/
217
-void backoffice_run(void){
222
+void backoffice_check_if_needed(void){
218223
Lease x;
219224
sqlite3_uint64 tmNow;
220
- sqlite3_uint64 idSelf;
221
- int lastWarning = 0;
222
- int warningDelay = 30;
223
- static int once = 0;
224
-
225
- if( once ){
226
- fossil_panic("multiple calls to backoffice_run()");
227
- }
228
- once = 1;
225
+
226
+ if( backofficeDb ) return;
227
+ if( g.zRepositoryName==0 ) return;
228
+ if( g.db==0 ) return;
229
+ tmNow = time(0);
230
+ backofficeReadLease(&x);
231
+ if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
232
+ /* Another backoffice process is already queued up to run. This
233
+ ** process does not need to do any backoffice work. */
234
+ return;
235
+ }else{
236
+ /* We need to run backup to be (at a minimum) on-deck */
237
+ backofficeDb = fossil_strdup(g.zRepositoryName);
238
+ }
239
+}
240
+
241
+/*
242
+** Check for errors prior to running backoffice_thread() or backoffice_run().
243
+*/
244
+static void backoffice_error_check_one(int *pOnce){
245
+ if( *pOnce ){
246
+ fossil_panic("multiple calls to backoffice()");
247
+ }
248
+ *pOnce = 1;
229249
if( g.db==0 ){
230250
fossil_panic("database not open for backoffice processing");
231251
}
232252
if( db_transaction_nesting_depth()!=0 ){
233253
fossil_panic("transaction %s not closed prior to backoffice processing",
234254
db_transaction_start_point());
235255
}
256
+}
257
+
258
+/* This is the main loop for backoffice processing.
259
+**
260
+** If others process is already working as the current backoffice and
261
+** the on-deck backoffice, then this routine returns very quickly
262
+** without doing any work.
263
+**
264
+** If no backoffice processes are running at all, this routine becomes
265
+** the main backoffice.
266
+**
267
+** If a primary backoffice is running, but a on-deck backoffice is
268
+** needed, this routine becomes that backoffice.
269
+*/
270
+static void backoffice_thread(void){
271
+ Lease x;
272
+ sqlite3_uint64 tmNow;
273
+ sqlite3_uint64 idSelf;
274
+ int lastWarning = 0;
275
+ int warningDelay = 30;
276
+ static int once = 0;
277
+
278
+ backoffice_error_check_one(&once);
236279
backofficeTimeout(BKOFCE_LEASE_TIME*2);
237280
idSelf = backofficeProcessId();
238281
while(1){
239282
tmNow = time(0);
240283
db_begin_write();
@@ -303,15 +346,61 @@
303346
void backoffice_work(void){
304347
email_backoffice(0);
305348
}
306349
307350
/*
308
-** COMMAND: test-backoffice
309
-**
310
-** Usage: test-backoffice
311
-**
312
-** Run backoffice processing
313
-*/
314
-void test_backoffice_command(void){
315
- db_find_and_open_repository(0,0);
316
- backoffice_run();
351
+** COMMAND: backoffice
352
+**
353
+** Usage: backoffice [-R repository]
354
+**
355
+** Run backoffice processing. This might be done by a cron job or
356
+** similar to make sure backoffice processing happens periodically.
357
+*/
358
+void backoffice_command(void){
359
+ verify_all_options();
360
+ db_find_and_open_repository(0,0);
361
+ backoffice_thread();
362
+}
363
+
364
+/*
365
+** This is the main interface to backoffice from the rest of the system.
366
+** This routine launches either backoffice_thread() directly or as a
367
+** subprocess.
368
+*/
369
+void backoffice_run_if_needed(void){
370
+ if( backofficeDb==0 ) return;
371
+ if( strcmp(backofficeDb,"x")==0 ) return;
372
+ if( g.db ) return;
373
+ if( g.repositoryOpen ) return;
374
+#if !defined(_WIN32)
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
+ db_open_repository(backofficeDb);
388
+ backofficeDb = "x";
389
+ backoffice_thread();
390
+ db_close(1);
391
+ if( g.fAnyTrace ){
392
+ fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid());
393
+ }
394
+ exit(0);
395
+ }
396
+ }
397
+#endif
398
+ /* Fork() failed or is unavailable. Run backoffice in this process, but
399
+ ** do so with the no-delay setting.
400
+ */
401
+ backofficeNoDelay = 1;
402
+ db_open_repository(backofficeDb);
403
+ backofficeDb = "x";
404
+ backoffice_thread();
405
+ db_close(1);
317406
}
318407
--- src/backoffice.c
+++ src/backoffice.c
@@ -71,23 +71,30 @@
71 sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
72 sqlite3_uint64 tmNext; /* Expiration of the next lease */
73 };
74 #endif
75
76 /*
77 ** Set to prevent backoffice processing from every entering sleep or
 
 
78 ** otherwise taking a long time to complete. Set this when a user-visible
79 ** process might need to wait for backoffice to complete.
80 */
81 static int backofficeNoDelay = 0;
82
83 /*
84 ** Disable the backoffice
 
 
 
 
85 */
86 void backoffice_no_delay(void){
87 backofficeNoDelay = 1;
88 }
 
89
90 /*
91 ** Parse a unsigned 64-bit integer from a string. Return a pointer
92 ** to the character of z[] that occurs after the integer.
93 */
@@ -205,36 +212,72 @@
205 x, backofficeProcessExists(x),
206 backofficeProcessDone(x));
207 }
208 }
209
210 /* This is the main public interface to the backoffice. A process invokes this
211 ** routine in an attempt to become the backoffice. If another process is
212 ** already working as the backoffice, this routine returns very quickly
213 ** without doing any work - allowing the other process to continue. But
214 ** if no other processes are currently operating as the backoffice, this
215 ** routine enters a loop to do background work periodically.
216 */
217 void backoffice_run(void){
218 Lease x;
219 sqlite3_uint64 tmNow;
220 sqlite3_uint64 idSelf;
221 int lastWarning = 0;
222 int warningDelay = 30;
223 static int once = 0;
224
225 if( once ){
226 fossil_panic("multiple calls to backoffice_run()");
227 }
228 once = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229 if( g.db==0 ){
230 fossil_panic("database not open for backoffice processing");
231 }
232 if( db_transaction_nesting_depth()!=0 ){
233 fossil_panic("transaction %s not closed prior to backoffice processing",
234 db_transaction_start_point());
235 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236 backofficeTimeout(BKOFCE_LEASE_TIME*2);
237 idSelf = backofficeProcessId();
238 while(1){
239 tmNow = time(0);
240 db_begin_write();
@@ -303,15 +346,61 @@
303 void backoffice_work(void){
304 email_backoffice(0);
305 }
306
307 /*
308 ** COMMAND: test-backoffice
309 **
310 ** Usage: test-backoffice
311 **
312 ** Run backoffice processing
313 */
314 void test_backoffice_command(void){
315 db_find_and_open_repository(0,0);
316 backoffice_run();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317 }
318
--- src/backoffice.c
+++ src/backoffice.c
@@ -71,23 +71,30 @@
71 sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
72 sqlite3_uint64 tmNext; /* Expiration of the next lease */
73 };
74 #endif
75
76 /***************************************************************************
77 ** Local state variables
78 **
79 ** Set to prevent backoffice processing from ever entering sleep or
80 ** otherwise taking a long time to complete. Set this when a user-visible
81 ** process might need to wait for backoffice to complete.
82 */
83 static int backofficeNoDelay = 0;
84
85 /* This variable is set to the name of a database on which backoffice
86 ** should run if backoffice process is needed. It is set by the
87 ** backoffice_check_if_needed() routine which must be run while the database
88 ** file is open. Later, after the database is closed, the
89 ** backoffice_run_if_needed() will consult this variable to see if it
90 ** should be a no-op.
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 */
@@ -205,36 +212,72 @@
212 x, backofficeProcessExists(x),
213 backofficeProcessDone(x));
214 }
215 }
216
217 /*
218 ** If backoffice processing is needed set the backofficeDb value to the
219 ** name of the database file. If no backoffice processing is needed,
220 ** this routine makes no changes to state.
 
 
221 */
222 void backoffice_check_if_needed(void){
223 Lease x;
224 sqlite3_uint64 tmNow;
225
226 if( backofficeDb ) return;
227 if( g.zRepositoryName==0 ) return;
228 if( g.db==0 ) return;
229 tmNow = time(0);
230 backofficeReadLease(&x);
231 if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
232 /* Another backoffice process is already queued up to run. This
233 ** process does not need to do any backoffice work. */
234 return;
235 }else{
236 /* We need to run backup to be (at a minimum) on-deck */
237 backofficeDb = fossil_strdup(g.zRepositoryName);
238 }
239 }
240
241 /*
242 ** Check for errors prior to running backoffice_thread() or backoffice_run().
243 */
244 static void backoffice_error_check_one(int *pOnce){
245 if( *pOnce ){
246 fossil_panic("multiple calls to backoffice()");
247 }
248 *pOnce = 1;
249 if( g.db==0 ){
250 fossil_panic("database not open for backoffice processing");
251 }
252 if( db_transaction_nesting_depth()!=0 ){
253 fossil_panic("transaction %s not closed prior to backoffice processing",
254 db_transaction_start_point());
255 }
256 }
257
258 /* This is the main loop for backoffice processing.
259 **
260 ** If others process is already working as the current backoffice and
261 ** the on-deck backoffice, then this routine returns very quickly
262 ** without doing any work.
263 **
264 ** If no backoffice processes are running at all, this routine becomes
265 ** the main backoffice.
266 **
267 ** If a primary backoffice is running, but a on-deck backoffice is
268 ** needed, this routine becomes that backoffice.
269 */
270 static void backoffice_thread(void){
271 Lease x;
272 sqlite3_uint64 tmNow;
273 sqlite3_uint64 idSelf;
274 int lastWarning = 0;
275 int warningDelay = 30;
276 static int once = 0;
277
278 backoffice_error_check_one(&once);
279 backofficeTimeout(BKOFCE_LEASE_TIME*2);
280 idSelf = backofficeProcessId();
281 while(1){
282 tmNow = time(0);
283 db_begin_write();
@@ -303,15 +346,61 @@
346 void backoffice_work(void){
347 email_backoffice(0);
348 }
349
350 /*
351 ** COMMAND: backoffice
352 **
353 ** Usage: backoffice [-R repository]
354 **
355 ** Run backoffice processing. This might be done by a cron job or
356 ** similar to make sure backoffice processing happens periodically.
357 */
358 void backoffice_command(void){
359 verify_all_options();
360 db_find_and_open_repository(0,0);
361 backoffice_thread();
362 }
363
364 /*
365 ** This is the main interface to backoffice from the rest of the system.
366 ** This routine launches either backoffice_thread() directly or as a
367 ** subprocess.
368 */
369 void backoffice_run_if_needed(void){
370 if( backofficeDb==0 ) return;
371 if( strcmp(backofficeDb,"x")==0 ) return;
372 if( g.db ) return;
373 if( g.repositoryOpen ) return;
374 #if !defined(_WIN32)
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 db_open_repository(backofficeDb);
388 backofficeDb = "x";
389 backoffice_thread();
390 db_close(1);
391 if( g.fAnyTrace ){
392 fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid());
393 }
394 exit(0);
395 }
396 }
397 #endif
398 /* Fork() failed or is unavailable. Run backoffice in this process, but
399 ** do so with the no-delay setting.
400 */
401 backofficeNoDelay = 1;
402 db_open_repository(backofficeDb);
403 backofficeDb = "x";
404 backoffice_thread();
405 db_close(1);
406 }
407
+1 -1
--- src/cgi.c
+++ src/cgi.c
@@ -354,11 +354,11 @@
354354
g.httpOut = fossil_fopen("/dev/null", "wb");
355355
#endif
356356
if( g.httpOut==0 ){
357357
fossil_warning("failed ot open /dev/null");
358358
}else{
359
- backoffice_run();
359
+ backoffice_check_if_needed();
360360
}
361361
}
362362
}
363363
364364
/*
365365
--- src/cgi.c
+++ src/cgi.c
@@ -354,11 +354,11 @@
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_run();
360 }
361 }
362 }
363
364 /*
365
--- src/cgi.c
+++ src/cgi.c
@@ -354,11 +354,11 @@
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
+1 -1
--- src/cgi.c
+++ src/cgi.c
@@ -354,11 +354,11 @@
354354
g.httpOut = fossil_fopen("/dev/null", "wb");
355355
#endif
356356
if( g.httpOut==0 ){
357357
fossil_warning("failed ot open /dev/null");
358358
}else{
359
- backoffice_run();
359
+ backoffice_check_if_needed();
360360
}
361361
}
362362
}
363363
364364
/*
365365
--- src/cgi.c
+++ src/cgi.c
@@ -354,11 +354,11 @@
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_run();
360 }
361 }
362 }
363
364 /*
365
--- src/cgi.c
+++ src/cgi.c
@@ -354,11 +354,11 @@
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
+1
--- src/db.c
+++ src/db.c
@@ -1880,10 +1880,11 @@
18801880
}
18811881
g.repositoryOpen = 0;
18821882
g.localOpen = 0;
18831883
assert( g.dbConfig==0 );
18841884
assert( g.zConfigDbName==0 );
1885
+ backoffice_run_if_needed();
18851886
}
18861887
18871888
/*
18881889
** Close the database as quickly as possible without unnecessary processing.
18891890
*/
18901891
--- src/db.c
+++ src/db.c
@@ -1880,10 +1880,11 @@
1880 }
1881 g.repositoryOpen = 0;
1882 g.localOpen = 0;
1883 assert( g.dbConfig==0 );
1884 assert( g.zConfigDbName==0 );
 
1885 }
1886
1887 /*
1888 ** Close the database as quickly as possible without unnecessary processing.
1889 */
1890
--- src/db.c
+++ src/db.c
@@ -1880,10 +1880,11 @@
1880 }
1881 g.repositoryOpen = 0;
1882 g.localOpen = 0;
1883 assert( g.dbConfig==0 );
1884 assert( g.zConfigDbName==0 );
1885 backoffice_run_if_needed();
1886 }
1887
1888 /*
1889 ** Close the database as quickly as possible without unnecessary processing.
1890 */
1891
+1
--- src/db.c
+++ src/db.c
@@ -1880,10 +1880,11 @@
18801880
}
18811881
g.repositoryOpen = 0;
18821882
g.localOpen = 0;
18831883
assert( g.dbConfig==0 );
18841884
assert( g.zConfigDbName==0 );
1885
+ backoffice_run_if_needed();
18851886
}
18861887
18871888
/*
18881889
** Close the database as quickly as possible without unnecessary processing.
18891890
*/
18901891
--- src/db.c
+++ src/db.c
@@ -1880,10 +1880,11 @@
1880 }
1881 g.repositoryOpen = 0;
1882 g.localOpen = 0;
1883 assert( g.dbConfig==0 );
1884 assert( g.zConfigDbName==0 );
 
1885 }
1886
1887 /*
1888 ** Close the database as quickly as possible without unnecessary processing.
1889 */
1890
--- src/db.c
+++ src/db.c
@@ -1880,10 +1880,11 @@
1880 }
1881 g.repositoryOpen = 0;
1882 g.localOpen = 0;
1883 assert( g.dbConfig==0 );
1884 assert( g.zConfigDbName==0 );
1885 backoffice_run_if_needed();
1886 }
1887
1888 /*
1889 ** Close the database as quickly as possible without unnecessary processing.
1890 */
1891
--- src/http_transport.c
+++ src/http_transport.c
@@ -270,11 +270,11 @@
270270
void transport_flip(UrlData *pUrlData){
271271
if( pUrlData->isFile ){
272272
char *zCmd;
273273
fclose(transport.pFile);
274274
zCmd = mprintf("\"%s\" http --in \"%s\" --out \"%s\" --ipaddr 127.0.0.1"
275
- " \"%s\" --localauth --nodelay",
275
+ " \"%s\" --localauth",
276276
g.nameOfExe, transport.zOutFile, transport.zInFile, pUrlData->name
277277
);
278278
fossil_system(zCmd);
279279
free(zCmd);
280280
transport.pFile = fossil_fopen(transport.zInFile, "rb");
281281
--- src/http_transport.c
+++ src/http_transport.c
@@ -270,11 +270,11 @@
270 void transport_flip(UrlData *pUrlData){
271 if( pUrlData->isFile ){
272 char *zCmd;
273 fclose(transport.pFile);
274 zCmd = mprintf("\"%s\" http --in \"%s\" --out \"%s\" --ipaddr 127.0.0.1"
275 " \"%s\" --localauth --nodelay",
276 g.nameOfExe, transport.zOutFile, transport.zInFile, pUrlData->name
277 );
278 fossil_system(zCmd);
279 free(zCmd);
280 transport.pFile = fossil_fopen(transport.zInFile, "rb");
281
--- src/http_transport.c
+++ src/http_transport.c
@@ -270,11 +270,11 @@
270 void transport_flip(UrlData *pUrlData){
271 if( pUrlData->isFile ){
272 char *zCmd;
273 fclose(transport.pFile);
274 zCmd = mprintf("\"%s\" http --in \"%s\" --out \"%s\" --ipaddr 127.0.0.1"
275 " \"%s\" --localauth",
276 g.nameOfExe, transport.zOutFile, transport.zInFile, pUrlData->name
277 );
278 fossil_system(zCmd);
279 free(zCmd);
280 transport.pFile = fossil_fopen(transport.zInFile, "rb");
281
-2
--- src/main.c
+++ src/main.c
@@ -2297,11 +2297,10 @@
22972297
** --host NAME specify hostname of the server
22982298
** --https signal a request coming in via https
22992299
** --in FILE Take input from FILE instead of standard input
23002300
** --ipaddr ADDR Assume the request comes from the given IP address
23012301
** --nocompress do not compress HTTP replies
2302
-** --nodelay omit backoffice processing if it would delay process exit
23032302
** --nojail drop root privilege but do not enter the chroot jail
23042303
** --nossl signal that no SSL connections are available
23052304
** --notfound URL use URL as "HTTP 404, object not found" page.
23062305
** --out FILE write results to FILE instead of to standard output
23072306
** --repolist If REPOSITORY is directory, URL "/" lists all repos
@@ -2364,11 +2363,10 @@
23642363
g.httpOut = stdout;
23652364
}
23662365
zIpAddr = find_option("ipaddr",0,1);
23672366
useSCGI = find_option("scgi", 0, 0)!=0;
23682367
zAltBase = find_option("baseurl", 0, 1);
2369
- if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
23702368
if( zAltBase ) set_base_url(zAltBase);
23712369
if( find_option("https",0,0)!=0 ){
23722370
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
23732371
cgi_replace_parameter("HTTPS","on");
23742372
}
23752373
--- src/main.c
+++ src/main.c
@@ -2297,11 +2297,10 @@
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
@@ -2364,11 +2363,10 @@
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
--- src/main.c
+++ src/main.c
@@ -2297,11 +2297,10 @@
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
@@ -2364,11 +2363,10 @@
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
-2
--- src/main.c
+++ src/main.c
@@ -2297,11 +2297,10 @@
22972297
** --host NAME specify hostname of the server
22982298
** --https signal a request coming in via https
22992299
** --in FILE Take input from FILE instead of standard input
23002300
** --ipaddr ADDR Assume the request comes from the given IP address
23012301
** --nocompress do not compress HTTP replies
2302
-** --nodelay omit backoffice processing if it would delay process exit
23032302
** --nojail drop root privilege but do not enter the chroot jail
23042303
** --nossl signal that no SSL connections are available
23052304
** --notfound URL use URL as "HTTP 404, object not found" page.
23062305
** --out FILE write results to FILE instead of to standard output
23072306
** --repolist If REPOSITORY is directory, URL "/" lists all repos
@@ -2364,11 +2363,10 @@
23642363
g.httpOut = stdout;
23652364
}
23662365
zIpAddr = find_option("ipaddr",0,1);
23672366
useSCGI = find_option("scgi", 0, 0)!=0;
23682367
zAltBase = find_option("baseurl", 0, 1);
2369
- if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
23702368
if( zAltBase ) set_base_url(zAltBase);
23712369
if( find_option("https",0,0)!=0 ){
23722370
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
23732371
cgi_replace_parameter("HTTPS","on");
23742372
}
23752373
--- src/main.c
+++ src/main.c
@@ -2297,11 +2297,10 @@
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
@@ -2364,11 +2363,10 @@
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
--- src/main.c
+++ src/main.c
@@ -2297,11 +2297,10 @@
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
@@ -2364,11 +2363,10 @@
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
+2 -2
--- src/winhttp.c
+++ src/winhttp.c
@@ -405,11 +405,11 @@
405405
aux = fossil_fopen(zCmdFName, "wb");
406406
if( aux==0 ) goto end_request;
407407
fwrite(zCmd, 1, strlen(zCmd), aux);
408408
409409
sqlite3_snprintf(sizeof(zCmd), zCmd,
410
- "\"%s\" http -args \"%s\" --nossl --nodelay%s",
410
+ "\"%s\" http -args \"%s\" --nossl%s",
411411
g.nameOfExe, zCmdFName, p->zOptions
412412
);
413413
in = fossil_fopen(zReplyFName, "w+b");
414414
fflush(out);
415415
fflush(aux);
@@ -476,11 +476,11 @@
476476
}
477477
assert( g.zRepositoryName && g.zRepositoryName[0] );
478478
zIp = SocketAddr_toString(&p->addr);
479479
sqlite3_snprintf(sizeof(zCmd), zCmd,
480480
"\"%s\" http --in \"%s\" --out \"%s\" --ipaddr %s \"%s\""
481
- " --scgi --nossl --nodelay%s",
481
+ " --scgi --nossl%s",
482482
g.nameOfExe, zRequestFName, zReplyFName, zIp,
483483
g.zRepositoryName, p->zOptions
484484
);
485485
fossil_free(zIp);
486486
in = fossil_fopen(zReplyFName, "w+b");
487487
--- src/winhttp.c
+++ src/winhttp.c
@@ -405,11 +405,11 @@
405 aux = fossil_fopen(zCmdFName, "wb");
406 if( aux==0 ) goto end_request;
407 fwrite(zCmd, 1, strlen(zCmd), aux);
408
409 sqlite3_snprintf(sizeof(zCmd), zCmd,
410 "\"%s\" http -args \"%s\" --nossl --nodelay%s",
411 g.nameOfExe, zCmdFName, p->zOptions
412 );
413 in = fossil_fopen(zReplyFName, "w+b");
414 fflush(out);
415 fflush(aux);
@@ -476,11 +476,11 @@
476 }
477 assert( g.zRepositoryName && g.zRepositoryName[0] );
478 zIp = SocketAddr_toString(&p->addr);
479 sqlite3_snprintf(sizeof(zCmd), zCmd,
480 "\"%s\" http --in \"%s\" --out \"%s\" --ipaddr %s \"%s\""
481 " --scgi --nossl --nodelay%s",
482 g.nameOfExe, zRequestFName, zReplyFName, zIp,
483 g.zRepositoryName, p->zOptions
484 );
485 fossil_free(zIp);
486 in = fossil_fopen(zReplyFName, "w+b");
487
--- src/winhttp.c
+++ src/winhttp.c
@@ -405,11 +405,11 @@
405 aux = fossil_fopen(zCmdFName, "wb");
406 if( aux==0 ) goto end_request;
407 fwrite(zCmd, 1, strlen(zCmd), aux);
408
409 sqlite3_snprintf(sizeof(zCmd), zCmd,
410 "\"%s\" http -args \"%s\" --nossl%s",
411 g.nameOfExe, zCmdFName, p->zOptions
412 );
413 in = fossil_fopen(zReplyFName, "w+b");
414 fflush(out);
415 fflush(aux);
@@ -476,11 +476,11 @@
476 }
477 assert( g.zRepositoryName && g.zRepositoryName[0] );
478 zIp = SocketAddr_toString(&p->addr);
479 sqlite3_snprintf(sizeof(zCmd), zCmd,
480 "\"%s\" http --in \"%s\" --out \"%s\" --ipaddr %s \"%s\""
481 " --scgi --nossl%s",
482 g.nameOfExe, zRequestFName, zReplyFName, zIp,
483 g.zRepositoryName, p->zOptions
484 );
485 fossil_free(zIp);
486 in = fossil_fopen(zReplyFName, "w+b");
487
+2 -2
--- src/winhttp.c
+++ src/winhttp.c
@@ -405,11 +405,11 @@
405405
aux = fossil_fopen(zCmdFName, "wb");
406406
if( aux==0 ) goto end_request;
407407
fwrite(zCmd, 1, strlen(zCmd), aux);
408408
409409
sqlite3_snprintf(sizeof(zCmd), zCmd,
410
- "\"%s\" http -args \"%s\" --nossl --nodelay%s",
410
+ "\"%s\" http -args \"%s\" --nossl%s",
411411
g.nameOfExe, zCmdFName, p->zOptions
412412
);
413413
in = fossil_fopen(zReplyFName, "w+b");
414414
fflush(out);
415415
fflush(aux);
@@ -476,11 +476,11 @@
476476
}
477477
assert( g.zRepositoryName && g.zRepositoryName[0] );
478478
zIp = SocketAddr_toString(&p->addr);
479479
sqlite3_snprintf(sizeof(zCmd), zCmd,
480480
"\"%s\" http --in \"%s\" --out \"%s\" --ipaddr %s \"%s\""
481
- " --scgi --nossl --nodelay%s",
481
+ " --scgi --nossl%s",
482482
g.nameOfExe, zRequestFName, zReplyFName, zIp,
483483
g.zRepositoryName, p->zOptions
484484
);
485485
fossil_free(zIp);
486486
in = fossil_fopen(zReplyFName, "w+b");
487487
--- src/winhttp.c
+++ src/winhttp.c
@@ -405,11 +405,11 @@
405 aux = fossil_fopen(zCmdFName, "wb");
406 if( aux==0 ) goto end_request;
407 fwrite(zCmd, 1, strlen(zCmd), aux);
408
409 sqlite3_snprintf(sizeof(zCmd), zCmd,
410 "\"%s\" http -args \"%s\" --nossl --nodelay%s",
411 g.nameOfExe, zCmdFName, p->zOptions
412 );
413 in = fossil_fopen(zReplyFName, "w+b");
414 fflush(out);
415 fflush(aux);
@@ -476,11 +476,11 @@
476 }
477 assert( g.zRepositoryName && g.zRepositoryName[0] );
478 zIp = SocketAddr_toString(&p->addr);
479 sqlite3_snprintf(sizeof(zCmd), zCmd,
480 "\"%s\" http --in \"%s\" --out \"%s\" --ipaddr %s \"%s\""
481 " --scgi --nossl --nodelay%s",
482 g.nameOfExe, zRequestFName, zReplyFName, zIp,
483 g.zRepositoryName, p->zOptions
484 );
485 fossil_free(zIp);
486 in = fossil_fopen(zReplyFName, "w+b");
487
--- src/winhttp.c
+++ src/winhttp.c
@@ -405,11 +405,11 @@
405 aux = fossil_fopen(zCmdFName, "wb");
406 if( aux==0 ) goto end_request;
407 fwrite(zCmd, 1, strlen(zCmd), aux);
408
409 sqlite3_snprintf(sizeof(zCmd), zCmd,
410 "\"%s\" http -args \"%s\" --nossl%s",
411 g.nameOfExe, zCmdFName, p->zOptions
412 );
413 in = fossil_fopen(zReplyFName, "w+b");
414 fflush(out);
415 fflush(aux);
@@ -476,11 +476,11 @@
476 }
477 assert( g.zRepositoryName && g.zRepositoryName[0] );
478 zIp = SocketAddr_toString(&p->addr);
479 sqlite3_snprintf(sizeof(zCmd), zCmd,
480 "\"%s\" http --in \"%s\" --out \"%s\" --ipaddr %s \"%s\""
481 " --scgi --nossl%s",
482 g.nameOfExe, zRequestFName, zReplyFName, zIp,
483 g.zRepositoryName, p->zOptions
484 );
485 fossil_free(zIp);
486 in = fossil_fopen(zReplyFName, "w+b");
487

Keyboard Shortcuts

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