From df828dcd8e4d42eee9d88f4747cff1730151e351 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Fri, 23 Dec 2011 17:31:35 +0100
Subject: Include wakeup pipe in /dev/poll poll-set also on non-SMP

I/O events could potentially be delayed for ever when enabling
kernel-poll on a non-SMP runtime system executing on Solaris. When
also combined with async-threads the runtime system hung before
completing the boot phase. This bug was introduced in
erts-5.9/OTP-R15B.
---
 erts/emulator/sys/common/erl_poll.c     |   4 +-
 erts/emulator/test/Makefile             |   1 +
 erts/emulator/test/smoke_test_SUITE.erl | 139 ++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+), 2 deletions(-)
 create mode 100644 erts/emulator/test/smoke_test_SUITE.erl

(limited to 'erts/emulator')

diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index b6cb271f17..3817b1e4d5 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -1949,7 +1949,7 @@ check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res)
 	     */
 	    struct dvpoll poll_res;
 	    int nfds = (int) erts_smp_atomic_read_nob(&ps->no_of_user_fds);
-#ifdef ERTS_SMP
+#if ERTS_POLL_USE_WAKEUP_PIPE
 	    nfds++; /* Wakeup pipe */
 #endif
 	    if (timeout > INT_MAX)
@@ -2487,7 +2487,7 @@ ERTS_POLL_EXPORT(erts_poll_info)(ErtsPollSet ps, ErtsPollInfo *pip)
     pip->memory_size = size;
 
     pip->poll_set_size = (int) erts_smp_atomic_read_nob(&ps->no_of_user_fds);
-#ifdef ERTS_SMP
+#if ERTS_POLL_USE_WAKEUP_PIPE
     pip->poll_set_size++; /* Wakeup pipe */
 #endif
 
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 08d2066da3..a3dcbc4cf3 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -88,6 +88,7 @@ MODULES= \
 	send_term_SUITE \
 	sensitive_SUITE \
 	signal_SUITE \
+	smoke_test_SUITE \
 	statistics_SUITE \
 	system_info_SUITE \
 	system_profile_SUITE \
diff --git a/erts/emulator/test/smoke_test_SUITE.erl b/erts/emulator/test/smoke_test_SUITE.erl
new file mode 100644
index 0000000000..98f1cf1ad5
--- /dev/null
+++ b/erts/emulator/test/smoke_test_SUITE.erl
@@ -0,0 +1,139 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(smoke_test_SUITE).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%-compile(export_all).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
+	 init_per_group/2,end_per_group/2, 
+	 init_per_testcase/2, end_per_testcase/2]).
+
+-export([boot_combo/1]).
+
+-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() -> 
+    [boot_combo].
+
+groups() -> 
+    [].
+
+init_per_suite(Config) ->
+    Config.
+
+end_per_suite(_Config) ->
+    ok.
+
+init_per_group(_GroupName, Config) ->
+    Config.
+
+end_per_group(_GroupName, Config) ->
+    Config.
+
+
+init_per_testcase(Case, Config) when is_list(Config) ->
+    Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
+    [{testcase, Case},{watchdog, Dog}|Config].
+
+end_per_testcase(_Case, Config) when is_list(Config) ->
+    Dog = ?config(watchdog, Config),
+    ?t:timetrap_cancel(Dog),
+    ok.
+
+%%%
+%%% The test cases -------------------------------------------------------------
+%%%
+
+boot_combo(Config) when is_list(Config) ->
+    ZFlags = os:getenv("ERL_ZFLAGS"),
+    NOOP = fun () -> ok end,
+    A42 = fun () ->
+		  case erlang:system_info(threads) of
+		      true ->
+			  42 = erlang:system_info(thread_pool_size);
+		      false ->
+			  ok
+		  end
+	  end,
+    SMPDisable = fun () -> false = erlang:system_info(smp_support) end,
+    try
+	chk_boot(Config, "+Ktrue", NOOP),
+	chk_boot(Config, "+A42", A42),
+	chk_boot(Config, "-smp disable", SMPDisable),
+	chk_boot(Config, "+Ktrue +A42", A42),
+	chk_boot(Config, "-smp disable +A42",
+		 fun () -> SMPDisable(), A42() end),
+	chk_boot(Config, "-smp disable +Ktrue", SMPDisable),
+	chk_boot(Config, "-smp disable +Ktrue +A42",
+		 fun () -> SMPDisable(), A42() end),
+	%% A lot more combos could be implemented...
+	ok
+    after
+	os:putenv("ERL_ZFLAGS", case ZFlags of
+				    false -> "";
+				    _ -> ZFlags
+				end)
+    end.
+
+%%%
+%%% Aux functions --------------------------------------------------------------
+%%%
+
+chk_boot(Config, Args, Fun) ->
+    true = os:putenv("ERL_ZFLAGS", Args),
+    Success = make_ref(),
+    Parent = self(),
+    ?t:format("--- Testing ~s~n", [Args]),
+    {ok, Node} = start_node(Config),
+    Pid = spawn_link(Node, fun () ->
+				   Fun(),
+				   Parent ! {self(), Success}
+			   end),
+    receive
+	{Pid, Success} ->
+	    Node = node(Pid),
+	    stop_node(Node),
+	    ?t:format("--- Success!~n", []),
+	    ok
+    end.
+
+start_node(Config) ->
+    start_node(Config, "").
+
+start_node(Config, Args) when is_list(Config) ->
+    ?line Pa = filename:dirname(code:which(?MODULE)),
+    ?line {A, B, C} = now(),
+    ?line Name = list_to_atom(atom_to_list(?MODULE)
+			      ++ "-"
+			      ++ atom_to_list(?config(testcase, Config))
+			      ++ "-"
+			      ++ integer_to_list(A)
+			      ++ "-"
+			      ++ integer_to_list(B)
+			      ++ "-"
+			      ++ integer_to_list(C)),
+    ?line ?t:start_node(Name, slave, [{args, "-pa "++Pa++" "++Args}]).
+
+stop_node(Node) ->
+    ?t:stop_node(Node).
+
-- 
cgit v1.2.3