diff --git a/io/io_tryread.c b/io/io_tryread.c index 81cae8e..747584e 100644 --- a/io/io_tryread.c +++ b/io/io_tryread.c @@ -105,8 +105,10 @@ int64 io_tryread(int64 d,char* buf,int64 len) { if (!e->nonblock) { setitimer(ITIMER_REAL,&old,0); } - if (r==-1 && errno==EAGAIN) + if (r==-1 && errno==EAGAIN) { + if (e->goterror) r=-3; io_eagain_read(d); + } if (r==-1) { if (errno==EINTR) errno=EAGAIN; if (errno!=EAGAIN) diff --git a/io/io_waituntil2.c b/io/io_waituntil2.c index 3cb1d61..d6862f4 100644 --- a/io/io_waituntil2.c +++ b/io/io_waituntil2.c @@ -167,6 +167,7 @@ int64 io_waituntil2(int64 milliseconds) { /* error; signal whatever app is looking for */ if (e->wantread) y[i].events|=POLLIN; if (e->wantwrite) y[i].events|=POLLOUT; + e->goterror=1; // prevent busy loop if the kernel return EAGAIN on read } newevents=0; diff --git a/io_internal.h b/io_internal.h index 02341e5..c38e87b 100644 --- a/io_internal.h +++ b/io_internal.h @@ -49,6 +49,7 @@ typedef struct { unsigned int epolladded:1; unsigned int closed:1; /* io_close called, but close deferred because of outstanding events */ unsigned int zerocopy:1; /* linux: setsockopt SO_ZEROCOPY done */ + unsigned int goterror:1; /* got POLLERR|POLLHUP */ #ifdef __MINGW32__ unsigned int readqueued:2; unsigned int writequeued:2;