-/* $Id: flock.c,v 1.14 2006-07-03 09:50:51 adam Exp $
- Copyright (C) 1995-2006
- Index Data ApS
-
-This file is part of the Zebra server.
+/* This file is part of the Zebra server.
+ Copyright (C) Index Data
Zebra is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
for more details.
You should have received a copy of the GNU General Public License
-along with Zebra; see the file LICENSE.zebra. If not, write to the
-Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
*/
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <yaz/xmalloc.h>
#include <yaz/log.h>
-/** whether this module should debug */
-#define DEBUG_FLOCK 1
-
/** have this module (mutex) been initialized? */
static int initialized = 0;
-/** whether fcntl locks are shared for all threads in a process */
+/** whether fcntl locks are shared for all threads in a process (POSIX) */
static int posix_locks = 1;
/** mutex for lock_list below */
{
int dlen = dir ? strlen(dir) : 0;
char *fname = xmalloc(dlen + strlen(name) + 3);
-
+
#ifdef WIN32
if (dlen)
{
int last_one = dir[dlen-1];
-
+
if (!strchr("/\\:", last_one))
sprintf(fname, "%s\\%s", dir, name);
else
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;
#ifdef WIN32
p->fd = open(name, O_BINARY|O_RDONLY);
if (p->fd == -1)
{
xfree(p);
- yaz_log(YLOG_WARN | YLOG_ERRNO,
+ yaz_log(YLOG_WARN | YLOG_ERRNO,
"zebra_lock_create fail fname=%s", fname);
p = 0;
}
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;
+ int r = 0;
int do_lock = 0;
- yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s begin",
+ yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s begin",
h->p->fd, h, h->p->fname);
#ifdef WIN32
h->write_flag = 1;
#endif
- yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s end",
+ yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s end",
h->p->fd, h, h->p->fname);
return r;
int zebra_lock_r(ZebraLockHandle h)
{
- int r;
+ int r = 0;
int do_lock = 0;
- yaz_log(log_level, "zebra_lock_r fd=%d p=%p fname=%s begin",
+ yaz_log(log_level, "zebra_lock_r 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)))
assert(posix_locks);
}
zebra_mutex_unlock(&h->p->file_mutex);
-
+
h->write_flag = 0;
#endif
- yaz_log(log_level, "zebra_lock_r fd=%d p=%p fname=%s end",
+ yaz_log(log_level, "zebra_lock_r fd=%d p=%p fname=%s end",
h->p->fd, h, h->p->fname);
return r;
}
int zebra_unlock(ZebraLockHandle h)
{
int r = 0;
- int do_unlock = 0;
yaz_log(log_level, "zebra_unlock fd=%d p=%p fname=%s begin",
h->p->fd, h, h->p->fname);
#ifdef WIN32
#else
zebra_mutex_lock(&h->p->file_mutex);
if (h->write_flag)
- h->p->no_file_write_lock--;
+ {
+ if (h->p->no_file_write_lock > 0)
+ 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_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);
else
{
+ r = 0;
assert(posix_locks);
}
+
zebra_mutex_unlock(&h->p->file_mutex);
if (posix_locks)
return r;
}
-#if HAVE_CONFSTR
-static int test_for_linuxthreads()
+/** \brief see if the fcntl locking is not POSIX
+ *
+ * The default posix_locks=1 is assumed.. This function sets posix_locks
+ * to zero if linuxthreads is in use.
+ */
+static int check_for_linuxthreads(void)
{
+#if __linux
+#ifdef _CS_GNU_LIBPTHREAD_VERSION
char conf_buf[512];
- size_t r;
-
- r = confstr(_CS_GNU_LIBPTHREAD_VERSION, conf_buf, sizeof(conf_buf));
+ size_t r = confstr(_CS_GNU_LIBPTHREAD_VERSION, conf_buf, sizeof(conf_buf));
if (r == 0)
{
yaz_log(YLOG_WARN|YLOG_ERRNO, "confstr failed");
return -1;
}
if (strncmp(conf_buf, "linuxthreads", 12) == 0)
- posix_locks = 0;
+ posix_locks = 0; /* Using linuxthreads.. */
+#else
+ posix_locks = 0; /* Old GLIBC on Linux. Assume linuxthreads */
+#endif
+#endif
return 0;
}
-#endif
void zebra_flock_init()
{
{
initialized = 1;
log_level = yaz_log_module_level("flock");
-#if DEBUG_FLOCK
- log_level = YLOG_LOG|YLOG_FLUSH;
-#endif
-#if HAVE_CONFSTR
- test_for_linuxthreads();
-#endif
+ yaz_log(log_level, "zebra_flock_init");
+ check_for_linuxthreads();
zebra_mutex_init(&lock_list_mutex);
yaz_log(log_level, "posix_locks: %d", posix_locks);
}
- yaz_log(log_level, "zebra_flock_init");
}
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab