diff audioDB.cpp @ 30:657e638b87ef

Add fcntl() locking to the database file handle. New procedures audioDB::get_lock() and audioDB::release_lock(), the latter of which is unused because we rely on the close() call in the destructor to release our locks.
author mas01cr
date Tue, 21 Aug 2007 16:59:33 +0000
parents 0357114be285
children 9503faa2981c
line wrap: on
line diff
--- a/audioDB.cpp	Thu Aug 16 11:39:46 2007 +0000
+++ b/audioDB.cpp	Tue Aug 21 16:59:33 2007 +0000
@@ -427,9 +427,49 @@
 
 */
 
+void audioDB::get_lock(int fd, bool exclusive) {
+  struct flock lock;
+  int status;
+  
+  lock.l_type = exclusive ? F_WRLCK : F_RDLCK;
+  lock.l_whence = SEEK_SET;
+  lock.l_start = 0;
+  lock.l_len = 0; /* "the whole file" */
+
+ retry:
+  do {
+    status = fcntl(fd, F_SETLKW, &lock);
+  } while (status != 0 && errno == EINTR);
+
+  if (status) {
+    if (errno == EAGAIN) {
+      sleep(1);
+      goto retry;
+    } else {
+      error("fcntl lock error");
+    }
+  }
+}
+
+void audioDB::release_lock(int fd) {
+  struct flock lock;
+  int status;
+
+  lock.l_type = F_UNLCK;
+  lock.l_whence = SEEK_SET;
+  lock.l_start = 0;
+  lock.l_len = 0;
+
+  status = fcntl(fd, F_SETLKW, &lock);
+
+  if (status)
+    error("fcntl unlock error");
+}
+
 void audioDB::create(const char* dbName){
   if ((dbfid = open (dbName, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0)
     error("Can't open database file", dbName);
+  get_lock(dbfid, 1);
 
   // go to the location corresponding to the last byte
   if (lseek (dbfid, O2_DEFAULTDBSIZE - 1, SEEK_SET) == -1)
@@ -473,7 +513,8 @@
 void audioDB::initTables(const char* dbName, bool forWrite, const char* inFile=0){
   if ((dbfid = open (dbName, forWrite ? O_RDWR : O_RDONLY)) < 0)
     error("Can't open database file", dbName);
-  
+  get_lock(dbfid, forWrite);
+
   // open the input file
   if (inFile && (infid = open (inFile, O_RDONLY)) < 0)
     error("can't open input file for reading", inFile);
@@ -667,6 +708,7 @@
 
   if ((dbfid = open (dbName, O_RDWR)) < 0)
     error("Can't open database file", dbName);
+  get_lock(dbfid, 1);
 
   if(!key)
     key=inFile;