cdb_tick() called periodically
authorArt Cancro <ajc@citadel.org>
Tue, 29 Aug 2023 03:53:58 +0000 (23:53 -0400)
committerArt Cancro <ajc@citadel.org>
Tue, 29 Aug 2023 03:53:58 +0000 (23:53 -0400)
citadel/server/backends/berkeley_db/berkeley_db.c
citadel/server/backends/common/database.c
citadel/server/database.h
citadel/server/housekeeping.c
citadel/server/room_ops.c
citadel/server/sysdep.c
citadel/server/threads.c

index 4d77a0b1483b33aba78e8a21ce7aa1a6a15b9be6..3e7d2af9002a399378a86161e8377fdc1d85500c 100644 (file)
@@ -621,6 +621,24 @@ void bdb_compact(void) {
 }
 
 
+// periodically called for maintenance
+void bdb_tick(void) {
+       int ret;
+       int rejected;
+
+       ret = bdb_env->lock_detect(bdb_env, 0, DB_LOCK_DEFAULT, &rejected);
+       if (ret) {
+               syslog(LOG_ERR, "bdb: lock_detect: %s", db_strerror(ret));
+       }
+       else if (rejected) {
+               syslog(LOG_DEBUG, "bdb: rejected lock %d", rejected);
+               bdb_abort();            // FIXME remove this, we want to unlock, not abort
+       }
+
+       syslog(LOG_DEBUG, "bdb: tick...");
+}
+
+
 // Calling this function activates the Berkeley DB back end.
 void bdb_init_backend(void) {
 
@@ -639,6 +657,7 @@ void bdb_init_backend(void) {
        cdb_end_transaction = bdb_end_transaction;
        cdb_check_handles = bdb_check_handles;
        cdb_trunc = bdb_trunc;
+       cdb_tick = bdb_tick;
 
        // Some functions in this backend need to store some per-thread data.
        // We crerate the key here, during module initialization.
index ac1ebbad61595a249ec413e20fe1728c68e4c9f6..934d5553e8456c41ffdf2542eb4519903d7b1bc0 100644 (file)
@@ -37,6 +37,7 @@ void                  (*check_handles)(void *)                                = NULL;
 void                   (*cdb_compact)(void)                                    = NULL;
 void                   (*cdb_checkpoint)(void)                                 = NULL;
 void                   (*cdb_rewind)(int)                                      = NULL;
+void                   (*cdb_tick)(void)                                       = NULL;
 
 // This function is responsible for choosing and initializing a back end.
 void cdb_init_backends(void) {
index c8345b8fd6684ad6897f92fdbd2d89587d0473d7..a83211d39c33252ae060bef7b1ff66d3632fb39f 100644 (file)
@@ -25,5 +25,6 @@ extern struct cdbdata         (*cdb_fetch)(int, const void *, int);
 extern void            (*cdb_checkpoint)(void);
 extern void            (*cdb_compact)(void);
 extern void            (*cdb_rewind)(int);
+extern void            (*cdb_tick)(void);
 
 #endif
index 8b13b955280319d9a3c67b006cae1fa1559294b0..55e7e77d68058f1b9b84fcb4a6d1a97ebbeadbfd 100644 (file)
@@ -124,6 +124,7 @@ void do_housekeeping(void) {
        // First, do the "as often as needed" stuff...
        JournalRunQueue();
        PerformSessionHooks(EVT_HOUSE);
+       cdb_tick();
 
        // Then, do the "once per minute" stuff...
        if (do_perminute_housekeeping_now) {
index f61e1f12668b96577fa1c1cef0aafea63dba8821..301f5987295ca117742880891614b545d2a641a2 100644 (file)
@@ -886,17 +886,6 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
                qrbuf.QRfloor = new_floor;
                CtdlPutRoom(&qrbuf);
 
-               begin_critical_section(S_CONFIG);
-       
-               // If baseroom/aideroom name changes, update config
-               if (!strncasecmp(old_name, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
-                       CtdlSetConfigStr("c_baseroom", new_name);
-               }
-               if (!strncasecmp(old_name, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) {
-                       CtdlSetConfigStr("c_aideroom", new_name);
-               }
-       
-               end_critical_section(S_CONFIG);
        
                // If the room name changed, then there are now two room
                // records, so we have to delete the old one.
@@ -909,6 +898,16 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
 
        end_critical_section(S_ROOMS);
 
+       // If baseroom/aideroom name changes, update config
+       begin_critical_section(S_CONFIG);
+       if (!strncasecmp(old_name, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
+               CtdlSetConfigStr("c_baseroom", new_name);
+       }
+       if (!strncasecmp(old_name, CtdlGetConfigStr("c_aideroom"), ROOMNAMELEN)) {
+               CtdlSetConfigStr("c_aideroom", new_name);
+       }
+       end_critical_section(S_CONFIG);
+
        // Adjust the floor reference counts if necessary
        if (new_floor != old_floor) {
                lgetfloor(&flbuf, old_floor);
index ee69a19c7272a8723d690bcbf9ae3aaafc2ff7c0..ada01885ffaf769edecb79d86c5726d8e3118fec 100644 (file)
@@ -46,7 +46,7 @@ static RETSIGTYPE signal_cleanup(int signum) {
        signal(SIGINT, SIG_DFL);
        signal(SIGHUP, SIG_DFL);
        signal(SIGTERM, SIG_DFL);
-       signal(SIGSEGV, SIG_DFL);
+       //signal(SIGSEGV, SIG_DFL);
        exit_signal = signum;
        server_shutting_down = 1;
        master_cleanup(signum);
@@ -83,13 +83,13 @@ void init_sysdep(void) {
        sigaddset(&set, SIGINT);
        sigaddset(&set, SIGHUP);
        sigaddset(&set, SIGTERM);
-       sigaddset(&set, SIGSEGV);
+       //sigaddset(&set, SIGSEGV);
        sigprocmask(SIG_UNBLOCK, &set, NULL);
 
        signal(SIGINT, signal_cleanup);
        signal(SIGHUP, signal_cleanup);
        signal(SIGTERM, signal_cleanup);
-       signal(SIGSEGV, signal_cleanup);
+       //signal(SIGSEGV, signal_cleanup);
 
        // Do not shut down the server on broken pipe signals, otherwise the
        // whole Citadel service would come down whenever a single client
index 8c186649832d50fc0849d020ee8537268638bc1c..78ded25def7c1c46543eb2bd6e0037951413256e 100644 (file)
@@ -21,6 +21,7 @@ int active_workers = 0;                               // Number of ACTIVE worker threads
 pthread_mutex_t Critters[MAX_SEMAPHORES];      // Things needing locking
 int server_shutting_down = 0;                  // set to nonzero during shutdown
 pthread_mutex_t ThreadCountMutex;
+char locks[MAX_SEMAPHORES+1];
 
 void InitializeSemaphores(void) {
        int i;
@@ -28,7 +29,9 @@ void InitializeSemaphores(void) {
        // Set up a bunch of semaphores to be used for critical sections
        for (i=0; i<MAX_SEMAPHORES; ++i) {
                pthread_mutex_init(&Critters[i], NULL);
+               locks[i] = ' ';
        }
+       locks[MAX_SEMAPHORES] = 0;
 }
 
 
@@ -57,12 +60,20 @@ void begin_critical_section(int which_one) {
                cdb_check_handles();
        }
 
+       syslog(LOG_ERR, "\033[3%dm  lock(%14p, %2d, %s)\033[0m", (which_one%6)+1, (CC==&masterCC ? 0 : CC), which_one, locks);
        pthread_mutex_lock(&Critters[which_one]);
+       if (locks[which_one] == 'X') {
+               syslog(LOG_ERR, "\033[7mHOLY SHIT, Thread %p sees double lock %d!!!!111\033[0m", CC, which_one);
+               abort();
+       }
+       locks[which_one] = 'X';
 }
 
 
 // Release a semaphore lock to end a critical section.
 void end_critical_section(int which_one) {
+       locks[which_one] = '_';
+       syslog(LOG_ERR, "\033[3%dmunlock(%14p, %2d, %s)\033[0m", (which_one%6)+1, (CC==&masterCC ? 0 : CC), which_one, locks);
        pthread_mutex_unlock(&Critters[which_one]);
 }