Pipes are now always internally opened for writing, to workaround a 'glib' behaviour, that eats 100% CPU when there is no writer anymore on a pipe watched for reading.

[INTERPRETER]
* BUG: Pipes are now always internally opened for writing, to workaround a 'glib' behaviour, that eats 100% CPU when there is no writer anymore on a pipe watched for reading.
This commit is contained in:
gambas 2021-07-14 02:08:01 +02:00
parent e08d47dd02
commit c8fe917e97
2 changed files with 19 additions and 5 deletions

View file

@ -100,6 +100,14 @@ typedef
} }
STREAM_DIRECT; STREAM_DIRECT;
typedef
struct {
STREAM_COMMON common;
int fd;
unsigned can_write : 1;
}
STREAM_PIPE;
typedef typedef
struct { struct {
STREAM_COMMON common; STREAM_COMMON common;
@ -155,7 +163,7 @@ typedef
STREAM_RESERVED _reserved; STREAM_RESERVED _reserved;
STREAM_DIRECT direct; STREAM_DIRECT direct;
STREAM_BUFFER buffer; STREAM_BUFFER buffer;
STREAM_DIRECT pipe; STREAM_PIPE pipe;
STREAM_MEMORY memory; STREAM_MEMORY memory;
STREAM_ARCH arch; STREAM_ARCH arch;
STREAM_PROCESS process; STREAM_PROCESS process;

View file

@ -56,19 +56,19 @@ static int stream_open(STREAM *stream, const char *path, int mode)
switch (mode & GB_ST_MODE) switch (mode & GB_ST_MODE)
{ {
case GB_ST_READ: fmode |= O_RDONLY | O_NONBLOCK; break; case GB_ST_READ: fmode |= O_RDWR; break;
case GB_ST_WRITE: fmode |= O_WRONLY; break; case GB_ST_WRITE: fmode |= O_WRONLY; break;
case GB_ST_READ_WRITE: fmode |= O_RDWR; break; case GB_ST_READ_WRITE: fmode |= O_RDWR; break;
default: fmode |= O_RDONLY; default: fmode |= O_RDWR;
} }
RESTART_SYSCALL(fd = open(path, fmode)) RESTART_SYSCALL(fd = open(path, fmode | O_NONBLOCK))
return TRUE; return TRUE;
if ((mode & GB_ST_MODE) == GB_ST_READ) if ((mode & GB_ST_MODE) == GB_ST_READ)
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK); fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
stream->direct.size = 0; stream->pipe.can_write = mode & GB_ST_WRITE;
FD = fd; FD = fd;
return FALSE; return FALSE;
@ -93,6 +93,12 @@ static int stream_read(STREAM *stream, char *buffer, int len)
static int stream_write(STREAM *stream, char *buffer, int len) static int stream_write(STREAM *stream, char *buffer, int len)
{ {
if (!stream->pipe.can_write)
{
errno = EBADF;
return -1;
}
return write(FD, buffer, len); return write(FD, buffer, len);
} }