NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/57659: closing pipe writefd fails to wake concurrent write on same writefd
>Number: 57659
>Category: kern
>Synopsis: closing pipe writefd fails to wake concurrent write on same writefd
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Oct 15 11:05:00 +0000 2023
>Originator: Taylor R Campbell
>Release: current
>Organization:
The NetBSD Fdation
>Environment:
>Description:
If a write system call on a pipe's writefd is blocking because the pipe is full, a concurrent close system call must wake the write system call and cause it to fail with EBADF.
But it doesn't; the write system call seems to hang indefinitely.
This happens before and after sys_pipe.c 1.165:
https://mail-index.netbsd.org/source-changes/2023/10/13/msg148107.html
>How-To-Repeat:
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
pthread_barrier_t barrier;
int fd;
static void
waitforbarrier(const char *caller)
{
int error;
error = pthread_barrier_wait(&barrier);
switch (error) {
case 0:
case PTHREAD_BARRIER_SERIAL_THREAD:
break;
default:
errc(1, error, "%s: pthread_barrier_wait", caller);
}
}
static void *
start(void *cookie)
{
static const char buf[1024*1024]; /* XXX >BIG_PIPE_SIZE */
ssize_t nwrit;
waitforbarrier("user");
nwrit = write(fd, buf, sizeof(buf));
if (nwrit != -1) /* buffer filled, try more */
nwrit = write(fd, buf, sizeof(buf));
assert(nwrit == -1);
assert(errno == EBADF);
return NULL;
}
int
main(void)
{
int p[2];
pthread_t t;
int error;
if (pipe(p) == -1)
err(1, "pipe");
fd = p[1];
error = pthread_barrier_init(&barrier, NULL, 2);
if (error)
errc(1, error, "pthread_barrier_init");
error = pthread_create(&t, NULL, &start, NULL);
if (error)
errc(1, error, "pthread_create");
waitforbarrier("closer");
sleep(1);
alarm(1);
if (close(fd) == -1)
err(1, "close");
error = pthread_join(t, NULL);
if (error)
errc(1, error, "pthread_join");
return 0;
}
>Fix:
Yes, please!
Home |
Main Index |
Thread Index |
Old Index