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 [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to