Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

wvlockfile.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Some handy functions to create/remove /var/lock lockfiles.
00006  */
00007 #include "wvlockfile.h"
00008 #include "wvfile.h"
00009 #include "strutils.h"
00010 #include <signal.h>
00011 #include <string.h>
00012 #include <sys/types.h>
00013 #include <fcntl.h>
00014 #include <sys/stat.h>
00015 #include <errno.h>
00016 
00017 WvLockFile::WvLockFile(WvString _devicename)
00018         : devicename(_devicename)
00019 {
00020     const char *p = strrchr(devicename, '/');
00021     if (p)
00022         p++;
00023     else
00024         p = devicename;
00025     
00026     lock_count = 0;
00027     filename = WvString("/var/lock/LCK..%s", p);
00028 }
00029 
00030 
00031 WvLockFile::~WvLockFile()
00032 {
00033     if (lock_count)
00034     {
00035         lock_count = 1;
00036         unlock();
00037     }
00038 }
00039 
00040 
00041 #if USE_LOCKDEV /* use the liblockdev.a locking routines */
00042 
00043 #include <lockdev.h>
00044 
00045 bool WvLockFile::lock()
00046 {
00047     if (lock_count)
00048     {
00049         lock_count++;
00050         return true;
00051     }
00052     
00053     if (dev_lock(devicename))
00054         return false;
00055 
00056     lock_count++;
00057     return true;
00058 }
00059 
00060 
00061 void WvLockFile::unlock()
00062 {
00063     if (!lock_count) return;
00064 
00065     if (!--lock_count)
00066         dev_unlock(devicename, getpid());
00067 }
00068 
00069 
00070 #else /* !USE_LOCKDEV -- implement our own locking routines */
00071 
00072 
00073 // note: this function uses the O_EXCL flag to open(), and thus assumes
00074 // that /var/lock is not an NFS-mounted drive (according to the open() man
00075 // page, you need to follow a special procedure to ensure successful NFS
00076 // locking)
00077 //
00078 // Actually there may be other race conditions that we should look into.
00079 bool WvLockFile::lock()
00080 {
00081     pid_t pid;
00082     
00083     if (lock_count)
00084     {
00085         lock_count++;
00086         return true;
00087     }
00088 
00089     WvFile fd(filename, O_RDWR | O_EXCL | O_CREAT, 0644);
00090 
00091     if (fd.isok()) 
00092     {
00093         // We made a lock file...
00094         fd.print( "%10s\n", getpid() );
00095     }
00096     else
00097     {
00098         char *inbuf;
00099         
00100         // Lock file is already there!  Check for staleness...
00101         sleep( 1 );     // preventing race condition...
00102         
00103         fd.open(filename, O_RDONLY);
00104         inbuf = trim_string(fd.getline(0));
00105         
00106         if (inbuf)
00107             pid = atoi(inbuf);
00108         else
00109             pid = 0;
00110         
00111         if(pid != 0  &&  kill(pid, 0) == -1  &&  errno == ESRCH)
00112         {
00113             // we can create a lockfile now
00114             fd.close();
00115             if (unlink(filename))
00116                 return false; // cannot remove lockfile
00117             fd.open(filename, O_RDWR | O_EXCL | O_CREAT, 0644);
00118             fd.print("%10s\n", getpid());
00119         }
00120         else
00121             return false; // device already locked
00122     }
00123 
00124     lock_count++;
00125     return true;
00126 }
00127 
00128 
00129 
00130 void WvLockFile::unlock()
00131 {
00132     if (!lock_count) return;
00133 
00134     if (!--lock_count)
00135         unlink( filename );
00136 }
00137 
00138 
00139 #endif /* !USE_LOCKDEV */

Generated on Sun Mar 16 01:01:11 2003 for WvStreams by doxygen1.3-rc3