aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2011-02-15 14:48:08 +0100
committerSverker Eriksson <[email protected]>2011-02-21 16:01:35 +0100
commit1580937874b35350c0ff5c2a72b2540d7ec28378 (patch)
tree86b7526c58488095e37335d7d5c669a61bc656f3
parentcd7fc2cb900dcd296f2ba215dea1c691440107d0 (diff)
downloadotp-1580937874b35350c0ff5c2a72b2540d7ec28378.tar.gz
otp-1580937874b35350c0ff5c2a72b2540d7ec28378.tar.bz2
otp-1580937874b35350c0ff5c2a72b2540d7ec28378.zip
Allow unexpected driver input event in driver_SUITE:smp_select
epoll on Linux has been seen to sometimes trigger unexpected events. Most of the time these events are filtered by erl_check_io, but may slip up to the driver in cases when fd's are reused. Also made clear in driver docs that spurious events may happen.
-rw-r--r--erts/doc/src/driver_entry.xml6
-rw-r--r--erts/emulator/test/driver_SUITE.erl4
-rw-r--r--erts/emulator/test/driver_SUITE_data/chkio_drv.c15
3 files changed, 19 insertions, 6 deletions
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
index dd949d4048..7d1585f483 100644
--- a/erts/doc/src/driver_entry.xml
+++ b/erts/doc/src/driver_entry.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -219,6 +219,10 @@ typedef struct erl_drv_entry {
completes, write to the pipe (use <c>SetEvent</c> on
Windows), this will make the emulator call
<c>ready_input</c> or <c>ready_output</c>.</p>
+ <p>Spurious events may happen. That is, calls to <c>ready_input</c>
+ or <c>ready_output</c> even though no real events are signaled. In
+ reality it should be rare (and OS dependant), but a robust driver
+ must nevertheless be able to handle such cases.</p>
</item>
<tag><marker id="driver_name"/>char *driver_name</tag>
<item>
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 39b2ed395f..e029e4ec87 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -1682,7 +1682,7 @@ smp_select0(Config) ->
ProcFun = fun()-> io:format("Worker ~p starting\n",[self()]),
?line Port = open_port({spawn, DrvName}, []),
smp_select_loop(Port, 100000),
- sleep(500), % wait for driver to handle pending events
+ sleep(1000), % wait for driver to handle pending events
?line true = erlang:port_close(Port),
Master ! {ok,self()},
io:format("Worker ~p finished\n",[self()])
diff --git a/erts/emulator/test/driver_SUITE_data/chkio_drv.c b/erts/emulator/test/driver_SUITE_data/chkio_drv.c
index b571cb30e6..bbdb09cfcb 100644
--- a/erts/emulator/test/driver_SUITE_data/chkio_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/chkio_drv.c
@@ -102,6 +102,7 @@ typedef struct chkio_smp_select {
int write_fd;
int next_read;
int next_write;
+ int first_write;
enum {Closed, Opened, Selected, Waiting} state;
int wasSelected;
unsigned rand_state;
@@ -577,9 +578,16 @@ chkio_drv_ready_input(ErlDrvData drv_data, ErlDrvEvent event)
inPipe = (pip->next_write - pip->next_read);
if (inPipe == 0) {
bytes = read(pip->read_fd, &word, sizeof(word));
- printf("Unexpected empty pipe, expected %u -> %u, bytes=%d, word=%d\n",
- pip->next_read, pip->next_write-1, bytes, word);
- abort();
+ printf("Unexpected empty pipe, expected %u -> %u, bytes=%d, word=%d, written=%d\n",
+ pip->next_read, pip->next_write-1, bytes, word,
+ (pip->next_write - pip->first_write));
+ /*abort();
+ Allow unexpected events as it's been seen to be triggered by epoll
+ on Linux. Most of the time the unwanted events are filtered by
+ the erl_check_io layer. But when fd's are reused the events may
+ slip up to the driver.
+ */
+ break;
}
n = rand_r(&pip->rand_state) % (inPipe*4);
@@ -1252,6 +1260,7 @@ chkio_drv_control(ErlDrvData drv_data,
pip->state = Opened;
pip->wasSelected = 0;
pip->next_write = pip->next_read = rand_r(&pip->rand_state) % 1024;
+ pip->first_write = pip->next_write;
if (op & 1) break;
op >>= 1;
}/*fall through*/