Skip to content

Commit 93a4f5b

Browse files
committed
Fix blocking stdout/stderr capture on Windows
- remove useless `ioctlsocket` on a file decriptor which is not a socket. See the Microsoft [_pipe documentation](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/pipe?view=msvc-160): > A pipe resembles a file because it has a file pointer, a file descriptor, or both, and it can be read from or written to by using the Standard Library input and output functions. However, a pipe does not represent a specific file or device. Instead, it represents temporary storage in memory that is independent of the program's own memory and is controlled entirely by the operating system. - use a large buffer and use `_fstat` on the file decriptor to check if there is something to read from the pipe. This to prevent blocking. See also the Microsoft [_pipe documentation](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/pipe?view=msvc-160): > All read and write operations on the pipe wait until there is enough data or enough buffer space to complete the I/O request.
1 parent ef81ad1 commit 93a4f5b

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

bindings/jupyroot/src/IOHandler.cxx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,25 @@ JupyROOTExecutorHandler::JupyROOTExecutorHandler() {}
7171

7272
static void PollImpl(FILE *stdStream, int *pipeHandle, std::string &pipeContent)
7373
{
74+
fflush(stdStream);
75+
#ifdef _MSC_VER
76+
char buffer[60000] = "";
77+
struct _stat st;
78+
_fstat(pipeHandle[0], &st);
79+
if (st.st_size) {
80+
_read(pipeHandle[0], buffer, 60000);
81+
pipeContent += buffer;
82+
}
83+
#else
7484
int buf_read;
7585
char ch;
76-
fflush(stdStream);
7786
while (true) {
7887
buf_read = read(pipeHandle[0], &ch, 1);
7988
if (buf_read == 1) {
8089
pipeContent += ch;
8190
} else break;
8291
}
92+
#endif
8393
}
8494

8595
void JupyROOTExecutorHandler::Poll()
@@ -94,10 +104,7 @@ static void InitCaptureImpl(int &savedStdStream, int *pipeHandle, int FILENO)
94104
if (pipe(pipeHandle) != 0) {
95105
return;
96106
}
97-
#ifdef _MSC_VER // Visual Studio
98-
unsigned long mode = 1;
99-
ioctlsocket(pipeHandle[0], FIONBIO, &mode);
100-
#else
107+
#ifndef _MSC_VER
101108
long flags_stdout = fcntl(pipeHandle[0], F_GETFL);
102109
if (flags_stdout == -1) return;
103110
flags_stdout |= O_NONBLOCK;

0 commit comments

Comments
 (0)