[erlang-questions] standard_error not handling eagain?

Steve Vinoski vinoski@REDACTED
Sun Aug 9 17:56:46 CEST 2015


The patch below seems to fix it, so please give it a try if you're
interested. Feedback welcomed. It requires more testing, as well as adding
Kota's test to the suite to prevent regressions. I'll do that later and
send in a PR.

--steve


diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index b036b20..adb449e 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -2527,7 +2527,7 @@ fd_async(void *async_data)
     SysIOVec      *iov0;
     SysIOVec      *iov;
     int            iovlen;
-    int            err;
+    int            err = 0;
     /* much of this code is stolen from efile_drv:invoke_writev */
     driver_pdl_lock(dd->blocking->pdl);
     iov0 = driver_peekq(dd->port_num, &iovlen);
@@ -2542,8 +2542,11 @@ fd_async(void *async_data)
         memcpy(iov,iov0,iovlen*sizeof(SysIOVec));
         driver_pdl_unlock(dd->blocking->pdl);

-        res = writev(dd->ofd, iov, iovlen);
-        err = errno;
+        do {
+            res = writev(dd->ofd, iov, iovlen);
+        } while (res < 0 && errno == EINTR);
+        if (res < 0)
+            err = errno;

         erts_free(ERTS_ALC_T_SYS_WRITE_BUF, iov);
     }
@@ -2582,7 +2585,12 @@ void fd_ready_async(ErlDrvData drv_data,
             return /* 0; */;
         }
     } else if (dd->blocking->res < 0) {
-        driver_failure_posix(port_num, dd->blocking->err);
+        if (dd->blocking->err == EAGAIN) {
+            set_busy_port(port_num, 1);
+            /* still data left to write in queue */
+            driver_async(port_num, &dd->blocking->pkey, fd_async, dd,
NULL);
+        } else
+            driver_failure_posix(port_num, dd->blocking->err);
         return; /* -1; */
     }
     return; /* 0; */




On Sun, Aug 9, 2015 at 11:03 AM, José Valim <jose.valim@REDACTED
> wrote:

> Thanks for a report that includes a way to reproduce the issue!
>
> For reference, this has been reported a couple days ago as well:
> http://erlang.org/pipermail/erlang-questions/2015-August/085375.html
>
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> On Sun, Aug 9, 2015 at 2:53 PM, UENISHI Kota <kuenishi@REDACTED> wrote:
>
>> Hi folks,
>> I'm asking here as I'm not sure how it should be although this looks
>> like a bug to me.  Reproduced in MacOS (mine is 10.10.4) AND 18.0
>> (maint-18 HEAD), but couldn't reproduce in Linux (Ubuntu 14.04) with
>> 18.0 or R16B02 with Mac.
>>
>> To reproduce, it's pretty easy: just print out to standard_error by
>> using io:put_char/1 or io:format/3, with writing a long iolist at
>> least more than a thousand characters [1]:
>>
>> main(_) ->
>>     Arg0 = [ [["1234567890" || _ <- [1,2,3,4,5,6,7,8,9,0]], 32,
>> integer_to_list(L), $\n]
>>              || L <- lists:seq(1, 200) ],
>>     io:format(standard_error, "~p~n", [whereis(standard_error)]),
>>     R = io:put_chars(standard_error, Arg0),
>>     io:format(standard_error, "~p, ~p~n", [R, whereis(standard_error)]).
>>
>> My result of this code is also copied in that gist [2].
>>
>> This phenomena seems to happen when writing a long buffer to FD 2 via
>> port driver  and suddenly gets EAGAIN back, and the port exits with
>> that error. I believe standard_error should not exit but should retry
>> writing when eagain or eintr was received. Thoughts?
>>
>> [1] https://gist.github.com/kuenishi/76333a8a93bc8ccad308#file-stderr-erl
>> [2]
>> https://gist.github.com/kuenishi/76333a8a93bc8ccad308#file-otp-18-0-maint-18-head
>>
>> --
>> UENISHI Kota :-)
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150809/2c395f74/attachment.htm>


More information about the erlang-questions mailing list