Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch win32Proc Excluding Merge-Ins
This is equivalent to a diff from d5c41263 to 0ef0e105
2018-08-07
| ||
20:58 | Improved windows code for the backoffice. Properly check to see if processes still exist. Provide a timeout feature. ... (check-in: 43c29877 user: drh tags: trunk) | |
2018-08-02
| ||
03:35 | Include winsock2.h for WinXP compatibility; was breaking the build ... (check-in: 889bc0f7 user: ashepilko tags: trunk) | |
03:05 | Just in case, modify backofficeTimeout() to handle being called more than once on Win32. ... (Closed-Leaf check-in: 0ef0e105 user: mistachkin tags: win32Proc) | |
03:03 | Wrap use of getpid() in the trace statements. ... (check-in: 842bf225 user: mistachkin tags: win32Proc) | |
2018-07-31
| ||
00:10 | Use a thread to implement backoffice work timeouts for Win32. ... (check-in: a9578f78 user: mistachkin tags: win32Proc) | |
00:09 | Update the custom MinGW makefile. ... (check-in: d5c41263 user: mistachkin tags: trunk) | |
00:09 | Fix harmless compiler warnings. ... (check-in: ea2e5151 user: mistachkin tags: trunk) | |
Changes to src/backoffice.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | ** if the Fossil binary is updated on a system, the backoffice processes ** will restart using the new binary automatically. */ #include "config.h" #include "backoffice.h" #include <time.h> #if defined(_WIN32) # include <windows.h> #else # include <unistd.h> # include <sys/types.h> # include <signal.h> #endif /* ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice ** processing run is valid. Each backoffice run monopolizes the lease for ** at least this amount of time. Hopefully all backoffice processing is ** finished much faster than this - usually in less than a second. But | > > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | ** if the Fossil binary is updated on a system, the backoffice processes ** will restart using the new binary automatically. */ #include "config.h" #include "backoffice.h" #include <time.h> #if defined(_WIN32) # include <process.h> # include <windows.h> # define GETPID (int)GetCurrentProcessId #else # include <unistd.h> # include <sys/types.h> # include <signal.h> # define GETPID getpid #endif /* ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice ** processing run is valid. Each backoffice run monopolizes the lease for ** at least this amount of time. Hopefully all backoffice processing is ** finished much faster than this - usually in less than a second. But |
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /* ** Disable the backoffice */ 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; | > > > > > > > > > > > > > > > > > | 87 88 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 116 117 | /* ** Disable the backoffice */ void backoffice_no_delay(void){ backofficeNoDelay = 1; } /* ** Sleeps for the specified number of milliseconds -OR- until interrupted ** by another thread (if supported by the underlying platform). Non-zero ** will be returned if the sleep was interrupted. */ static int backofficeSleep(int milliseconds){ #if defined(_WIN32) assert( milliseconds>=0 ); if( SleepEx((DWORD)milliseconds, TRUE)==WAIT_IO_COMPLETION ){ return 1; } #else sqlite3_sleep(milliseconds); #endif return 0; } /* ** 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; |
︙ | ︙ | |||
129 130 131 132 133 134 135 136 137 138 139 140 141 | db_multi_exec( "REPLACE INTO repository.config(name,value,mtime)" " VALUES('backoffice','%lld %lld %lld %lld',now())", pLease->idCurrent, pLease->tmCurrent, pLease->idNext, pLease->tmNext); } /* ** Check to see if the process identified by selfId is alive. If ** we cannot prove the the process is dead, return true. */ static int backofficeProcessExists(sqlite3_uint64 pid){ #if defined(_WIN32) | > > > > > > > > > > > > > > > > > > | | < | < < < < | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | db_multi_exec( "REPLACE INTO repository.config(name,value,mtime)" " VALUES('backoffice','%lld %lld %lld %lld',now())", pLease->idCurrent, pLease->tmCurrent, pLease->idNext, pLease->tmNext); } /* ** Check to see if the specified Win32 process is still alive. It ** should be noted that even if this function returns non-zero, the ** process may die before another operation on it can be completed. */ #if defined(_WIN32) #ifndef PROCESS_QUERY_LIMITED_INFORMATION # define PROCESS_QUERY_LIMITED_INFORMATION (0x1000) #endif static int backofficeWin32ProcessExists(DWORD dwProcessId){ HANDLE hProcess; hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,FALSE,dwProcessId); if( hProcess==NULL ) return 0; CloseHandle(hProcess); return 1; } #endif /* ** Check to see if the process identified by selfId is alive. If ** we cannot prove the the process is dead, return true. */ static int backofficeProcessExists(sqlite3_uint64 pid){ #if defined(_WIN32) return pid>0 && backofficeWin32ProcessExists((DWORD)pid)!=0; #else return pid>0 && kill((pid_t)pid, 0)==0; #endif } /* ** Check to see if the process identified by selfId has finished. If ** we cannot prove the the process is still running, return true. */ static int backofficeProcessDone(sqlite3_uint64 pid){ #if defined(_WIN32) return pid<=0 || backofficeWin32ProcessExists((DWORD)pid)==0; #else return pid<=0 || kill((pid_t)pid, 0)!=0; #endif } /* ** Return a process id number for the current process */ static sqlite3_uint64 backofficeProcessId(void){ return (sqlite3_uint64)GETPID(); } /* ** Set an alarm to cause the process to exit after "x" seconds. This ** prevents any kind of bug from keeping a backoffice process running ** indefinitely. */ static void backofficeSigalrmHandler(int x){ fossil_panic("backoffice timeout (%d seconds)", x); } #if defined(_WIN32) static void *threadHandle = NULL; static void __stdcall backofficeWin32NoopApcProc(ULONG_PTR pArg){} /* NO-OP */ static void backofficeWin32ThreadCleanup(){ if( threadHandle!=NULL ){ /* Queue no-op asynchronous procedure call to the sleeping * thread. This will cause it to wake up with a non-zero * return value. */ if( QueueUserAPC(backofficeWin32NoopApcProc, threadHandle, 0) ){ /* Wait for the thread to wake up and then exit. */ WaitForSingleObject(threadHandle, INFINITE); } CloseHandle(threadHandle); threadHandle = NULL; } } static unsigned __stdcall backofficeWin32SigalrmThreadProc( void *pArg /* IN: Pointer to integer number of whole seconds. */ ){ int seconds = FOSSIL_PTR_TO_INT(pArg); if( SleepEx((DWORD)seconds * 1000, TRUE)==0 ){ backofficeSigalrmHandler(seconds); } _endthreadex(0); return 0; /* NOT REACHED */ } #endif static void backofficeTimeout(int x){ #if defined(_WIN32) backofficeWin32ThreadCleanup(); threadHandle = (void*)_beginthreadex( 0, 0, backofficeWin32SigalrmThreadProc, FOSSIL_INT_TO_PTR(x), 0, 0 ); #else signal(SIGALRM, backofficeSigalrmHandler); alarm(x); #endif } /* |
︙ | ︙ | |||
257 258 259 260 261 262 263 | x.tmCurrent = tmNow + BKOFCE_LEASE_TIME; x.idNext = 0; x.tmNext = 0; backofficeWriteLease(&x); db_end_transaction(0); if( g.fAnyTrace ){ fprintf(stderr, "/***** Begin Backoffice Processing %d *****/\n", | | | | > > > > > > > | > > > | > > | > > > > > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 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 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | x.tmCurrent = tmNow + BKOFCE_LEASE_TIME; x.idNext = 0; x.tmNext = 0; backofficeWriteLease(&x); db_end_transaction(0); if( g.fAnyTrace ){ fprintf(stderr, "/***** Begin Backoffice Processing %d *****/\n", GETPID()); } backoffice_work(); break; } if( backofficeNoDelay ){ /* If the no-delay flag is set, exit immediately rather than queuing ** up. Assume that some future request will come along and handle any ** necessary backoffice work. */ db_end_transaction(0); break; } /* This process needs to queue up and wait for the current lease ** to expire before continuing. */ x.idNext = idSelf; x.tmNext = (tmNow>x.tmCurrent ? tmNow : x.tmCurrent) + BKOFCE_LEASE_TIME; backofficeWriteLease(&x); db_end_transaction(0); if( g.fAnyTrace ){ fprintf(stderr, "/***** Backoffice On-deck %d *****/\n", GETPID()); } if( x.tmCurrent >= tmNow ){ if( backofficeSleep(1000*(x.tmCurrent - tmNow + 1)) ){ /* The sleep was interrupted by a signal from another thread. */ if( g.fAnyTrace ){ fprintf(stderr, "/***** Backoffice Interrupt %d *****/\n", GETPID()); } db_end_transaction(0); break; } }else{ if( lastWarning+warningDelay < tmNow ){ fossil_warning( "backoffice process %lld still running after %d seconds", x.idCurrent, (int)(BKOFCE_LEASE_TIME + tmNow - x.tmCurrent)); lastWarning = tmNow; warningDelay *= 2; } if( backofficeSleep(1000) ){ /* The sleep was interrupted by a signal from another thread. */ if( g.fAnyTrace ){ fprintf(stderr, "/***** Backoffice Interrupt %d *****/\n", GETPID()); } db_end_transaction(0); break; } } } #if defined(_WIN32) backofficeWin32ThreadCleanup(); #endif return; } /* ** This routine runs to do the backoffice processing. When adding new ** backoffice processing tasks, add them here. */ |
︙ | ︙ |