aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/unix/sys.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2014-06-26 18:50:51 +0200
committerLukas Larsson <[email protected]>2014-10-16 17:55:56 +0200
commit2e84a2ab5e0f0c82c2d79f69cd2f4bff762762a4 (patch)
tree1e01c1362e398f3df93b681c1eda4fb3cfbe9fbe /erts/emulator/sys/unix/sys.c
parent1af8998028f77b4ca01c52972a5983b072ef02d1 (diff)
downloadotp-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.c23
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];