Make SIGSTOP working for sleeps done while waiting for fifo readers or
writers in open(2), when the fifo is located on an NFS mount. Reported by: bde Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
9cac79b378
commit
e3612a4c1f
@ -137,7 +137,7 @@ fifo_open(ap)
|
|||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct fifoinfo *fip;
|
struct fifoinfo *fip;
|
||||||
struct pipe *fpipe;
|
struct pipe *fpipe;
|
||||||
int error;
|
int error, stops_deferred;
|
||||||
|
|
||||||
vp = ap->a_vp;
|
vp = ap->a_vp;
|
||||||
fp = ap->a_fp;
|
fp = ap->a_fp;
|
||||||
@ -188,8 +188,11 @@ fifo_open(ap)
|
|||||||
if ((ap->a_mode & O_NONBLOCK) == 0) {
|
if ((ap->a_mode & O_NONBLOCK) == 0) {
|
||||||
if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
|
if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
|
||||||
VOP_UNLOCK(vp, 0);
|
VOP_UNLOCK(vp, 0);
|
||||||
|
stops_deferred = sigallowstop();
|
||||||
error = msleep(&fip->fi_readers, PIPE_MTX(fpipe),
|
error = msleep(&fip->fi_readers, PIPE_MTX(fpipe),
|
||||||
PDROP | PCATCH | PSOCK, "fifoor", 0);
|
PDROP | PCATCH | PSOCK, "fifoor", 0);
|
||||||
|
if (stops_deferred)
|
||||||
|
sigdeferstop();
|
||||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
if (error) {
|
if (error) {
|
||||||
fip->fi_readers--;
|
fip->fi_readers--;
|
||||||
@ -212,8 +215,11 @@ fifo_open(ap)
|
|||||||
}
|
}
|
||||||
if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
|
if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
|
||||||
VOP_UNLOCK(vp, 0);
|
VOP_UNLOCK(vp, 0);
|
||||||
|
stops_deferred = sigallowstop();
|
||||||
error = msleep(&fip->fi_writers, PIPE_MTX(fpipe),
|
error = msleep(&fip->fi_writers, PIPE_MTX(fpipe),
|
||||||
PDROP | PCATCH | PSOCK, "fifoow", 0);
|
PDROP | PCATCH | PSOCK, "fifoow", 0);
|
||||||
|
if (stops_deferred)
|
||||||
|
sigdeferstop();
|
||||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
if (error) {
|
if (error) {
|
||||||
fip->fi_writers--;
|
fip->fi_writers--;
|
||||||
|
@ -2587,15 +2587,18 @@ sigdeferstop(void)
|
|||||||
* not immediately suspend if a stop was posted. Instead, the thread
|
* not immediately suspend if a stop was posted. Instead, the thread
|
||||||
* will suspend either via ast() or a subsequent interruptible sleep.
|
* will suspend either via ast() or a subsequent interruptible sleep.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
sigallowstop()
|
sigallowstop(void)
|
||||||
{
|
{
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
|
int prev;
|
||||||
|
|
||||||
td = curthread;
|
td = curthread;
|
||||||
thread_lock(td);
|
thread_lock(td);
|
||||||
|
prev = (td->td_flags & TDF_SBDRY) != 0;
|
||||||
td->td_flags &= ~TDF_SBDRY;
|
td->td_flags &= ~TDF_SBDRY;
|
||||||
thread_unlock(td);
|
thread_unlock(td);
|
||||||
|
return (prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -325,7 +325,7 @@ extern struct mtx sigio_lock;
|
|||||||
|
|
||||||
int cursig(struct thread *td);
|
int cursig(struct thread *td);
|
||||||
int sigdeferstop(void);
|
int sigdeferstop(void);
|
||||||
void sigallowstop(void);
|
int sigallowstop(void);
|
||||||
void execsigs(struct proc *p);
|
void execsigs(struct proc *p);
|
||||||
void gsignal(int pgid, int sig, ksiginfo_t *ksi);
|
void gsignal(int pgid, int sig, ksiginfo_t *ksi);
|
||||||
void killproc(struct proc *p, char *why);
|
void killproc(struct proc *p, char *why);
|
||||||
|
Loading…
Reference in New Issue
Block a user