Removed race condition from CheckIfAlreadySeen()
[citadel.git] / citadel / database.c
index aec4a61f6f0806edba3766977cbca0dcc5aa77b7..3bed3c920fb546ccf90a66a21da4f62156dd4ddd 100644 (file)
@@ -49,6 +49,7 @@
 #include "control.h"
 #include "citserver.h"
 #include "config.h"
+#pragma GCC diagnostic ignored "-Wcast-qual"
 
 static DB *dbp[MAXCDB];                /* One DB handle for each Citadel database */
 static DB_ENV *dbenv;          /* The DB environment (global) */
@@ -510,14 +511,12 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
        memset(&dkey, 0, sizeof(DBT));
        memset(&ddata, 0, sizeof(DBT));
        dkey.size = ckeylen;
-       /* no, we don't care for this error. */
-       dkey.data = ckey;
-
+       dkey.data = (void *)ckey;
        ddata.size = cdatalen;
        ddata.data = cdata;
 
-       /* Only compress Visit records.  Everything else is uncompressed. */
-       if (cdb == CDB_VISIT) {
+       /* Only compress Visit and UseTable records.  Everything else is uncompressed. */
+       if ( (cdb == CDB_VISIT) || (cdb == CDB_USETABLE) ) {
                compressing = 1;
                zheader.magic = COMPRESS_MAGIC;
                zheader.uncompressed_len = cdatalen;
@@ -657,8 +656,7 @@ struct cdbdata *cdb_fetch(int cdb, const void *key, int keylen)
 
        memset(&dkey, 0, sizeof(DBT));
        dkey.size = keylen;
-       /* no we don't care about this error. */
-       dkey.data = key;
+       dkey.data = (void *)key;
 
        if (TSD->tid != NULL) {
                memset(&dret, 0, sizeof(DBT));
@@ -871,66 +869,30 @@ void cdb_trunc(int cdb)
        }
 }
 
-int SeentDebugEnabled = 0;
 
-time_t CheckIfAlreadySeen(const char *Facility,
-                         StrBuf *guid,
-                         time_t now,
-                         time_t antiexpire,
-                         eCheckType cType,
-                         long ccid,
-                         long ioid)
+
+// Has an item already been seen (is it in the CDB_USETABLE) ?
+// Returns 0 if it hasn't, 1 if it has
+// In either case, writes the item to the database for next time.
+int CheckIfAlreadySeen(StrBuf *guid)
 {
-       time_t InDBTimeStamp = 0;
+       int found = 0;
        struct UseTable ut;
        struct cdbdata *cdbut;
 
-       if (cType != eWrite)
-       {
-               syslog(LOG_DEBUG, "Loading [%s]", ChrPtr(guid));
-               cdbut = cdb_fetch(CDB_USETABLE, SKEY(guid));
-               if ((cdbut != NULL) && (cdbut->ptr != NULL)) {
-                       memcpy(&ut, cdbut->ptr,
-                              ((cdbut->len > sizeof(struct UseTable)) ?
-                               sizeof(struct UseTable) : cdbut->len));
-                       InDBTimeStamp = now - ut.ut_timestamp;
-
-                       if (InDBTimeStamp < antiexpire)
-                       {
-                               syslog(LOG_DEBUG, "Found - Not expired %ld < %ld", InDBTimeStamp, antiexpire);
-                               cdb_free(cdbut);
-                               return InDBTimeStamp;
-                       }
-                       else
-                       {
-                               syslog(LOG_DEBUG, "Found - Expired. %ld >= %ld", InDBTimeStamp, antiexpire);
-                               cdb_free(cdbut);
-                       }
-               }
-               else
-               {
-                       if (cdbut) cdb_free(cdbut);
-                       
-                       syslog(LOG_DEBUG, "not Found");
-                       if (cType == eCheckUpdate)
-                               return 0;
-               }
-
-               if (cType == eCheckExist)
-                       return InDBTimeStamp;
+       syslog(LOG_DEBUG, "CheckIfAlreadySeen(%s)", ChrPtr(guid));
+       cdbut = cdb_fetch(CDB_USETABLE, SKEY(guid));
+       if (cdbut != NULL) {
+               found = 1;
+               cdb_free(cdbut);
        }
 
+       /* (Re)write the record, to update the timestamp.  Zeroing it out makes it compress better. */
+       memset(&ut, 0, sizeof(struct UseTable));
        memcpy(ut.ut_msgid, SKEY(guid));
-       ut.ut_timestamp = now;
-
-       syslog(LOG_DEBUG, "Saving new Timestamp");
-       /* rewrite the record anyway, to update the timestamp */
-       cdb_store(CDB_USETABLE,
-                 SKEY(guid),
-                 &ut, sizeof(struct UseTable) );
-
-       syslog(LOG_DEBUG, "Done Saving");
-       return InDBTimeStamp;
+       ut.ut_timestamp = time(NULL);
+       cdb_store(CDB_USETABLE, SKEY(guid), &ut, sizeof(struct UseTable));
+       return(found);
 }
 
 
@@ -980,16 +942,11 @@ void cmd_rsen(char *argbuf) {
        }
 
 }
-void LogDebugEnableSeenEnable(const int n)
-{
-       SeentDebugEnabled = n;
-}
 
 CTDL_MODULE_INIT(database)
 {
        if (!threading)
        {
-               CtdlRegisterDebugFlagHook(HKEY("SeenDebug"), LogDebugEnableSeenEnable, &SeentDebugEnabled);
                CtdlRegisterProtoHook(cmd_rsen, "RSEN", "manipulate Aggregators seen database");
        }