From 1737ce5da35d23f4a701d2ab20b2bec84f2177dd Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Thu, 15 Mar 2001 22:23:43 +0000 Subject: [PATCH] Changed locking mechanism of the bucket library to fcntl() instead of flock() as the flock locks have totally broken semantics -- they happily permit multiple locks on a shared fd! --- lib/bucket.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/bucket.c b/lib/bucket.c index d5733c59..abe97672 100644 --- a/lib/bucket.c +++ b/lib/bucket.c @@ -43,25 +43,46 @@ static void CONSTRUCTOR obuck_init_config(void) static void obuck_broken(char *msg) { - die("Object pool corrupted: %s (pos=%Lx)", msg, (long long) bucket_start); /* FIXME */ + die("Object pool corrupted: %s (pos=%Lx)", msg, (long long) bucket_start); +} + +/* + * Unfortunately we cannot use flock() here since it happily permits + * locking a shared fd (e.g., after fork()) multiple times. The fcntl + * locks are very ugly and they don't support 64-bit offsets, but we + * can work around the problem by always locking the first header + * in the file. + */ + +static inline void +obuck_do_lock(int type) +{ + struct flock fl; + + fl.l_type = type; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = sizeof(struct obuck_header); + if (fcntl(obuck_fd, F_SETLKW, &fl) < 0) + die("fcntl lock: %m"); } static inline void obuck_lock_read(void) { - flock(obuck_fd, LOCK_SH); + obuck_do_lock(F_RDLCK); } static inline void obuck_lock_write(void) { - flock(obuck_fd, LOCK_EX); + obuck_do_lock(F_WRLCK); } static inline void obuck_unlock(void) { - flock(obuck_fd, LOCK_UN); + obuck_do_lock(F_UNLCK); } /*** FastIO emulation ***/ @@ -163,7 +184,7 @@ obuck_cleanup(void) bclose(obuck_fb); } -void /* FIXME: Call somewhere :) */ +void obuck_sync(void) { bflush(obuck_fb); -- 2.39.2