Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nif] Add support for enif_dist_ctrl_put_data #6887

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions erts/emulator/beam/erl_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -2284,6 +2284,58 @@ int enif_is_port_alive(ErlNifEnv *env, ErlNifPort *port)
}
}

int
enif_dist_ctrl_put_data(ErlNifEnv *env, ERL_NIF_TERM dist_handle, ErlNifBinary *bin)
{
Process *proc = NULL;
int sched;
DistEntry *dep = NULL;
Eterm input_handler;
Uint32 conn_id;
int retval = 0;

(void)execution_state(env, &proc, &sched);

if (proc == NULL || sched <= 0) {
return 0;
}

if (bin == NULL || bin->data == NULL) {
return 0;
}

dep = erts_dhandle_to_dist_entry(dist_handle, &conn_id);
if (dep == NULL) {
return 0;
}

input_handler = (Eterm)erts_atomic_read_nob(&dep->input_handler);

if (input_handler != proc->common.id) {
return 0;
}

(void)erts_atomic64_inc_nob(&dep->in);

if (bin->size == 0) {
return 1;
}

(void)erts_proc_unlock(proc, ERTS_PROC_LOCK_MAIN);

if (erts_net_message(NULL, dep, conn_id, NULL, 0, (Binary *)(bin->ref_bin), bin->data, bin->size) != 0) {
retval = 0;
} else {
retval = 1;
}

(void)erts_proc_lock(proc, ERTS_PROC_LOCK_MAIN);

BUMP_REDS(proc, 5);

return retval;
}

ERL_NIF_TERM
enif_now_time(ErlNifEnv *env)
{
Expand Down
2 changes: 2 additions & 0 deletions erts/emulator/beam/erl_nif_api_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ ERL_NIF_API_FUNC_DECL(ErlNifTermType,enif_term_type,(ErlNifEnv* env, ERL_NIF_TER
ERL_NIF_API_FUNC_DECL(ErlNifResourceType*,enif_init_resource_type,(ErlNifEnv*, const char* name_str, const ErlNifResourceTypeInit*, ErlNifResourceFlags flags, ErlNifResourceFlags* tried));
ERL_NIF_API_FUNC_DECL(int,enif_dynamic_resource_call,(ErlNifEnv*, ERL_NIF_TERM mod, ERL_NIF_TERM name, ERL_NIF_TERM rsrc, void* call_data));

ERL_NIF_API_FUNC_DECL(int, enif_dist_ctrl_put_data, (ErlNifEnv *env, ERL_NIF_TERM dist_handle, ErlNifBinary *bin));
ERL_NIF_API_FUNC_DECL(int, enif_get_string_length, (ErlNifEnv *env, ERL_NIF_TERM list, unsigned *len, ErlNifCharEncoding encoding));
ERL_NIF_API_FUNC_DECL(int, enif_make_new_atom, (ErlNifEnv *env, const char *name, ERL_NIF_TERM *atom, ErlNifCharEncoding encoding));
ERL_NIF_API_FUNC_DECL(int, enif_make_new_atom_len, (ErlNifEnv *env, const char *name, size_t len, ERL_NIF_TERM *atom, ErlNifCharEncoding encoding));
Expand Down Expand Up @@ -413,6 +414,7 @@ ERL_NIF_API_FUNC_DECL(int, enif_set_option, (ErlNifEnv *env, ErlNifOption opt, .
# define enif_term_type ERL_NIF_API_FUNC_MACRO(enif_term_type)
# define enif_init_resource_type ERL_NIF_API_FUNC_MACRO(enif_init_resource_type)
# define enif_dynamic_resource_call ERL_NIF_API_FUNC_MACRO(enif_dynamic_resource_call)
# define enif_dist_ctrl_put_data ERL_NIF_API_FUNC_MACRO(enif_dist_ctrl_put_data)
# define enif_get_string_length ERL_NIF_API_FUNC_MACRO(enif_get_string_length)
# define enif_make_new_atom ERL_NIF_API_FUNC_MACRO(enif_make_new_atom)
# define enif_make_new_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_new_atom_len)
Expand Down
41 changes: 38 additions & 3 deletions erts/emulator/test/nif_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
match_state_arg/1,
pid/1,
id/1,
nif_term_type/1
nif_term_type/1,
nif_dist_ctrl/1
]).

-export([many_args_100/100]).
Expand Down Expand Up @@ -194,7 +195,8 @@
compare_pids_nif/2,
term_type_nif/1,
dynamic_resource_call/4,
msa_find_y_nif/1
msa_find_y_nif/1,
dist_ctrl_put_data_nif/2
]).

-define(nif_stub,nif_stub_error(?LINE)).
Expand Down Expand Up @@ -246,7 +248,8 @@ all() ->
nif_ioq,
match_state_arg,
pid,
nif_term_type].
nif_term_type,
nif_dist_ctrl].

init_per_suite(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
Expand Down Expand Up @@ -4235,6 +4238,36 @@ nif_term_type(Config) ->

ok.

nif_dist_ctrl(Config) ->
ensure_lib_loaded(Config),
{Pid, MRef} = spawn_monitor(fun() ->
Node = 'nif_dist_ctrl@localhost',
{erts_dflags, _, Mandatory, _, _, _} = erts_internal:get_dflags(),
Creation = erts_internal:get_creation(),
DHandle = erts_internal:new_connection(Node),
Port = InputHandler = FromPid = ToPid = self(),
DHandle = erlang:setnode(Node, Port, {Mandatory, Creation}),
ok = erlang:dist_ctrl_input_handler(DHandle, InputHandler),
Tag = make_ref(),
PassThroughFrame = iolist_to_binary([
$p,
term_to_binary({22, FromPid, ToPid}),
term_to_binary(Tag)
]),
1 = dist_ctrl_put_data_nif(DHandle, PassThroughFrame),
ok = receive Tag -> ok end,
InvalidFrame = iolist_to_binary([
$p,
term_to_binary({22, FromPid, ToPid, Tag})
]),
0 = dist_ctrl_put_data_nif(DHandle, InvalidFrame),
% process is scheduled to be killed in erts_net_message by misc aux work
erlang:yield(),
exit(unreachable)
end),
{'DOWN', MRef, process, Pid, killed} = receive_any(),
ok.

%% Verify match state arguments are not passed to declared NIFs.
match_state_arg(Config) ->
ensure_lib_loaded(Config),
Expand Down Expand Up @@ -4388,5 +4421,7 @@ term_type_nif(_) -> ?nif_stub.

dynamic_resource_call(_,_,_,_) -> ?nif_stub.

dist_ctrl_put_data_nif(_,_) -> ?nif_stub.

nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
19 changes: 18 additions & 1 deletion erts/emulator/test/nif_SUITE_data/nif_SUITE.c
Original file line number Diff line number Diff line change
Expand Up @@ -3796,6 +3796,22 @@ static ERL_NIF_TERM msa_find_y_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return ok_bin;
}

static ERL_NIF_TERM dist_ctrl_put_data_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ERL_NIF_TERM dist_handle;
ErlNifBinary bin;
int result;

if (argc != 2 || !enif_inspect_binary(env, argv[1], &bin)) {
return enif_make_badarg(env);
}

dist_handle = argv[0];

result = enif_dist_ctrl_put_data(env, dist_handle, &bin);
return enif_make_int(env, result);
}

static ErlNifFunc nif_funcs[] =
{
{"lib_version", 0, lib_version},
Expand Down Expand Up @@ -3911,7 +3927,8 @@ static ErlNifFunc nif_funcs[] =
{"is_pid_undefined_nif", 1, is_pid_undefined_nif},
{"compare_pids_nif", 2, compare_pids_nif},
{"term_type_nif", 1, term_type_nif},
{"msa_find_y_nif", 1, msa_find_y_nif}
{"msa_find_y_nif", 1, msa_find_y_nif},
{"dist_ctrl_put_data_nif", 2, dist_ctrl_put_data_nif},
};

ERL_NIF_INIT(nif_SUITE,nif_funcs,load,NULL,upgrade,unload)