diff options
author | Sverker Eriksson <[email protected]> | 2017-02-09 17:30:30 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2017-02-09 17:30:30 +0100 |
commit | a8d5234c77634df9522727ff200cef4fcab49c22 (patch) | |
tree | 51c3d51eaab4510928d0439265eb0613bac3a68d | |
parent | d85e74e0c0e4bc66c875e2fd5f54d89255df0047 (diff) | |
download | otp-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.xml | 28 | ||||
-rw-r--r-- | erts/emulator/beam/erl_drv_nif.h | 8 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.h | 6 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.c | 14 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.h | 4 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 2 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE.erl | 9 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 4 |
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, &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, &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 & ERL_NIF_SELECT_ERROR) { +retval = enif_select(env, fd, ERL_NIF_SELECT_STOP, resource, ref); +if (retval < 0) { /* handle error */ } /* Success! */ +if (retval & 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[]) |