00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <errno.h>
00047 #include <fcntl.h>
00048 #include <pthread.h>
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <sys/types.h>
00052 #include <sys/stat.h>
00053 #include <unistd.h>
00054
00055 #include <glib.h>
00056
00057 #include "erregrwlock.h"
00058 #include "erreglog.h"
00059
00060
00061 #define LOCK_FILE "/lockfile"
00062
00063
00064 static int g_lock_fd = -1;
00065 static pthread_mutex_t g_mutex;
00066 static lock_state_t g_lock_state = lock_none;
00067
00068
00069 static int lock_reg(int cmd, int type)
00070 {
00071 struct flock lock;
00072 lock.l_type = type;
00073 lock.l_start = 0;
00074 lock.l_whence = SEEK_SET;
00075 lock.l_len = 0;
00076
00077 return fcntl(g_lock_fd, cmd, &lock);
00078 }
00079
00080 #define read_lock() lock_reg(F_SETLK, F_RDLCK)
00081 #define readw_lock() lock_reg(F_SETLKW, F_RDLCK)
00082 #define write_lock() lock_reg(F_SETLK, F_WRLCK)
00083 #define writew_lock() lock_reg(F_SETLKW, F_WRLCK)
00084 #define un_lock() lock_reg(F_SETLK, F_UNLCK)
00085
00086
00087
00088 gboolean erRegRWLockInit(void)
00089 {
00090 ERREG_RWLOCK_LOGPRINTF("entry");
00091 g_assert(g_lock_fd < 0);
00092
00093 gboolean bRet = FALSE;
00094 int rc;
00095
00096
00097 rc = pthread_mutex_init(&(g_mutex), NULL);
00098 if (rc != 0)
00099 {
00100
00101 ERREG_RWLOCK_ERRORPRINTF("Could not initialize mutex, error [%d] [%s]", rc, strerror(rc));
00102 g_assert_not_reached();
00103 }
00104 else
00105 {
00106
00107 g_lock_fd = open(DATADIR LOCK_FILE, O_RDWR | O_CREAT);
00108 if (g_lock_fd < 0)
00109 {
00110
00111 ERREG_RWLOCK_ERRORPRINTF("Could not open file [%s], error [%d] [%s]", DATADIR LOCK_FILE, errno, strerror(errno));
00112 g_assert_not_reached();
00113 }
00114 else
00115 {
00116
00117 bRet = TRUE;
00118 }
00119 }
00120
00121 g_lock_state = lock_none;
00122 return bRet;
00123 }
00124
00125
00126 void erRegRWLockDestroy(void)
00127 {
00128 ERREG_RWLOCK_LOGPRINTF("entry");
00129 g_assert(g_lock_fd >= 0);
00130
00131 int rc;
00132
00133
00134 rc = close(g_lock_fd);
00135 if (rc != 0)
00136 {
00137
00138 ERREG_RWLOCK_ERRORPRINTF("Could not close file, error [%d] [%s]", errno, strerror(errno));
00139 g_assert_not_reached();
00140 }
00141 g_lock_fd = -1;
00142
00143
00144 rc = pthread_mutex_destroy(&(g_mutex));
00145 if (rc != 0)
00146 {
00147
00148 ERREG_RWLOCK_ERRORPRINTF("Could not destroy mutex, error [%d] [%s]", rc, strerror(rc));
00149 g_assert_not_reached();
00150 }
00151
00152 g_lock_state = lock_none;
00153 }
00154
00155
00156 gboolean erRegReadLock(void)
00157 {
00158 ERREG_RWLOCK_LOGPRINTF("entry");
00159 g_assert(g_lock_fd >= 0);
00160
00161 gboolean bRet = FALSE;
00162 int rc;
00163
00164
00165 rc = pthread_mutex_lock(&g_mutex);
00166 if (rc != 0)
00167 {
00168
00169 ERREG_RWLOCK_ERRORPRINTF("Could not lock mutex, error [%d] [%s]", rc, strerror(rc));
00170 g_assert_not_reached();
00171 }
00172 else
00173 {
00174
00175 rc = readw_lock();
00176 if (rc == -1)
00177 {
00178
00179 ERREG_RWLOCK_ERRORPRINTF("Could not lock file, error [%d] [%s]", errno, strerror(errno));
00180 g_assert_not_reached();
00181 }
00182 else
00183 {
00184
00185 ERREG_RWLOCK_LOGPRINTF("Obtained RLock.");
00186 g_lock_state = lock_read;
00187 bRet = TRUE;
00188 }
00189 }
00190
00191 return bRet;
00192 }
00193
00194
00195 gboolean erRegWriteLock(void)
00196 {
00197 ERREG_RWLOCK_LOGPRINTF("entry");
00198 g_assert(g_lock_fd >= 0);
00199
00200 gboolean bRet = FALSE;
00201 int rc;
00202
00203
00204 rc = pthread_mutex_lock(&g_mutex);
00205 if (rc != 0)
00206 {
00207
00208 ERREG_RWLOCK_ERRORPRINTF("Could not lock mutex, error [%d] [%s]", rc, strerror(rc));
00209 g_assert_not_reached();
00210 }
00211 else
00212 {
00213
00214 rc = writew_lock();
00215 if (rc == -1)
00216 {
00217
00218 ERREG_RWLOCK_ERRORPRINTF("Could not lock file, error [%d] [%s]", errno, strerror(errno));
00219 g_assert_not_reached();
00220 }
00221 else
00222 {
00223
00224 ERREG_RWLOCK_LOGPRINTF("Obtained WLock");
00225 g_lock_state = lock_write;
00226 bRet = TRUE;
00227 }
00228 }
00229
00230 return bRet;
00231 }
00232
00233
00234 gboolean erRegUnlock(void)
00235 {
00236 ERREG_RWLOCK_LOGPRINTF("entry");
00237 g_assert(g_lock_fd >= 0);
00238
00239 gboolean bRet = FALSE;
00240 int rc;
00241
00242
00243 rc = un_lock();
00244 if (rc == -1)
00245 {
00246
00247 ERREG_RWLOCK_ERRORPRINTF("Could not release file lock, error [%d] [%s]", errno, strerror(errno));
00248 g_assert_not_reached();
00249 }
00250 else
00251 {
00252
00253 rc = pthread_mutex_unlock(&g_mutex);
00254 if (rc != 0)
00255 {
00256
00257 ERREG_RWLOCK_ERRORPRINTF("Could not release mutex, error [%d] [%s]", rc, strerror(rc));
00258 g_assert_not_reached();
00259 }
00260 else
00261 {
00262
00263 ERREG_RWLOCK_LOGPRINTF("Released Lock");
00264 g_lock_state = lock_none;
00265 bRet = TRUE;
00266 }
00267 }
00268
00269 return bRet;
00270 }
00271
00272
00273 lock_state_t erRegGetLockState(void)
00274 {
00275 return g_lock_state;
00276 }