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>
