From 1580937874b35350c0ff5c2a72b2540d7ec28378 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Tue, 15 Feb 2011 14:48:08 +0100
Subject: 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.
---
erts/doc/src/driver_entry.xml | 6 +++++-
erts/emulator/test/driver_SUITE.erl | 4 ++--
erts/emulator/test/driver_SUITE_data/chkio_drv.c | 15 ++++++++++++---
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 @@
- 20012010
+ 20012011
Ericsson AB. All Rights Reserved.
@@ -219,6 +219,10 @@ typedef struct erl_drv_entry {
completes, write to the pipe (use SetEvent on
Windows), this will make the emulator call
ready_input or ready_output.
+ Spurious events may happen. That is, calls to ready_input
+ or ready_output 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.
char *driver_name
-
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*/
--
cgit v1.2.3