00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <errno.h>
00018 #include <fcntl.h>
00019 #include <stdio.h>
00020 #include <sys/types.h>
00021 #include <sys/file.h>
00022 #include <sys/stat.h>
00023 #include <unistd.h>
00024
00025 #include "Error.h"
00026 #include "ObjLock.h"
00027
00028 ObjLock::ObjLock(const string & name)
00029 {
00030 this->name = name;
00031
00032 fd = open(name.c_str(), O_RDWR | O_CREAT | O_NONBLOCK,
00033 S_IWUSR | S_IRUSR);
00034 if (fd == -1)
00035 throw(SystemError("Error in ObjLock constructor (open)"),
00036 errno);
00037 #ifndef USE_FLOCK
00038 memset((void *) &l, 0, sizeof(struct flock));
00039 l.l_whence = SEEK_SET;
00040 #endif
00041 }
00042
00043 ObjLock::~ObjLock()
00044 {
00045 unlock();
00046 close(fd);
00047 }
00048
00049 void ObjLock::lockShBlk(void)
00050 {
00051 #ifdef USE_FLOCK
00052 if (flock(fd, LOCK_SH) == -1)
00053 throw(SystemError("Error flock", errno));
00054 #else
00055 l.l_type = F_RDLCK;
00056 if (fcntl(fd, F_SETLKW, &l) == -1)
00057 throw(SystemError("Error fcntl", errno));
00058 #endif
00059 }
00060
00061 int ObjLock::lockShNoBlk(void)
00062 {
00063 int s;
00064
00065 #ifdef USE_FLOCK
00066 s = flock(fd, LOCK_SH | LOCK_NB);
00067 #else
00068 l.l_type = F_RDLCK;
00069 s = fcntl(fd, F_SETLK, &l);
00070 #endif
00071 if (s == 0) {
00072 return locked;
00073 } else if (errno == EWOULDBLOCK) {
00074 return not_locked;
00075 } else {
00076 throw(SystemError("Error in lockShNoBlk", errno,
00077 ERROR_LOCATION));
00078 }
00079 }
00080
00081 void ObjLock::lockExBlk(void)
00082 {
00083 #ifdef USE_FLOCK
00084 if (flock(fd, LOCK_EX) == -1)
00085 throw(SystemError("Error in flock", errno,
00086 ERROR_LOCATION));
00087 #else
00088 l.l_type = F_WRLCK;
00089 if (fcntl(fd, F_SETLKW, &l) == -1)
00090 throw(SystemError("Error in fcntl", errno,
00091 ERROR_LOCATION));
00092 #endif
00093 }
00094
00095 int ObjLock::lockExNoBlk(void)
00096 {
00097 int s;
00098
00099 #ifdef USE_FLOCK
00100 s = flock(fd, LOCK_EX | LOCK_NB);
00101 #else
00102 l.l_type = F_WRLCK;
00103 s = fcntl(fd, F_SETLK, &l);
00104 #endif
00105 if (s == 0) {
00106 return locked;
00107 } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
00108 return not_locked;
00109 } else {
00110 throw(SystemError("Error in flock or fcntl", errno,
00111 ERROR_LOCATION));
00112 }
00113 }
00114
00115 void ObjLock::unlock(void)
00116 {
00117 #ifdef USE_FLOCK
00118 if (flock(fd, LOCK_UN) == -1)
00119 throw(SystemError("Error in flock", errno,
00120 ERROR_LOCATION));
00121 #else
00122 l.l_type = F_UNLCK;
00123 if (fcntl(fd, F_SETLKW, &l) == -1)
00124 throw(SystemError("Error in fcntl", errno,
00125 ERROR_LOCATION));
00126 #endif
00127 }