Wed Nov 11 00:47:32 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
authorArt Cancro <ajc@citadel.org>
Wed, 11 Nov 1998 05:49:35 +0000 (05:49 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 11 Nov 1998 05:49:35 +0000 (05:49 +0000)
* msgbase.c: fixed a bug that was misrouting incoming network msgs
* server.h, database.c: wrapped all GDBM calls in critical sections
  to avoid making those calls re-entrantly (gdbm fatal: lseek error)

citadel/ChangeLog
citadel/database.c
citadel/server.h

index 4215f3cc41d40e890ca721baac27db3edd7fb851..b5d1be9a9e754f853fd4956ca4bf227fb76e95b3 100644 (file)
@@ -1,3 +1,8 @@
+Wed Nov 11 00:47:32 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
+       * msgbase.c: fixed a bug that was misrouting incoming network msgs
+       * server.h, database.c: wrapped all GDBM calls in critical sections
+         to avoid making those calls re-entrantly (gdbm fatal: lseek error)
+
 1998-11-10 Nathan Bryant <bryant@cs.usm.maine.edu>
        * Makefile.in: link in snprintf.o where needed
 
index 7fa9a903931c490cfb502e35e7516b568df40632..98da2e38c536189c9b6a09710632e11d2f890e55 100644 (file)
@@ -42,24 +42,32 @@ void defrag_databases(void) {
 
        /* defrag the message base */
        begin_critical_section(S_MSGMAIN);
+       begin_critical_section(S_DATABASE);
        gdbm_reorganize(gdbms[CDB_MSGMAIN]);
+       end_critical_section(S_DATABASE);
        end_critical_section(S_MSGMAIN);
 
        /* defrag the user file, mailboxes, and user/room relationships */
        begin_critical_section(S_USERSUPP);
+       begin_critical_section(S_DATABASE);
        gdbm_reorganize(gdbms[CDB_USERSUPP]);
        gdbm_reorganize(gdbms[CDB_VISIT]);
+       end_critical_section(S_DATABASE);
        end_critical_section(S_USERSUPP);
 
        /* defrag the room files and message lists */
        begin_critical_section(S_QUICKROOM);
+       begin_critical_section(S_DATABASE);
        gdbm_reorganize(gdbms[CDB_QUICKROOM]);
        gdbm_reorganize(gdbms[CDB_MSGLISTS]);
+       end_critical_section(S_DATABASE);
        end_critical_section(S_QUICKROOM);
 
        /* defrag the floor table */
        begin_critical_section(S_FLOORTAB);
+       begin_critical_section(S_DATABASE);
        gdbm_reorganize(gdbms[CDB_FLOORTAB]);
+       end_critical_section(S_DATABASE);
        end_critical_section(S_FLOORTAB);
        }
 
@@ -77,6 +85,8 @@ void open_databases(void) {
         */
        system("exec mkdir data 2>/dev/null");
 
+       begin_critical_section(S_DATABASE);
+
        gdbms[CDB_MSGMAIN] = gdbm_open("data/msgmain.gdbm", 8192,
                GDBM_WRCREAT, 0600, NULL);
        if (gdbms[CDB_MSGMAIN] == NULL) {
@@ -124,6 +134,8 @@ void open_databases(void) {
                dtkey[a].dptr = NULL;
                }
 
+       end_critical_section(S_DATABASE);
+
        }
 
 
@@ -137,12 +149,14 @@ void close_databases(void) {
        /* Hmm... we should decide when would be a good time to defrag.
         * Server shutdowns might be an opportune time.
         */
-       /* defrag_databases(); */
+       defrag_databases();
 
+       begin_critical_section(S_DATABASE);
        for (a=0; a<MAXCDB; ++a) {
                lprintf(7, "Closing database %d\n", a);
                gdbm_close(gdbms[a]);
                }
+       end_critical_section(S_DATABASE);
 
        for (a=0; a<MAXKEYS; ++a) {
                if (dtkey[a].dptr != NULL) {
@@ -162,13 +176,17 @@ int cdb_store(int cdb,
                void *data, int datalen) {
 
        datum dkey, ddata;
+       int retval;
 
        dkey.dsize = keylen;
        dkey.dptr = key;
        ddata.dsize = datalen;
        ddata.dptr = data;
 
-       if ( gdbm_store(gdbms[cdb], dkey, ddata, GDBM_REPLACE) < 0 ) {
+       begin_critical_section(S_DATABASE);
+       retval = gdbm_store(gdbms[cdb], dkey, ddata, GDBM_REPLACE);
+       end_critical_section(S_DATABASE);
+       if ( retval < 0 ) {
                 lprintf(2, "gdbm error: %s\n", gdbm_strerror(gdbm_errno));
                 return(-1);
                }
@@ -183,11 +201,15 @@ int cdb_store(int cdb,
 int cdb_delete(int cdb, void *key, int keylen) {
 
        datum dkey;
+       int retval;
 
        dkey.dsize = keylen;
        dkey.dptr = key;
 
-       return(gdbm_delete(gdbms[cdb], dkey));
+       begin_critical_section(S_DATABASE);
+       retval = gdbm_delete(gdbms[cdb], dkey);
+       end_critical_section(S_DATABASE);
+       return(retval);
 
        }
 
@@ -207,7 +229,9 @@ struct cdbdata *cdb_fetch(int cdb, void *key, int keylen) {
        dkey.dsize = keylen;
        dkey.dptr = key;
 
+       begin_critical_section(S_DATABASE);
        dret = gdbm_fetch(gdbms[cdb], dkey);
+       end_critical_section(S_DATABASE);
        if (dret.dptr == NULL) {
                return NULL;
                }
@@ -245,7 +269,9 @@ void cdb_rewind(int cdb) {
                free(dtkey[CC->cs_pid].dptr);
                }
 
+       begin_critical_section(S_DATABASE);
        dtkey[CC->cs_pid] = gdbm_firstkey(gdbms[cdb]);
+       end_critical_section(S_DATABASE);
        }
 
 
@@ -262,7 +288,9 @@ struct cdbdata *cdb_next_item(int cdb) {
                return NULL;
                }
 
+       begin_critical_section(S_DATABASE);
        dret = gdbm_fetch(gdbms[cdb], dtkey[CC->cs_pid]);
+       end_critical_section(S_DATABASE);
        if (dret.dptr == NULL) {        /* bad read */
                free(dtkey[CC->cs_pid].dptr);
                return NULL;
@@ -272,6 +300,8 @@ struct cdbdata *cdb_next_item(int cdb) {
        cdbret->len = dret.dsize;
        cdbret->ptr = dret.dptr;
 
+       begin_critical_section(S_DATABASE);
        dtkey[CC->cs_pid] = gdbm_nextkey(gdbms[cdb], dtkey[CC->cs_pid]);
+       end_critical_section(S_DATABASE);
        return(cdbret);
        }
index 96258a208641c8f214ef2a42fe993d4c73790f92..0a29b4ebc2cbdc6cd9a3974f249ec0c4b88de038 100644 (file)
@@ -108,7 +108,8 @@ struct ChatLine {
 #define S_CHATQUEUE    7
 #define S_CONTROL      8
 #define S_HOUSEKEEPING 9
-#define MAX_SEMAPHORES 10
+#define S_DATABASE     10
+#define MAX_SEMAPHORES 11
 
 
 /*