Date: Sat, 30 Nov 2002 11:33:25 -0500 (EST) From: Daniel Eischen <eischen@pcnet1.pcnet.com> To: Brian Smith <dbsoft@technologist.com> Cc: Terry Lambert <tlambert2@mindspring.com>, "current@FreeBSD.ORG" <current@FreeBSD.ORG> Subject: Re: Are SysV semaphores thread-safe on CURRENT? Message-ID: <Pine.GSO.4.10.10211301128220.24768-100000@pcnet1.pcnet.com> In-Reply-To: <20021130141711.CIZH19077.mailhost.chi1.ameritech.net@bbs.dbsoft-consulting.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 30 Nov 2002, Brian Smith wrote: > On Mon, 18 Nov 2002 22:05:34 -0800, Terry Lambert wrote: > > >Use mmap of a backing-store file, and then use file locking to > >do record locking in the shared memory segment. > > Ok, I did this, and it actually works considerably better than > the SysV shared memory. However flock() has the same problem > as the SysV semaphores, where they block the entire process, > allowing the same deadlock situation to occur. Has this flock() > behavior changed in CURRENT? No, libc_r doesn't properly handle flock. Usually, all syscalls that take file descriptors as arguments honor the non-blocking mode of the file if set. I guess flock(2) doesn't and has its own option to the operation argument (LOCK_NB). I hacked libc_r to periodically check (every 100msecs) the flock. See if this fixes things: -- Dan Eischen Index: lib/libc_r/uthread/uthread_flock.c =================================================================== RCS file: /opt/d/CVS/src/lib/libc_r/uthread/uthread_flock.c,v retrieving revision 1.10 diff -u -r1.10 uthread_flock.c --- lib/libc_r/uthread/uthread_flock.c 10 Apr 2001 04:19:20 -0000 1.10 +++ lib/libc_r/uthread/uthread_flock.c 30 Nov 2002 16:23:59 -0000 @@ -32,6 +32,7 @@ * $FreeBSD: src/lib/libc_r/uthread/uthread_flock.c,v 1.10 2001/04/10 04:19:20 deischen Exp $ */ #include <sys/file.h> +#include <errno.h> #include <pthread.h> #include "pthread_private.h" @@ -40,10 +41,40 @@ int _flock(int fd, int operation) { - int ret; + struct pthread *curthread; + struct timespec ts; + int ret; if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { - ret = __sys_flock(fd, operation); + if ((operation & LOCK_NB) != 0) { + ret = __sys_flock(fd, operation); + } + else { + curthread = _get_curthread(); + ts.tv_sec = 0; + ts.tv_nsec = 100000000; /* 100msecs */ + while (((ret = __sys_flock(fd, operation | LOCK_NB)) == 0) + || (errno == EWOULDBLOCK)) { + curthread->data.fd.fd = fd; + _thread_kern_set_timeout(&ts); + + /* Reset the interrupted operation flag: */ + curthread->interrupted = 0; + + _thread_kern_sched_state(PS_SLEEP_WAIT, + __FILE__, __LINE__); + + /* + * Check if the operation was interrupted + * by a signal + */ + if (curthread->interrupted) { + errno = EINTR; + ret = -1; + break; + } + } + } _FD_UNLOCK(fd, FD_RDWR); } return (ret); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10211301128220.24768-100000>