Fossil SCM

Improvements to the way backoffice is launched, especially on unix where it now runs in a separate process using fork(). Also fix some minor bugs in other parts of the system that were found while testing backoffice.

drh 2018-08-07 18:30 trunk merge
Commit 4180dc6b5a6c226fd22c8b3551dcd26bd0aa936eeb00dd2c6c897e70a2fac4eb
+159 -37
--- src/backoffice.c
+++ src/backoffice.c
@@ -35,10 +35,29 @@
3535
** Backoffice processes should die off after doing whatever work they need
3636
** to do. In this way, we avoid having lots of idle processes in the
3737
** process table, doing nothing on rarely accessed repositories, and
3838
** if the Fossil binary is updated on a system, the backoffice processes
3939
** will restart using the new binary automatically.
40
+**
41
+** At any point in time there should be at most two backoffice processes.
42
+** There is a main process that is doing the actually work, and there is
43
+** a second stand-by process that is waiting for the main process to finish
44
+** and that will become the main process after a delay.
45
+**
46
+** After any successful web page reply, the backoffice_check_if_needed()
47
+** routine is called. That routine checks to see if both one or both of
48
+** the backoffice processes are already running. That routine remembers the
49
+** status in a global variable.
50
+**
51
+** Later, after the repository database is closed, the
52
+** backoffice_run_if_needed() routine is called. If the prior call
53
+** to backoffice_check_if_needed() indicated that backoffice processing
54
+** might be required, the run_if_needed() attempts to kick off a backoffice
55
+** process.
56
+**
57
+** All work performance by the backoffice is in the backoffice_work()
58
+** routine.
4059
*/
4160
#include "config.h"
4261
#include "backoffice.h"
4362
#include <time.h>
4463
#if defined(_WIN32)
@@ -52,38 +71,58 @@
5271
/*
5372
** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
5473
** processing run is valid. Each backoffice run monopolizes the lease for
5574
** at least this amount of time. Hopefully all backoffice processing is
5675
** finished much faster than this - usually in less than a second. But
57
-** regardless of how fast each invocations run, successive backoffice runs
76
+** regardless of how long each invocation lasts, successive backoffice runs
5877
** must be spaced out by at least this much time.
5978
*/
60
-#define BKOFCE_LEASE_TIME 60 /* Length of lease validity */
79
+#define BKOFCE_LEASE_TIME 60 /* Length of lease validity in seconds */
6180
6281
#if LOCAL_INTERFACE
6382
/*
6483
** An instance of the following object describes a lease on the backoffice
6584
** processing timeslot. This lease is used to help ensure that no more than
66
-** one processing is running backoffice at a time.
85
+** one process is running backoffice at a time.
6786
*/
6887
struct Lease {
69
- sqlite3_uint64 idCurrent; /* ID for the current lease holder */
70
- sqlite3_uint64 tmCurrent; /* Expiration of the current lease */
71
- sqlite3_uint64 idNext; /* ID for the next lease holder on queue */
72
- sqlite3_uint64 tmNext; /* Expiration of the next lease */
88
+ sqlite3_uint64 idCurrent; /* process ID for the current lease holder */
89
+ sqlite3_uint64 tmCurrent; /* Expiration of the current lease */
90
+ sqlite3_uint64 idNext; /* process ID for the next lease holder on queue */
91
+ sqlite3_uint64 tmNext; /* Expiration of the next lease */
7392
};
7493
#endif
7594
76
-/*
77
-** Set to prevent backoffice processing from every entering sleep or
95
+/***************************************************************************
96
+** Local state variables
97
+**
98
+** Set to prevent backoffice processing from ever entering sleep or
7899
** otherwise taking a long time to complete. Set this when a user-visible
79100
** process might need to wait for backoffice to complete.
80101
*/
81102
static int backofficeNoDelay = 0;
82103
104
+/* This variable is set to the name of a database on which backoffice
105
+** should run if backoffice process is needed. It is set by the
106
+** backoffice_check_if_needed() routine which must be run while the database
107
+** file is open. Later, after the database is closed, the
108
+** backoffice_run_if_needed() will consult this variable to see if it
109
+** should be a no-op.
110
+*/
111
+static char *backofficeDb = 0;
112
+
113
+/* End of state variables
114
+****************************************************************************/
115
+
83116
/*
84
-** Disable the backoffice
117
+** Do not allow backoffice processes to sleep waiting on a timeslot.
118
+** They must either do their work immediately or exit.
119
+**
120
+** In a perfect world, this interface would not exist, as there would
121
+** never be a problem with waiting backoffice threads. But in some cases
122
+** a backoffice will delay a UI thread, so we don't want them to run for
123
+** longer than needed.
85124
*/
86125
void backoffice_no_delay(void){
87126
backofficeNoDelay = 1;
88127
}
89128
@@ -130,11 +169,11 @@
130169
pLease->idCurrent, pLease->tmCurrent,
131170
pLease->idNext, pLease->tmNext);
132171
}
133172
134173
/*
135
-** Check to see if the process identified by selfId is alive. If
174
+** Check to see if the process identified by pid is alive. If
136175
** we cannot prove the the process is dead, return true.
137176
*/
138177
static int backofficeProcessExists(sqlite3_uint64 pid){
139178
#if defined(_WIN32)
140179
return 1;
@@ -142,11 +181,11 @@
142181
return pid>0 && kill((pid_t)pid, 0)==0;
143182
#endif
144183
}
145184
146185
/*
147
-** Check to see if the process identified by selfId has finished. If
186
+** Check to see if the process identified by pid has finished. If
148187
** we cannot prove the the process is still running, return true.
149188
*/
150189
static int backofficeProcessDone(sqlite3_uint64 pid){
151190
#if defined(_WIN32)
152191
return 1;
@@ -205,36 +244,72 @@
205244
x, backofficeProcessExists(x),
206245
backofficeProcessDone(x));
207246
}
208247
}
209248
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.
249
+/*
250
+** If backoffice processing is needed set the backofficeDb variable to the
251
+** name of the database file. If no backoffice processing is needed,
252
+** this routine makes no changes to state.
216253
*/
217
-void backoffice_run(void){
254
+void backoffice_check_if_needed(void){
218255
Lease x;
219256
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;
257
+
258
+ if( backofficeDb ) return;
259
+ if( g.zRepositoryName==0 ) return;
260
+ if( g.db==0 ) return;
261
+ tmNow = time(0);
262
+ backofficeReadLease(&x);
263
+ if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
264
+ /* Another backoffice process is already queued up to run. This
265
+ ** process does not need to do any backoffice work. */
266
+ return;
267
+ }else{
268
+ /* We need to run backup to be (at a minimum) on-deck */
269
+ backofficeDb = fossil_strdup(g.zRepositoryName);
270
+ }
271
+}
272
+
273
+/*
274
+** Check for errors prior to running backoffice_thread() or backoffice_run().
275
+*/
276
+static void backoffice_error_check_one(int *pOnce){
277
+ if( *pOnce ){
278
+ fossil_panic("multiple calls to backoffice()");
279
+ }
280
+ *pOnce = 1;
229281
if( g.db==0 ){
230282
fossil_panic("database not open for backoffice processing");
231283
}
232284
if( db_transaction_nesting_depth()!=0 ){
233285
fossil_panic("transaction %s not closed prior to backoffice processing",
234286
db_transaction_start_point());
235287
}
288
+}
289
+
290
+/* This is the main loop for backoffice processing.
291
+**
292
+** If another process is already working as the current backoffice and
293
+** the on-deck backoffice, then this routine returns very quickly
294
+** without doing any work.
295
+**
296
+** If no backoffice processes are running at all, this routine becomes
297
+** the main backoffice.
298
+**
299
+** If a primary backoffice is running, but a on-deck backoffice is
300
+** needed, this routine becomes that on-desk backoffice.
301
+*/
302
+static void backoffice_thread(void){
303
+ Lease x;
304
+ sqlite3_uint64 tmNow;
305
+ sqlite3_uint64 idSelf;
306
+ int lastWarning = 0;
307
+ int warningDelay = 30;
308
+ static int once = 0;
309
+
310
+ backoffice_error_check_one(&once);
236311
backofficeTimeout(BKOFCE_LEASE_TIME*2);
237312
idSelf = backofficeProcessId();
238313
while(1){
239314
tmNow = time(0);
240315
db_begin_write();
@@ -303,15 +378,62 @@
303378
void backoffice_work(void){
304379
email_backoffice(0);
305380
}
306381
307382
/*
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();
383
+** COMMAND: backoffice
384
+**
385
+** Usage: backoffice [-R repository]
386
+**
387
+** Run backoffice processing. This might be done by a cron job or
388
+** similar to make sure backoffice processing happens periodically.
389
+*/
390
+void backoffice_command(void){
391
+ verify_all_options();
392
+ db_find_and_open_repository(0,0);
393
+ backoffice_thread();
394
+}
395
+
396
+/*
397
+** This is the main interface to backoffice from the rest of the system.
398
+** This routine launches either backoffice_thread() directly or as a
399
+** subprocess.
400
+*/
401
+void backoffice_run_if_needed(void){
402
+ if( backofficeDb==0 ) return;
403
+ if( strcmp(backofficeDb,"x")==0 ) return;
404
+ if( g.db ) return;
405
+ if( g.repositoryOpen ) return;
406
+#if !defined(_WIN32)
407
+ {
408
+ pid_t pid = fork();
409
+ if( pid>0 ){
410
+ /* This is the parent in a successful fork(). Return immediately. */
411
+ if( g.fAnyTrace ){
412
+ fprintf(stderr,
413
+ "/***** Subprocess %d creates backoffice child %d *****/\n",
414
+ getpid(), (int)pid);
415
+ }
416
+ return;
417
+ }
418
+ if( pid==0 ){
419
+ /* This is the child of a successful fork(). Run backoffice. */
420
+ db_open_repository(backofficeDb);
421
+ backofficeDb = "x";
422
+ backoffice_thread();
423
+ db_close(1);
424
+ if( g.fAnyTrace ){
425
+ fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid());
426
+ }
427
+ exit(0);
428
+ }
429
+ }
430
+#endif
431
+ /* Fork() failed or is unavailable. Run backoffice in this process, but
432
+ ** do so with the no-delay setting.
433
+ */
434
+ backofficeNoDelay = 1;
435
+ db_open_repository(backofficeDb);
436
+ backofficeDb = "x";
437
+ backoffice_thread();
438
+ db_close(1);
317439
}
318440
--- src/backoffice.c
+++ src/backoffice.c
@@ -35,10 +35,29 @@
35 ** Backoffice processes should die off after doing whatever work they need
36 ** to do. In this way, we avoid having lots of idle processes in the
37 ** process table, doing nothing on rarely accessed repositories, and
38 ** if the Fossil binary is updated on a system, the backoffice processes
39 ** will restart using the new binary automatically.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40 */
41 #include "config.h"
42 #include "backoffice.h"
43 #include <time.h>
44 #if defined(_WIN32)
@@ -52,38 +71,58 @@
52 /*
53 ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
54 ** processing run is valid. Each backoffice run monopolizes the lease for
55 ** at least this amount of time. Hopefully all backoffice processing is
56 ** finished much faster than this - usually in less than a second. But
57 ** regardless of how fast each invocations run, successive backoffice runs
58 ** must be spaced out by at least this much time.
59 */
60 #define BKOFCE_LEASE_TIME 60 /* Length of lease validity */
61
62 #if LOCAL_INTERFACE
63 /*
64 ** An instance of the following object describes a lease on the backoffice
65 ** processing timeslot. This lease is used to help ensure that no more than
66 ** one processing is running backoffice at a time.
67 */
68 struct Lease {
69 sqlite3_uint64 idCurrent; /* ID for the current lease holder */
70 sqlite3_uint64 tmCurrent; /* Expiration of the current lease */
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
@@ -130,11 +169,11 @@
130 pLease->idCurrent, pLease->tmCurrent,
131 pLease->idNext, pLease->tmNext);
132 }
133
134 /*
135 ** Check to see if the process identified by selfId is alive. If
136 ** we cannot prove the the process is dead, return true.
137 */
138 static int backofficeProcessExists(sqlite3_uint64 pid){
139 #if defined(_WIN32)
140 return 1;
@@ -142,11 +181,11 @@
142 return pid>0 && kill((pid_t)pid, 0)==0;
143 #endif
144 }
145
146 /*
147 ** Check to see if the process identified by selfId has finished. If
148 ** we cannot prove the the process is still running, return true.
149 */
150 static int backofficeProcessDone(sqlite3_uint64 pid){
151 #if defined(_WIN32)
152 return 1;
@@ -205,36 +244,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 +378,62 @@
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
@@ -35,10 +35,29 @@
35 ** Backoffice processes should die off after doing whatever work they need
36 ** to do. In this way, we avoid having lots of idle processes in the
37 ** process table, doing nothing on rarely accessed repositories, and
38 ** if the Fossil binary is updated on a system, the backoffice processes
39 ** will restart using the new binary automatically.
40 **
41 ** At any point in time there should be at most two backoffice processes.
42 ** There is a main process that is doing the actually work, and there is
43 ** a second stand-by process that is waiting for the main process to finish
44 ** and that will become the main process after a delay.
45 **
46 ** After any successful web page reply, the backoffice_check_if_needed()
47 ** routine is called. That routine checks to see if both one or both of
48 ** the backoffice processes are already running. That routine remembers the
49 ** status in a global variable.
50 **
51 ** Later, after the repository database is closed, the
52 ** backoffice_run_if_needed() routine is called. If the prior call
53 ** to backoffice_check_if_needed() indicated that backoffice processing
54 ** might be required, the run_if_needed() attempts to kick off a backoffice
55 ** process.
56 **
57 ** All work performance by the backoffice is in the backoffice_work()
58 ** routine.
59 */
60 #include "config.h"
61 #include "backoffice.h"
62 #include <time.h>
63 #if defined(_WIN32)
@@ -52,38 +71,58 @@
71 /*
72 ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
73 ** processing run is valid. Each backoffice run monopolizes the lease for
74 ** at least this amount of time. Hopefully all backoffice processing is
75 ** finished much faster than this - usually in less than a second. But
76 ** regardless of how long each invocation lasts, successive backoffice runs
77 ** must be spaced out by at least this much time.
78 */
79 #define BKOFCE_LEASE_TIME 60 /* Length of lease validity in seconds */
80
81 #if LOCAL_INTERFACE
82 /*
83 ** An instance of the following object describes a lease on the backoffice
84 ** processing timeslot. This lease is used to help ensure that no more than
85 ** one process is running backoffice at a time.
86 */
87 struct Lease {
88 sqlite3_uint64 idCurrent; /* process ID for the current lease holder */
89 sqlite3_uint64 tmCurrent; /* Expiration of the current lease */
90 sqlite3_uint64 idNext; /* process ID for the next lease holder on queue */
91 sqlite3_uint64 tmNext; /* Expiration of the next lease */
92 };
93 #endif
94
95 /***************************************************************************
96 ** Local state variables
97 **
98 ** Set to prevent backoffice processing from ever entering sleep or
99 ** otherwise taking a long time to complete. Set this when a user-visible
100 ** process might need to wait for backoffice to complete.
101 */
102 static int backofficeNoDelay = 0;
103
104 /* This variable is set to the name of a database on which backoffice
105 ** should run if backoffice process is needed. It is set by the
106 ** backoffice_check_if_needed() routine which must be run while the database
107 ** file is open. Later, after the database is closed, the
108 ** backoffice_run_if_needed() will consult this variable to see if it
109 ** should be a no-op.
110 */
111 static char *backofficeDb = 0;
112
113 /* End of state variables
114 ****************************************************************************/
115
116 /*
117 ** Do not allow backoffice processes to sleep waiting on a timeslot.
118 ** They must either do their work immediately or exit.
119 **
120 ** In a perfect world, this interface would not exist, as there would
121 ** never be a problem with waiting backoffice threads. But in some cases
122 ** a backoffice will delay a UI thread, so we don't want them to run for
123 ** longer than needed.
124 */
125 void backoffice_no_delay(void){
126 backofficeNoDelay = 1;
127 }
128
@@ -130,11 +169,11 @@
169 pLease->idCurrent, pLease->tmCurrent,
170 pLease->idNext, pLease->tmNext);
171 }
172
173 /*
174 ** Check to see if the process identified by pid is alive. If
175 ** we cannot prove the the process is dead, return true.
176 */
177 static int backofficeProcessExists(sqlite3_uint64 pid){
178 #if defined(_WIN32)
179 return 1;
@@ -142,11 +181,11 @@
181 return pid>0 && kill((pid_t)pid, 0)==0;
182 #endif
183 }
184
185 /*
186 ** Check to see if the process identified by pid has finished. If
187 ** we cannot prove the the process is still running, return true.
188 */
189 static int backofficeProcessDone(sqlite3_uint64 pid){
190 #if defined(_WIN32)
191 return 1;
@@ -205,36 +244,72 @@
244 x, backofficeProcessExists(x),
245 backofficeProcessDone(x));
246 }
247 }
248
249 /*
250 ** If backoffice processing is needed set the backofficeDb variable to the
251 ** name of the database file. If no backoffice processing is needed,
252 ** this routine makes no changes to state.
 
 
253 */
254 void backoffice_check_if_needed(void){
255 Lease x;
256 sqlite3_uint64 tmNow;
257
258 if( backofficeDb ) return;
259 if( g.zRepositoryName==0 ) return;
260 if( g.db==0 ) return;
261 tmNow = time(0);
262 backofficeReadLease(&x);
263 if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
264 /* Another backoffice process is already queued up to run. This
265 ** process does not need to do any backoffice work. */
266 return;
267 }else{
268 /* We need to run backup to be (at a minimum) on-deck */
269 backofficeDb = fossil_strdup(g.zRepositoryName);
270 }
271 }
272
273 /*
274 ** Check for errors prior to running backoffice_thread() or backoffice_run().
275 */
276 static void backoffice_error_check_one(int *pOnce){
277 if( *pOnce ){
278 fossil_panic("multiple calls to backoffice()");
279 }
280 *pOnce = 1;
281 if( g.db==0 ){
282 fossil_panic("database not open for backoffice processing");
283 }
284 if( db_transaction_nesting_depth()!=0 ){
285 fossil_panic("transaction %s not closed prior to backoffice processing",
286 db_transaction_start_point());
287 }
288 }
289
290 /* This is the main loop for backoffice processing.
291 **
292 ** If another process is already working as the current backoffice and
293 ** the on-deck backoffice, then this routine returns very quickly
294 ** without doing any work.
295 **
296 ** If no backoffice processes are running at all, this routine becomes
297 ** the main backoffice.
298 **
299 ** If a primary backoffice is running, but a on-deck backoffice is
300 ** needed, this routine becomes that on-desk backoffice.
301 */
302 static void backoffice_thread(void){
303 Lease x;
304 sqlite3_uint64 tmNow;
305 sqlite3_uint64 idSelf;
306 int lastWarning = 0;
307 int warningDelay = 30;
308 static int once = 0;
309
310 backoffice_error_check_one(&once);
311 backofficeTimeout(BKOFCE_LEASE_TIME*2);
312 idSelf = backofficeProcessId();
313 while(1){
314 tmNow = time(0);
315 db_begin_write();
@@ -303,15 +378,62 @@
378 void backoffice_work(void){
379 email_backoffice(0);
380 }
381
382 /*
383 ** COMMAND: backoffice
384 **
385 ** Usage: backoffice [-R repository]
386 **
387 ** Run backoffice processing. This might be done by a cron job or
388 ** similar to make sure backoffice processing happens periodically.
389 */
390 void backoffice_command(void){
391 verify_all_options();
392 db_find_and_open_repository(0,0);
393 backoffice_thread();
394 }
395
396 /*
397 ** This is the main interface to backoffice from the rest of the system.
398 ** This routine launches either backoffice_thread() directly or as a
399 ** subprocess.
400 */
401 void backoffice_run_if_needed(void){
402 if( backofficeDb==0 ) return;
403 if( strcmp(backofficeDb,"x")==0 ) return;
404 if( g.db ) return;
405 if( g.repositoryOpen ) return;
406 #if !defined(_WIN32)
407 {
408 pid_t pid = fork();
409 if( pid>0 ){
410 /* This is the parent in a successful fork(). Return immediately. */
411 if( g.fAnyTrace ){
412 fprintf(stderr,
413 "/***** Subprocess %d creates backoffice child %d *****/\n",
414 getpid(), (int)pid);
415 }
416 return;
417 }
418 if( pid==0 ){
419 /* This is the child of a successful fork(). Run backoffice. */
420 db_open_repository(backofficeDb);
421 backofficeDb = "x";
422 backoffice_thread();
423 db_close(1);
424 if( g.fAnyTrace ){
425 fprintf(stderr, "/***** Backoffice Child %d exits *****/\n", getpid());
426 }
427 exit(0);
428 }
429 }
430 #endif
431 /* Fork() failed or is unavailable. Run backoffice in this process, but
432 ** do so with the no-delay setting.
433 */
434 backofficeNoDelay = 1;
435 db_open_repository(backofficeDb);
436 backofficeDb = "x";
437 backoffice_thread();
438 db_close(1);
439 }
440
+2 -12
--- src/cgi.c
+++ src/cgi.c
@@ -344,22 +344,12 @@
344344
345345
/* After the webpage has been sent, do any useful background
346346
** processing.
347347
*/
348348
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_run();
360
- }
349
+ if( g.db!=0 && iReplyStatus==200 ){
350
+ backoffice_check_if_needed();
361351
}
362352
}
363353
364354
/*
365355
** Do a redirect request to the URL given in the argument.
366356
--- 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_run();
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/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/forum.c
+++ src/forum.c
@@ -944,7 +944,8 @@
944944
@ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a>
945945
@ </tr>
946946
fossil_free(zAge);
947947
}
948948
@ </table></div>
949
+ db_finalize(&q);
949950
style_footer();
950951
}
951952
--- 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
--- 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
+1 -1
--- src/printf.c
+++ src/printf.c
@@ -1081,11 +1081,11 @@
10811081
static int once = 0;
10821082
10831083
if( once ) exit(1);
10841084
once = 1;
10851085
mainInFatalError = 1;
1086
- db_force_rollback();
1086
+ /* db_force_rollback(); */
10871087
va_start(ap, zFormat);
10881088
sqlite3_vsnprintf(sizeof(z),z,zFormat, ap);
10891089
va_end(ap);
10901090
if( g.fAnyTrace ){
10911091
fprintf(stderr, "/***** panic on %d *****/\n", getpid());
10921092
--- 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
+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