diff --git a/.travis.yml b/.travis.yml index c979f722..0f7ed035 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,8 @@ matrix: elixir: 1.7.4 - otp_release: 21.3 elixir: 1.8.1 + - otp_release: 22.0 + elixir: 1.8.1 env: global: diff --git a/erl_nif_sys/gen_api.erl b/erl_nif_sys/gen_api.erl index 15afb02d..f208dc89 100644 --- a/erl_nif_sys/gen_api.erl +++ b/erl_nif_sys/gen_api.erl @@ -33,8 +33,15 @@ version_opts("2.13") -> [{major,2}, {minor,13}, exception, getenv, time, % erl version_opts("2.14") -> [{major,2}, {minor,14}, exception, getenv, time, % erlang 21.0 dirty_scheduler_opt, nif_2_11, nif_2_12, nif_2_13, nif_2_14]; -version_opts(_) -> - io:format("Unsupported Erlang version.\n\nIs the erlang_nif-sys version up to date in the Cargo.toml?\nDoes 'cargo update' fix it?\nIf not please report at https://github.com/goertzenator/erlang_nif-sys.\n"), +version_opts("2.15") -> [{major,2}, {minor,15}, exception, getenv, time, % erlang 22.0 + dirty_scheduler_opt, nif_2_11, nif_2_12, nif_2_13, + nif_2_14, nif_2_15]; +version_opts(Ver) -> + io:format( + "This OTP release uses the unsupported Erlang NIF version ~p.\n\n" + "Please report at https://github.com/rustlerium/rustler.\n", + [Ver] + ), halt(1). ulong_opts("4") -> [{ulongsize, 4}]; @@ -344,11 +351,24 @@ api_list(Opts) -> [ {"", "dummy_enif_vfprintf", ""}, {"", "dummy_enif_vsnprintf", ""}, - {"c_int", "enif_make_map_from_arrays", "env: *mut ErlNifEnv, keys: *const ERL_NIF_TERM, values: *const ERL_NIF_TERM, cnt: usize, map_out: *mut ERL_NIF_TERM"} + {"c_int", "enif_make_map_from_arrays", "env: *mut ErlNifEnv, keys: *const ERL_NIF_TERM, values: *const ERL_NIF_TERM, cnt: usize, map_out: *mut ERL_NIF_TERM"} ]; false -> [] - end. + end ++ + case proplists:get_bool(nif_2_15, Opts) of + true -> [ + {"ErlNifTermType", "enif_term_type", "env: *mut ErlNifEnv, term: *const ERL_NIF_TERM"}, + {"c_int", "enif_compare_pids", "pid1: *const ErlNifPid, pid2: *const ErlNifPid"}, + {"c_int", "enif_is_pid_undefined", "pid: *const ErlNifPid"}, + {"", "enif_set_pid_undefined", "pid: *mut ErlNifPid"}, + {"ERL_NIF_TERM", "enif_make_monitor_term", "env: *mut ErlNifEnv, mon: *const ErlNifMonitor"}, + + {"c_int", "enif_select_read", "env: *mut ErlNifEnv, e: ErlNifEvent, obj: *const c_void, pid: *const ErlNifPid, msg: *const ERL_NIF_TERM, msg_env: *mut ErlNifEnv"}, + {"c_int", "enif_select_write", "env: *mut ErlNifEnv, e: ErlNifEvent, obj: *const c_void, pid: *const ErlNifPid, msg: *const ERL_NIF_TERM, msg_env: *mut ErlNifEnv"} + ]; + false -> [] + end. main([UlongSizeT]) -> main([UlongSizeT,"."]); diff --git a/erl_nif_sys/src/erl_nif_sys_api.rs b/erl_nif_sys/src/erl_nif_sys_api.rs index 34582dfa..4b6364bd 100644 --- a/erl_nif_sys/src/erl_nif_sys_api.rs +++ b/erl_nif_sys/src/erl_nif_sys_api.rs @@ -149,6 +149,9 @@ pub type ErlNifSelectFlags = c_int; pub const ERL_NIF_SELECT_READ: ErlNifSelectFlags = (1 << 0); pub const ERL_NIF_SELECT_WRITE: ErlNifSelectFlags = (1 << 1); pub const ERL_NIF_SELECT_STOP: ErlNifSelectFlags = (1 << 2); +pub const ERL_NIF_SELECT_FAILED: ErlNifSelectFlags = (1 << 3); +pub const ERL_NIF_SELECT_READ_CANCELLED: ErlNifSelectFlags = (1 << 4); +pub const ERL_NIF_SELECT_WRITE_CANCELLED: ErlNifSelectFlags = (1 << 5); /// See [ErlNifMonitor](http://www.erlang.org/doc/man/erl_nif.html#ErlNifMonitor) in the Erlang docs. #[derive(Debug, Copy, Clone)] @@ -288,6 +291,31 @@ pub enum ErlNifHash { ERL_NIF_PHASH2 = 2, } +/// See [ErlNifTermType](http://www.erlang.org/doc/man/erl_nif.html#ErlNifTermType) in the Erlang docs. +#[derive(Copy, Clone)] +#[repr(C)] +pub enum ErlNifTermType { + // from https://github.com/erlang/otp/blob/6618ce7b6a621e92db72ea4f01f7d38553c8818c/erts/emulator/beam/erl_nif.h#L291 + ERL_NIF_TERM_TYPE_ATOM = 1, + ERL_NIF_TERM_TYPE_BITSTRING = 2, + ERL_NIF_TERM_TYPE_FLOAT = 3, + ERL_NIF_TERM_TYPE_FUN = 4, + ERL_NIF_TERM_TYPE_INTEGER = 5, + ERL_NIF_TERM_TYPE_LIST = 6, + ERL_NIF_TERM_TYPE_MAP = 7, + ERL_NIF_TERM_TYPE_PID = 8, + ERL_NIF_TERM_TYPE_PORT = 9, + ERL_NIF_TERM_TYPE_REFERENCE = 10, + ERL_NIF_TERM_TYPE_TUPLE = 11, + + /* This is a dummy value intended to coax the compiler into warning about + * unhandled values in a switch even if all the above values have been + * handled. We can add new entries at any time so the user must always + * have a default case. */ + ERL_NIF_TERM_TYPE__MISSING_DEFAULT_CASE__READ_THE_MANUAL = -1 +} + + include!(concat!(env!("OUT_DIR"), "/nif_api.snippet")); // example of included content: // extern "C" { diff --git a/rustler/build.rs b/rustler/build.rs index 2fac7827..118529f3 100644 --- a/rustler/build.rs +++ b/rustler/build.rs @@ -11,7 +11,7 @@ use which::which; lazy_static! { // keep this sorted by version number static ref NIF_VERSION: Vec<&'static str> = vec![ - "2.7", "2.8", "2.9", "2.10", "2.11", "2.12", "2.13", "2.14" + "2.7", "2.8", "2.9", "2.10", "2.11", "2.12", "2.13", "2.14", "2.15" ]; } diff --git a/rustler_tests/test/resource_test.exs b/rustler_tests/test/resource_test.exs index 376e741c..f66850e3 100644 --- a/rustler_tests/test/resource_test.exs +++ b/rustler_tests/test/resource_test.exs @@ -29,6 +29,7 @@ defmodule RustlerTest.ResourceTest do # Clean them up. Don't crash. :erlang.garbage_collect() + :timer.sleep(100) # Erlang's exact GC should have cleaned all that up. assert RustlerTest.resource_immutable_count() == 0