aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-02-09 17:30:30 +0100
committerSverker Eriksson <[email protected]>2017-02-09 17:30:30 +0100
commita8d5234c77634df9522727ff200cef4fcab49c22 (patch)
tree51c3d51eaab4510928d0439265eb0613bac3a68d
parentd85e74e0c0e4bc66c875e2fd5f54d89255df0047 (diff)
downloadotp-a8d5234c77634df9522727ff200cef4fcab49c22.tar.gz
otp-a8d5234c77634df9522727ff200cef4fcab49c22.tar.bz2
otp-a8d5234c77634df9522727ff200cef4fcab49c22.zip
erts: Change return value for enif_select
to negative int as error and positive as success.
-rw-r--r--erts/doc/src/erl_nif.xml28
-rw-r--r--erts/emulator/beam/erl_drv_nif.h8
-rw-r--r--erts/emulator/beam/erl_nif.h6
-rw-r--r--erts/emulator/sys/common/erl_check_io.c14
-rw-r--r--erts/emulator/sys/common/erl_check_io.h4
-rw-r--r--erts/emulator/sys/unix/sys.c2
-rw-r--r--erts/emulator/test/nif_SUITE.erl9
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c4
8 files changed, 38 insertions, 37 deletions
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 9800a530f2..e8e7bd4a80 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -2583,7 +2583,7 @@ enif_map_iterator_destroy(env, &amp;iter);</code>
</func>
<func>
- <name><ret>enum ErlNifSelectReturn</ret>
+ <name><ret>int</ret>
<nametext>enif_select(ErlNifEnv* env, ErlNifEvent event, enum ErlNifSelectFlags mode,
void* obj, const ErlNifPid* pid, ERL_NIF_TERM ref)</nametext>
</name>
@@ -2626,36 +2626,36 @@ enif_map_iterator_destroy(env, &amp;iter);</code>
the event object. This safe way of closing event objects must be used
even if all notifications have been received and no further calls to
<c>enif_select</c> have been made.</p>
- <p>Returns an integer where different bits indicate the outcome of the call:</p>
+ <p>Returns a non-negative value on success where the following bits can be set:</p>
<taglist>
- <tag><c>ERL_NIF_SELECT_ERROR</c></tag>
- <item>The master error bit. It will always be set if the call failed for
- any reason.</item>
<tag><c>ERL_NIF_SELECT_STOP_CALLED</c></tag>
<item>The stop callback was called directly by <c>enif_select</c>.</item>
<tag><c>ERL_NIF_SELECT_STOP_SCHEDULED</c></tag>
<item>The stop callback was scheduled to run on some other thread
or later by this thread.</item>
+ </taglist>
+ <p>Returns a negative value if the call failed where the follwing bits can be set:</p>
+ <taglist>
<tag><c>ERL_NIF_SELECT_INVALID_EVENT</c></tag>
<item>Argument <c>event</c> is not a valid OS event object.</item>
<tag><c>ERL_NIF_SELECT_FAILED</c></tag>
<item>The system call failed to add the event object to the poll set.</item>
</taglist>
- <p>The return value from a successful call with <c>mode</c> as <c>ERL_NIF_SELECT_STOP</c>,
- will contain either bit <c>ERL_NIF_SELECT_STOP_CALLED</c> or
- <c>ERL_NIF_SELECT_STOP_SCHEDULED</c>.</p>
<note>
- <p>Always use bitwise AND to test the return value. New significant bits
- may be added in future releases to give more detailed information for both
- failed and successful calls. Do NOT use equallity tests like <c>==</c>, as
- that may cause your application to stop working.</p>
+ <p>Use bitwise AND to test for specific bits in the return vaue.
+ New significant bits may be added in future releases to give more detailed
+ information for both failed and successful calls. Do NOT use equallity tests
+ like <c>==</c>, as that may cause your application to stop working.</p>
<p>Example:</p>
<code type="none">
-retval = enif_select(env, fd, ERL_NIF_SELECT_READ, resource, ref);
-if (retval &amp; ERL_NIF_SELECT_ERROR) {
+retval = enif_select(env, fd, ERL_NIF_SELECT_STOP, resource, ref);
+if (retval < 0) {
/* handle error */
}
/* Success! */
+if (retval &amp; ERL_NIF_SELECT_STOP_CALLED) {
+ /* ... */
+}
</code>
</note>
</desc>
diff --git a/erts/emulator/beam/erl_drv_nif.h b/erts/emulator/beam/erl_drv_nif.h
index 8de4a7855d..2d21dac87a 100644
--- a/erts/emulator/beam/erl_drv_nif.h
+++ b/erts/emulator/beam/erl_drv_nif.h
@@ -56,14 +56,6 @@ enum ErlNifSelectFlags {
ERL_NIF_SELECT_STOP = (1 << 2)
};
-enum ErlNifSelectReturn {
- ERL_NIF_SELECT_ERROR = (1 << 0),
- ERL_NIF_SELECT_STOP_CALLED = (1 << 1),
- ERL_NIF_SELECT_STOP_SCHEDULED = (1 << 2),
- ERL_NIF_SELECT_INVALID_EVENT = (1 << 3),
- ERL_NIF_SELECT_FAILED = (1 << 4)
-};
-
/*
* A driver monitor
*/
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 5248f287ee..9ff28a30cc 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -142,6 +142,12 @@ typedef struct
typedef int ErlNifEvent; /* An event to be selected on. */
//#endif
+/* Return bits from enif_select: */
+#define ERL_NIF_SELECT_STOP_CALLED (1 << 0)
+#define ERL_NIF_SELECT_STOP_SCHEDULED (1 << 1)
+#define ERL_NIF_SELECT_INVALID_EVENT (1 << 2)
+#define ERL_NIF_SELECT_FAILED (1 << 3)
+
typedef enum
{
ERL_NIF_RT_CREATE = 1,
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c
index 089f10fd8e..2964b09b8c 100644
--- a/erts/emulator/sys/common/erl_check_io.c
+++ b/erts/emulator/sys/common/erl_check_io.c
@@ -1198,7 +1198,7 @@ done_unknown:
return ret;
}
-enum ErlNifSelectReturn
+int
ERTS_CIO_EXPORT(enif_select)(ErlNifEnv* env,
ErlNifEvent e,
enum ErlNifSelectFlags mode,
@@ -1213,7 +1213,7 @@ ERTS_CIO_EXPORT(enif_select)(ErlNifEnv* env,
ErtsPollEvents new_events, old_events;
ErtsDrvEventState *state;
int wake_poller;
- enum ErlNifSelectReturn ret;
+ int ret;
enum { NO_STOP=0, CALL_STOP, CALL_STOP_AND_RELEASE } call_stop = NO_STOP;
#if ERTS_CIO_HAVE_DRV_EVENT
ErtsDrvEventDataState *free_event = NULL;
@@ -1229,11 +1229,11 @@ ERTS_CIO_EXPORT(enif_select)(ErlNifEnv* env,
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
if ((unsigned)fd >= (unsigned)erts_smp_atomic_read_nob(&drv_ev_state_len)) {
if (fd < 0) {
- return ERL_NIF_SELECT_ERROR | ERL_NIF_SELECT_INVALID_EVENT;
+ return INT_MIN | ERL_NIF_SELECT_INVALID_EVENT;
}
if (fd >= max_fds) {
nif_select_large_fd_error(fd, mode, resource, ref);
- return ERL_NIF_SELECT_ERROR | ERL_NIF_SELECT_INVALID_EVENT;
+ return INT_MIN | ERL_NIF_SELECT_INVALID_EVENT;
}
grow_drv_ev_state(fd);
}
@@ -1327,7 +1327,7 @@ ERTS_CIO_EXPORT(enif_select)(ErlNifEnv* env,
state->driver.nif->out.ddeselect_cnt = 0;
state->driver.stop.resource = NULL;
}
- ret = ERL_NIF_SELECT_ERROR | ERL_NIF_SELECT_FAILED;
+ ret = INT_MIN | ERL_NIF_SELECT_FAILED;
goto done;
}
@@ -2518,6 +2518,10 @@ static void drv_ev_state_free(void *des)
void
ERTS_CIO_EXPORT(erts_init_check_io)(void)
{
+ ERTS_CT_ASSERT((INT_MIN & (ERL_NIF_SELECT_STOP_CALLED |
+ ERL_NIF_SELECT_STOP_SCHEDULED |
+ ERL_NIF_SELECT_INVALID_EVENT |
+ ERL_NIF_SELECT_FAILED)) == 0);
erts_smp_atomic_init_nob(&erts_check_io_time, 0);
erts_smp_atomic_init_nob(&pollset.in_poll_wait, 0);
diff --git a/erts/emulator/sys/common/erl_check_io.h b/erts/emulator/sys/common/erl_check_io.h
index 4f9efeefcd..f02d6c1f62 100644
--- a/erts/emulator/sys/common/erl_check_io.h
+++ b/erts/emulator/sys/common/erl_check_io.h
@@ -34,8 +34,8 @@
int driver_select_kp(ErlDrvPort, ErlDrvEvent, int, int);
int driver_select_nkp(ErlDrvPort, ErlDrvEvent, int, int);
-enum ErlNifSelectReturn enif_select_kp(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm);
-enum ErlNifSelectReturn enif_select_nkp(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm);
+int enif_select_kp(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm);
+int enif_select_nkp(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm);
int driver_event_kp(ErlDrvPort, ErlDrvEvent, ErlDrvEventData);
int driver_event_nkp(ErlDrvPort, ErlDrvEvent, ErlDrvEventData);
Uint erts_check_io_size_kp(void);
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 4843ee4ba2..f4bdc129e1 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -161,7 +161,7 @@ int erts_use_kernel_poll = 0;
struct {
int (*select)(ErlDrvPort, ErlDrvEvent, int, int);
- enum ErlNifSelectReturn (*enif_select)(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm);
+ int (*enif_select)(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm);
int (*event)(ErlDrvPort, ErlDrvEvent, ErlDrvEventData);
void (*check_io_as_interrupt)(void);
void (*check_io_interrupt)(int);
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index de26e73c3d..d88ac01e46 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -457,11 +457,10 @@ t_on_load(Config) when is_list(Config) ->
-define(ERL_NIF_SELECT_WRITE, (1 bsl 1)).
-define(ERL_NIF_SELECT_STOP, (1 bsl 2)).
--define(ERL_NIF_SELECT_ERROR, (1 bsl 0)).
--define(ERL_NIF_SELECT_STOP_CALLED, (1 bsl 1)).
--define(ERL_NIF_SELECT_STOP_SCHEDULED, (1 bsl 2)).
--define(ERL_NIF_SELECT_INVALID_EVENT, (1 bsl 3)).
--define(ERL_NIF_SELECT_FAILED, (1 bsl 4)).
+-define(ERL_NIF_SELECT_STOP_CALLED, (1 bsl 0)).
+-define(ERL_NIF_SELECT_STOP_SCHEDULED, (1 bsl 1)).
+-define(ERL_NIF_SELECT_INVALID_EVENT, (1 bsl 2)).
+-define(ERL_NIF_SELECT_FAILED, (1 bsl 3)).
select(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 6cf02c6efe..05b4b05e16 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -2123,7 +2123,7 @@ static ERL_NIF_TERM select_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
void* obj;
ErlNifPid nifpid, *pid = NULL;
ERL_NIF_TERM ref;
- enum ErlNifSelectReturn retval;
+ int retval;
if (!get_fd(env, argv[0], &fdr)
|| !enif_get_uint(env, argv[1], &mode)
@@ -2143,7 +2143,7 @@ static ERL_NIF_TERM select_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
enif_self(env, &fdr->pid);
retval = enif_select(env, fdr->fd, mode, obj, pid, ref);
- return enif_make_int(env, (int)retval);
+ return enif_make_int(env, retval);
}
static ERL_NIF_TERM pipe_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])