Ticket #8: greyfix-8.patch

File greyfix-8.patch, 1.8 kB (added by kmkaplan, 12 years ago)

BUGFIX detect deadlocks during run_expiry.

  • greyfix.c

    Tue Jan 15 16:23:44 CET 2008  kaplan+greyfix@kim-minh.com
      * BUGFIX detect deadlocks during run_expiry.
      Closes ticket #8 <URL:http://trac.kim-minh.com/greyfix/ticket/8>
    diff -rN -u old-greyfix/greyfix.c new-greyfix/greyfix.c
    old new  
    7979static DBT dbkey = { 0 }; 
    8080static DBT dbdata = { 0 }; 
    8181static struct triplet_data triplet_data; 
     82static int deadlock_detect = 0; 
    8283 
    8384static unsigned long greylist_delay = DELAY_MAIL_SECS; 
    8485static unsigned long bloc_max_idle = AUTO_RECORD_LIFE_SECS; 
     
    161162        log_db_error("db_env_create", rc); 
    162163    else { 
    163164        dbenv->set_errcall(dbenv, db_errcall_fcn); 
     165        rc = dbenv->set_lk_detect(dbenv, DB_LOCK_YOUNGEST); 
     166        if (rc) 
     167            log_db_error("dbenv->set_lk_detect DB_LOCK_YOUNGEST, expired triplets will not be deleted", rc); 
     168        else 
     169            deadlock_detect = 1; 
    164170        rc = dbenv->open(dbenv, db_home, 
    165171                         DB_INIT_LOCK | DB_INIT_MPOOL | DB_CREATE, 0); 
    166172        if (rc) { 
     
    269275    int rc; 
    270276    time_t now; 
    271277    unsigned int count = 0; 
    272     if (db == 0) 
     278    /* Cursor operations can hold several locks and therefore deadlock 
     279       so don't run expiry if deadlock detection does not work 
     280       http://www.oracle.com/technology/documentation/berkeley-db/db/ref/lock/notxn.html */ 
     281    if (db == 0 || deadlock_detect == 0) 
    273282        return; 
    274283    if (time(&now) == (time_t)-1) { 
    275284        syslog(LOG_ERR, "time failed during run_expiry"); 
     
    303312                    count++; 
    304313            } 
    305314        } 
    306         if (rc != DB_NOTFOUND) 
     315        if (rc == DB_LOCK_DEADLOCK) 
     316            syslog(LOG_DEBUG, "skipping concurrent expiry avoids " 
     317                   "deadlocks and unnecessary work"); 
     318        else if (rc != DB_NOTFOUND) 
    307319            log_db_error("dbcp->c_get failed", rc); 
    308320        if (rc = dbcp->c_close(dbcp)) 
    309321            log_db_error("dbcp->c_close failed", rc);