1 Reply Latest reply: Mar 14, 2012 8:03 AM by 923397 RSS

    deadlock in use Berkeley DB

    923397
      Hello everyone, I am use the Berkeley DB(ver: db-5.2.28) in my C++ project (OS: windows). It works fine.
      I encountered some problems recently, The program sometimes hang in some cases has been.
      I write a test code and it will remain in the WaitForSingleObject code when <font color="red">I run some instance of the program and close one of these. </font>

      ( mutex/mut_win32.c : 238 if ((ret = WaitForSingleObject(event, ms)) == WAIT_FAILED) )
      (sometimes it will deadlock in the DB->open)
      I tried set the DB_ENV open with DB_INIT_LOCK|DB_INIT_TXN flags, set_lk_detect, DB get whith DB_RMW flags, But it also happend.

      Who can tell me how to safety use to avoid this problem?

      Here is the test code:
      {
          DB_ENV *dbenv;
          DB *dbp;
      
          int ret;
      
          char keystr[] = "key";
          char buf[] = "valuedata";
          char savebuf[1024] = "";
          DBT key, data;
      
          unsigned long testtimes = 0;
      
          if((ret = db_env_create(&dbenv, 0)) != 0) 
          {
              fprintf(stderr, "dbenv create: %s\n", db_strerror(ret));
              return 1;
          }
      
          if((ret = dbenv->open(dbenv, NULL, 
                      DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN, 
                      0)) != 0) 
          {
              fprintf(stderr, "dbenv open:%s\n", db_strerror(ret));
              dbenv->close(dbenv, 0);
              return 1;
          }
      
          if((ret = db_create(&dbp, dbenv, 0)) != 0)
          {
              fprintf(stderr, "database create: %s\n", db_strerror(ret));
              return 1;
          }
      
          if((ret = dbp->open(dbp, NULL, "test.db", NULL, DB_BTREE, 
                       DB_CREATE|DB_AUTO_COMMIT,0)) != 0)
          {
              fprintf(stderr, "database open: %s\n", db_strerror(ret));
              return 1;
          }
      
          while(true)
          {
              ++testtimes;
      
              memset(&key, 0, sizeof(DBT));
              memset(&data, 0, sizeof(DBT));
              key.data = keystr;
              key.size = strlen(keystr);
              data.data = buf;
              data.size = sizeof(buf);
              if((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
              {
                  fprintf(stderr, "database write: %s\n", db_strerror(ret));
              }
      
              memset(&key, 0, sizeof(DBT));
              memset(&data, 0, sizeof(DBT));
              key.data = keystr;
              key.size = strlen(keystr);
              data.data = savebuf;
              data.ulen = sizeof(savebuf);
              data.flags = DB_DBT_USERMEM;
              if((ret = dbp->get(dbp, NULL, &key, &data, 0)) != 0)
              {
                  fprintf(stderr, "database read: %s\n", db_strerror(ret));
              }
      
              printf("data test %8ld\n", testtimes);
          }
      
          if((ret = dbp->close(dbp, 0)) != 0) 
          {
              fprintf(stderr, "database close: %s\n", db_strerror(ret));
              return 1;
          }
      
          if((ret = dbenv->close(dbenv, 0)) != 0) 
          {
              fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
              return 1;
          }
      
          return 0;
      }
      Edited by: 920394 on Mar 13, 2012 2:05 AM
        • 1. Re: deadlock in use Berkeley DB
          923397
          Even run this program once and close it, then run it again will also occur the problem.
          (add Transactions (DB_ENV->txn_begin & DB_TXN->commit) also can't resolve the problem)

          Or whether there is any function can be detected db file problems before operate it?

          Edited by: 920394 on Mar 14, 2012 6:03 AM