aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSteve Vinoski <[email protected]>2015-08-10 08:34:28 -0400
committerLukas Larsson <[email protected]>2015-08-18 16:25:28 +0200
commitba8740af39b7d4c612b2ee55e3bad6fbdcaf1418 (patch)
treee04ea41c953fdfb1af6cb0177fc86e6ca3243b9a /lib
parent61828f77ca2542109ece006d730a4f8fe3300616 (diff)
downloadotp-ba8740af39b7d4c612b2ee55e3bad6fbdcaf1418.tar.gz
otp-ba8740af39b7d4c612b2ee55e3bad6fbdcaf1418.tar.bz2
otp-ba8740af39b7d4c612b2ee55e3bad6fbdcaf1418.zip
Handle ERRNO_BLOCK in fd_driver async functions
Several users on erlang-questions have reported problems with recent releases where output to standard_error causes standard_error_sup to die from receiving an unexpected eagain error. In the fd_driver, change the fd_async() function to handle EINTR, and change fd_ready_async() to handle ERRNO_BLOCK. Add a new test to standard_error_SUITE to generate output to standard_error and ensure that standard_error_sup does not die. Thanks to Kota Uenishi for contributing the test case.
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/test/standard_error_SUITE.erl31
1 files changed, 29 insertions, 2 deletions
diff --git a/lib/kernel/test/standard_error_SUITE.erl b/lib/kernel/test/standard_error_SUITE.erl
index e8917bbd47..97ead9b9fd 100644
--- a/lib/kernel/test/standard_error_SUITE.erl
+++ b/lib/kernel/test/standard_error_SUITE.erl
@@ -21,13 +21,13 @@
-module(standard_error_SUITE).
-export([all/0,suite/0]).
--export([badarg/1,getopts/1]).
+-export([badarg/1,getopts/1,output/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
all() ->
- [badarg,getopts].
+ [badarg,getopts,output].
badarg(Config) when is_list(Config) ->
{'EXIT',{badarg,_}} = (catch io:put_chars(standard_error, [oops])),
@@ -37,3 +37,30 @@ badarg(Config) when is_list(Config) ->
getopts(Config) when is_list(Config) ->
[{encoding,latin1}] = io:getopts(standard_error),
ok.
+
+%% Test that writing a lot of output to standard_error does not cause the
+%% processes handling it to terminate like this:
+%%
+%% =ERROR REPORT==== 9-Aug-2015::23:19:23 ===
+%% ** Generic server standard_error_sup terminating
+%% ** Last message in was {'EXIT',<0.28.0>,eagain}
+%% ** When Server state == {state,standard_error,undefined,<0.28.0>,
+%% {local,standard_error_sup}}
+%% ** Reason for termination ==
+%% ** eagain
+%%
+%% This problem, observed with Erlang 18.0.2, was fixed in fd_driver by
+%% properly handling EAGAIN if it arises on file descriptor writes.
+%%
+output(Config) when is_list(Config) ->
+ Ref = monitor(process, standard_error_sup),
+ Chars = [ [["1234567890" || _ <- lists:seq(1,10)], $\s,
+ integer_to_list(L), $\r, $\n] || L <- lists:seq(1, 100) ],
+ ok = io:put_chars(standard_error, Chars),
+ receive
+ {'DOWN', Ref, process, _, _} ->
+ error(standard_error_noproc)
+ after
+ 500 ->
+ ok
+ end.