just use ltsleep rather than lockmgr + PCATCH with horrible timeout dance.
This commit is contained in:
parent
c14bdacc17
commit
dd80ddaf14
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sys_pipe.c,v 1.66 2005/09/11 17:55:26 christos Exp $ */
|
||||
/* $NetBSD: sys_pipe.c,v 1.67 2005/10/29 12:31:07 yamt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
@ -83,7 +83,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.66 2005/09/11 17:55:26 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.67 2005/10/29 12:31:07 yamt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -324,7 +324,6 @@ pipe_create(pipep, allockva)
|
||||
pipe->pipe_atime = pipe->pipe_ctime;
|
||||
pipe->pipe_mtime = pipe->pipe_ctime;
|
||||
simple_lock_init(&pipe->pipe_slock);
|
||||
lockinit(&pipe->pipe_lock, PSOCK | PCATCH, "pipelk", 0, 0);
|
||||
|
||||
if (allockva && (error = pipespace(pipe, PIPE_SIZE)))
|
||||
return (error);
|
||||
@ -343,40 +342,24 @@ pipelock(pipe, catch)
|
||||
struct pipe *pipe;
|
||||
int catch;
|
||||
{
|
||||
int error;
|
||||
|
||||
LOCK_ASSERT(simple_lock_held(&pipe->pipe_slock));
|
||||
|
||||
while (1) {
|
||||
error = lockmgr(&pipe->pipe_lock, LK_EXCLUSIVE | LK_INTERLOCK,
|
||||
&pipe->pipe_slock);
|
||||
if (error == 0)
|
||||
break;
|
||||
while (pipe->pipe_state & PIPE_LOCKFL) {
|
||||
int error;
|
||||
const int pcatch = catch ? PCATCH : 0;
|
||||
|
||||
simple_lock(&pipe->pipe_slock);
|
||||
if (catch || (error != EINTR && error != ERESTART))
|
||||
break;
|
||||
/*
|
||||
* XXX XXX XXX
|
||||
* The pipe lock is initialised with PCATCH on and we cannot
|
||||
* override this in a lockmgr() call. Thus a pending signal
|
||||
* will cause lockmgr() to return with EINTR or ERESTART.
|
||||
* We cannot simply re-enter lockmgr() at this point since
|
||||
* the pending signals have not yet been posted and would
|
||||
* cause an immediate EINTR/ERESTART return again.
|
||||
* As a workaround we pause for a while here, giving the lock
|
||||
* a chance to drain, before trying again.
|
||||
* XXX XXX XXX
|
||||
*
|
||||
* NOTE: Consider dropping PCATCH from this lock; in practice
|
||||
* it is never held for long enough periods for having it
|
||||
* interruptable at the start of pipe_read/pipe_write to be
|
||||
* beneficial.
|
||||
*/
|
||||
(void) ltsleep(&lbolt, PSOCK, "rstrtpipelock", hz,
|
||||
pipe->pipe_state |= PIPE_LWANT;
|
||||
error = ltsleep(pipe, PSOCK | pcatch, "pipelk", 0,
|
||||
&pipe->pipe_slock);
|
||||
if (error != 0)
|
||||
return error;
|
||||
}
|
||||
return (error);
|
||||
|
||||
pipe->pipe_state |= PIPE_LOCKFL;
|
||||
simple_unlock(&pipe->pipe_slock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -387,7 +370,13 @@ pipeunlock(pipe)
|
||||
struct pipe *pipe;
|
||||
{
|
||||
|
||||
lockmgr(&pipe->pipe_lock, LK_RELEASE, NULL);
|
||||
KASSERT(pipe->pipe_state & PIPE_LOCKFL);
|
||||
|
||||
pipe->pipe_state &= ~PIPE_LOCKFL;
|
||||
if (pipe->pipe_state & PIPE_LWANT) {
|
||||
pipe->pipe_state &= ~PIPE_LWANT;
|
||||
wakeup(pipe);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1352,8 +1341,9 @@ retry:
|
||||
PIPE_UNLOCK(ppipe);
|
||||
}
|
||||
|
||||
(void)lockmgr(&pipe->pipe_lock, LK_DRAIN | LK_INTERLOCK,
|
||||
&pipe->pipe_slock);
|
||||
KASSERT((pipe->pipe_state & PIPE_LOCKFL) == 0);
|
||||
|
||||
PIPE_UNLOCK(pipe);
|
||||
|
||||
/*
|
||||
* free resources
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pipe.h,v 1.16 2005/03/17 20:39:17 kleink Exp $ */
|
||||
/* $NetBSD: pipe.h,v 1.17 2005/10/29 12:31:07 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 John S. Dyson
|
||||
@ -94,6 +94,10 @@ struct pipemapping {
|
||||
#define PIPE_SIGNALR 0x020 /* Do selwakeup() on read(2) */
|
||||
#define PIPE_DIRECTW 0x040 /* Pipe in direct write mode setup */
|
||||
#define PIPE_DIRECTR 0x080 /* Pipe direct read request (setup complete) */
|
||||
#define PIPE_LOCKFL 0x100 /* Process has exclusive access to
|
||||
pointers/data. */
|
||||
#define PIPE_LWANT 0x200 /* Process wants exclusive access to
|
||||
pointers/data. */
|
||||
|
||||
/*
|
||||
* Per-pipe data structure.
|
||||
@ -101,7 +105,6 @@ struct pipemapping {
|
||||
*/
|
||||
struct pipe {
|
||||
struct simplelock pipe_slock; /* pipe mutex */
|
||||
struct lock pipe_lock; /* long-term pipe lock */
|
||||
struct pipebuf pipe_buffer; /* data storage */
|
||||
struct pipemapping pipe_map; /* pipe mapping for direct I/O */
|
||||
struct selinfo pipe_sel; /* for compat with select */
|
||||
|
Loading…
Reference in New Issue
Block a user