X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=util%2Fflock.c;h=42dd067103b2e9cde02b8e39ff9a3f292dd59402;hb=4f8332e37fadf4306abe2b8f4a0e9442c7450d0f;hp=49537414b2afb66c1e5c0f81ce78d1ae981fbb03;hpb=bd3a317131488141726cedfba9f86b9e479c5385;p=idzebra-moved-to-github.git diff --git a/util/flock.c b/util/flock.c index 4953741..42dd067 100644 --- a/util/flock.c +++ b/util/flock.c @@ -1,4 +1,4 @@ -/* $Id: flock.c,v 1.8 2006-06-27 11:56:29 adam Exp $ +/* $Id: flock.c,v 1.13 2006-06-30 15:10:20 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -40,6 +40,18 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include +/** whether lock file desciptors are shared within one process' threads */ +#define ZEBRA_FLOCK_SHARE_FD_IN_THREADS 1 + +/** whether we always lock on the file - even if rd/wr locks should do */ +#define ZEBRA_FLOCK_FILE_LOCK_ALWAYS 1 + +/** whether we should also use pthreads locking to do "extra" rd/wr locks */ +#define ZEBRA_FLOCK_EXTRA_RDWR_LOCKS 1 + +/** whether this module should debug */ +#define DEBUG_FLOCK 0 + /** have this module (mutex) been initialized? */ static int initialized = 0; @@ -69,7 +81,9 @@ struct zebra_lock_info { /** number of file write locks/read locks */ int no_file_write_lock; int no_file_read_lock; +#if ZEBRA_FLOCK_EXTRA_RDWR_LOCKS Zebra_lock_rdwr rdwr_lock; +#endif Zebra_mutex file_mutex; #endif /** next in lock list */ @@ -114,17 +128,22 @@ char *zebra_mk_fname(const char *dir, const char *name) ZebraLockHandle zebra_lock_create(const char *dir, const char *name) { char *fname = zebra_mk_fname(dir, name); - struct zebra_lock_info *p; + struct zebra_lock_info *p = 0; ZebraLockHandle h = 0; assert(initialized); zebra_mutex_lock(&lock_list_mutex); + /* see if we have the same filename in a global list of "lock files" */ +#ifndef WIN32 +#if ZEBRA_FLOCK_SHARE_FD_IN_THREADS for (p = lock_list; p ; p = p->next) if (!strcmp(p->fname, fname)) break; +#endif +#endif if (!p) - { + { /* didn't match (or we didn't want it to match! */ p = (struct zebra_lock_info *) xmalloc(sizeof(*p)); p->ref_count = 0; @@ -146,10 +165,10 @@ ZebraLockHandle zebra_lock_create(const char *dir, const char *name) { p->fname = fname; fname = 0; /* fname buffer now owned by p->fname */ - yaz_log(log_level, "zebra_lock_create fd=%d p=%p fname=%s", - p->fd, p, p->fname); #ifndef WIN32 +#if ZEBRA_FLOCK_EXTRA_RDWR_LOCKS zebra_lock_rdwr_init(&p->rdwr_lock); +#endif zebra_mutex_init(&p->file_mutex); p->no_file_write_lock = 0; p->no_file_read_lock = 0; @@ -160,10 +179,15 @@ ZebraLockHandle zebra_lock_create(const char *dir, const char *name) } if (p) { + /* we have lock info so we can make a handle pointing to that */ p->ref_count++; h = (ZebraLockHandle) xmalloc(sizeof(*h)); h->p = p; +#ifndef WIN32 h->write_flag = 0; +#endif + yaz_log(log_level, "zebra_lock_create fd=%d p=%p fname=%s", + h->p->fd, h, p->fname); } zebra_mutex_unlock(&lock_list_mutex); xfree(fname); /* free it - if it's still there */ @@ -178,12 +202,13 @@ void zebra_lock_destroy(ZebraLockHandle h) yaz_log(log_level, "zebra_lock_destroy fd=%d p=%p fname=%s", h->p->fd, h, h->p->fname); zebra_mutex_lock(&lock_list_mutex); - yaz_log(log_level, "zebra_lock_destroy fd=%d p=%p fname=%s 1", - h->p->fd, h, h->p->fname); + yaz_log(log_level, "zebra_lock_destroy fd=%d p=%p fname=%s refcount=%d", + h->p->fd, h, h->p->fname, h->p->ref_count); assert(h->p->ref_count > 0); --(h->p->ref_count); if (h->p->ref_count == 0) { + /* must remove shared info from lock_list */ struct zebra_lock_info **hp = &lock_list; while (*hp) { @@ -195,8 +220,14 @@ void zebra_lock_destroy(ZebraLockHandle h) else hp = &(*hp)->next; } + + yaz_log(log_level, "zebra_lock_destroy fd=%d p=%p fname=%s remove", + h->p->fd, h, h->p->fname); + #ifndef WIN32 +#if ZEBRA_FLOCK_EXTRA_RDWR_LOCKS zebra_lock_rdwr_destroy(&h->p->rdwr_lock); +#endif zebra_mutex_destroy(&h->p->file_mutex); #endif if (h->p->fd != -1) @@ -212,57 +243,82 @@ void zebra_lock_destroy(ZebraLockHandle h) static int unixLock(int fd, int type, int cmd) { struct flock area; + int r; area.l_type = type; area.l_whence = SEEK_SET; area.l_len = area.l_start = 0L; - return fcntl(fd, cmd, &area); + + yaz_log(log_level, "fcntl begin type=%d fd=%d", type, fd); + r = fcntl(fd, cmd, &area); + if (r == -1) + yaz_log(YLOG_WARN|YLOG_ERRNO, "fcntl FAIL type=%d fd=%d", type, fd); + else + yaz_log(log_level, "fcntl type=%d OK fd=%d", type, fd); + + return r; } #endif int zebra_lock_w(ZebraLockHandle h) { int r; - yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s", + int do_lock = ZEBRA_FLOCK_FILE_LOCK_ALWAYS; + yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s begin", h->p->fd, h, h->p->fname); - + #ifdef WIN32 while ((r = _locking(h->p->fd, _LK_LOCK, 1))) ; #else +#if ZEBRA_FLOCK_EXTRA_RDWR_LOCKS + zebra_lock_rdwr_wlock(&h->p->rdwr_lock); +#endif + zebra_mutex_lock(&h->p->file_mutex); if (h->p->no_file_write_lock == 0) + do_lock = 1; + h->p->no_file_write_lock++; + if (do_lock) { /* if there is already a read lock.. upgrade to write lock */ r = unixLock(h->p->fd, F_WRLCK, F_SETLKW); } - h->p->no_file_write_lock++; zebra_mutex_unlock(&h->p->file_mutex); - zebra_lock_rdwr_wlock(&h->p->rdwr_lock); -#endif h->write_flag = 1; + yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s end", + h->p->fd, h, h->p->fname); +#endif + return r; } int zebra_lock_r(ZebraLockHandle h) { int r; + int do_lock = ZEBRA_FLOCK_FILE_LOCK_ALWAYS; + yaz_log(log_level, "zebra_lock_r fd=%d p=%p fname=%s", h->p->fd, h, h->p->fname); #ifdef WIN32 while ((r = _locking(h->p->fd, _LK_LOCK, 1))) ; #else +#if ZEBRA_FLOCK_EXTRA_RDWR_LOCKS + zebra_lock_rdwr_rlock(&h->p->rdwr_lock); +#endif + zebra_mutex_lock(&h->p->file_mutex); if (h->p->no_file_read_lock == 0 && h->p->no_file_write_lock == 0) + do_lock = 1; + h->p->no_file_read_lock++; + if (do_lock) { /* only read lock if no write locks already */ r = unixLock(h->p->fd, F_RDLCK, F_SETLKW); } - h->p->no_file_read_lock++; zebra_mutex_unlock(&h->p->file_mutex); - - zebra_lock_rdwr_rlock(&h->p->rdwr_lock); + h->write_flag = 0; #endif return r; @@ -271,26 +327,32 @@ int zebra_lock_r(ZebraLockHandle h) int zebra_unlock(ZebraLockHandle h) { int r = 0; - yaz_log(log_level, "zebra_unlock fd=%d p=%p fname=%s", + int do_unlock = ZEBRA_FLOCK_FILE_LOCK_ALWAYS; + yaz_log(log_level, "zebra_unlock fd=%d p=%p fname=%s begin", h->p->fd, h, h->p->fname); #ifdef WIN32 r = _locking(h->p->fd, _LK_UNLCK, 1); #else - if (h->write_flag) - zebra_lock_rdwr_wunlock(&h->p->rdwr_lock); - else - zebra_lock_rdwr_runlock(&h->p->rdwr_lock); - zebra_mutex_lock(&h->p->file_mutex); if (h->write_flag) h->p->no_file_write_lock--; else h->p->no_file_read_lock--; if (h->p->no_file_read_lock == 0 && h->p->no_file_write_lock == 0) - { + do_unlock = 1; + if (do_unlock) r = unixLock(h->p->fd, F_UNLCK, F_SETLKW); - } zebra_mutex_unlock(&h->p->file_mutex); + +#if ZEBRA_FLOCK_EXTRA_RDWR_LOCKS + if (h->write_flag) + zebra_lock_rdwr_wunlock(&h->p->rdwr_lock); + else + zebra_lock_rdwr_runlock(&h->p->rdwr_lock); +#endif + + yaz_log(log_level, "zebra_unlock fd=%d p=%p fname=%s end", + h->p->fd, h, h->p->fname); #endif return r; } @@ -300,9 +362,13 @@ void zebra_flock_init() if (!initialized) { log_level = yaz_log_module_level("flock"); +#if DEBUG_FLOCK + log_level = YLOG_LOG|YLOG_FLUSH; +#endif initialized = 1; zebra_mutex_init(&lock_list_mutex); } + yaz_log(log_level, "zebra_flock_init"); } /*