}
+// 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) {
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.
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) {
extern void (*cdb_checkpoint)(void);
extern void (*cdb_compact)(void);
extern void (*cdb_rewind)(int);
+extern void (*cdb_tick)(void);
#endif
// 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) {
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.
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);
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);
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
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;
// 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;
}
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]);
}