diff options
author | Lukas Larsson <[email protected]> | 2014-06-26 18:50:51 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2014-10-16 17:55:56 +0200 |
commit | 2e84a2ab5e0f0c82c2d79f69cd2f4bff762762a4 (patch) | |
tree | 1e01c1362e398f3df93b681c1eda4fb3cfbe9fbe /erts/emulator/sys/unix/sys.c | |
parent | 1af8998028f77b4ca01c52972a5983b072ef02d1 (diff) | |
download | otp-2e84a2ab5e0f0c82c2d79f69cd2f4bff762762a4.tar.gz otp-2e84a2ab5e0f0c82c2d79f69cd2f4bff762762a4.tar.bz2 otp-2e84a2ab5e0f0c82c2d79f69cd2f4bff762762a4.zip |
erts: Make tty driver non-blocking
Instead of using blocking call to fwrite, the tty driver
now uses non-blocking calls to writev and queues any output
data that cannot be written into the driver queue. Without
this change an stdout write could block an entire scheduler
if for some reason the pseudo tty on the other side does not
consume the output of the Erlang shell.
OTP-12239
Diffstat (limited to 'erts/emulator/sys/unix/sys.c')
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index c3d7440409..ad8b60fe7c 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -34,6 +34,7 @@ #include <termios.h> #include <ctype.h> #include <sys/utsname.h> +#include <sys/select.h> #ifdef ISC32 #include <sys/bsdtypes.h> @@ -2658,18 +2659,30 @@ void sys_preload_end(Preload* p) /* Nothing */ } -/* Read a key from console (?) */ - +/* Read a key from console, used by break.c + Here we assume that all schedulers are stopped so that erl_poll + does not interfere with the select below. +*/ int sys_get_key(fd) int fd; { - int c; + int c, ret; unsigned char rbuf[64]; + fd_set fds; fflush(stdout); /* Flush query ??? */ - if ((c = read(fd,rbuf,64)) <= 0) { - return c; + FD_ZERO(&fds); + FD_SET(fd,&fds); + + ret = select(fd+1, &fds, NULL, NULL, NULL); + + if (ret == 1) { + do { + c = read(fd,rbuf,64); + } while (c < 0 && errno == EAGAIN); + if (c <= 0) + return c; } return rbuf[0]; |