aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-02-09 15:23:11 +0100
committerSverker Eriksson <[email protected]>2017-02-09 15:51:27 +0100
commitd85e74e0c0e4bc66c875e2fd5f54d89255df0047 (patch)
tree181a24e041b4439f01170ac9db9302bb0fa7df89 /erts/emulator/test
parent2d3de607e346e6b965f410e8c4e126cd38c6603e (diff)
downloadotp-d85e74e0c0e4bc66c875e2fd5f54d89255df0047.tar.gz
otp-d85e74e0c0e4bc66c875e2fd5f54d89255df0047.tar.bz2
otp-d85e74e0c0e4bc66c875e2fd5f54d89255df0047.zip
erts: Add pid argument to enif_select
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/nif_SUITE.erl54
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c16
2 files changed, 47 insertions, 23 deletions
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index e3af9f7454..de26e73c3d 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -468,21 +468,31 @@ select(Config) when is_list(Config) ->
ensure_lib_loaded(Config),
Ref = make_ref(),
+ Ref2 = make_ref(),
{{R, R_ptr}, {W, W_ptr}} = pipe_nif(),
ok = write_nif(W, <<"hej">>),
<<"hej">> = read_nif(R, 3),
%% Wait for read
eagain = read_nif(R, 3),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Ref),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref),
[] = flush(),
ok = write_nif(W, <<"hej">>),
[{select, R, Ref, ready_input}] = flush(),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref2),
+ [{select, R, Ref2, ready_input}] = flush(),
+ Papa = self(),
+ Pid = spawn_link(fun() ->
+ [{select, R, Ref, ready_input}] = flush(),
+ Papa ! {self(), done}
+ end),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Pid,Ref),
+ {Pid, done} = receive_any(1000),
<<"hej">> = read_nif(R, 3),
%% Wait for write
Written = write_full(W, $a),
- 0 = select_nif(W,?ERL_NIF_SELECT_WRITE,W,Ref),
+ 0 = select_nif(W,?ERL_NIF_SELECT_WRITE,W,self(),Ref),
[] = flush(),
Half = byte_size(Written) div 2,
<<First:Half/binary,Second/binary>> = Written,
@@ -494,16 +504,16 @@ select(Config) when is_list(Config) ->
%% Close write and wait for EOF
eagain = read_nif(R, 1),
- check_stop_ret(select_nif(W,?ERL_NIF_SELECT_STOP,W,Ref)),
+ check_stop_ret(select_nif(W,?ERL_NIF_SELECT_STOP,W,null,Ref)),
[{fd_resource_stop, W_ptr, _}] = flush(),
{1, {W_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(W),
[] = flush(),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Ref),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref),
[{select, R, Ref, ready_input}] = flush(),
eof = read_nif(R,1),
- check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,Ref)),
+ check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,null,Ref)),
[{fd_resource_stop, R_ptr, _}] = flush(),
{1, {R_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(R),
@@ -520,8 +530,8 @@ select_2(Config) ->
%% Change ref
eagain = read_nif(R, 1),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Ref1),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Ref2),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref2),
[] = flush(),
ok = write_nif(W, <<"hej">>),
@@ -530,35 +540,35 @@ select_2(Config) ->
%% Change pid
eagain = read_nif(R, 1),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Ref1),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
Papa = self(),
- Pid2 = spawn_link(fun() ->
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Ref1),
- [] = flush(),
- Papa ! sync,
- [{select, R, Ref1, ready_input}] = flush(),
- <<"hej">> = read_nif(R, 3),
- Papa ! done
- end),
+ spawn_link(fun() ->
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
+ [] = flush(),
+ Papa ! sync,
+ [{select, R, Ref1, ready_input}] = flush(),
+ <<"hej">> = read_nif(R, 3),
+ Papa ! done
+ end),
sync = receive_any(),
ok = write_nif(W, <<"hej">>),
done = receive_any(),
[] = flush(),
- check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,Ref1)),
+ check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,null,Ref1)),
[{fd_resource_stop, R_ptr, _}] = flush(),
{1, {R_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(R),
%% Stop without previous read/write select
- ?ERL_NIF_SELECT_STOP_CALLED = select_nif(W,?ERL_NIF_SELECT_STOP,W,Ref1),
+ ?ERL_NIF_SELECT_STOP_CALLED = select_nif(W,?ERL_NIF_SELECT_STOP,W,null,Ref1),
[{fd_resource_stop, W_ptr, 1}] = flush(),
{1, {W_ptr,1}} = last_fd_stop_call(),
true = is_closed_nif(W),
select_3(Config).
-select_3(Config) ->
+select_3(_Config) ->
erlang:garbage_collect(),
{_,_,2} = last_resource_dtor_call(),
ok.
@@ -2263,6 +2273,10 @@ call(Pid,Cmd) ->
receive_any() ->
receive M -> M end.
+receive_any(Timeout) ->
+ receive M -> M
+ after Timeout -> timeout end.
+
flush() ->
flush(10).
flush(Timeout) ->
@@ -2635,7 +2649,7 @@ term_to_binary_nif(_, _) -> ?nif_stub.
binary_to_term_nif(_, _, _) -> ?nif_stub.
port_command_nif(_, _) -> ?nif_stub.
format_term_nif(_,_) -> ?nif_stub.
-select_nif(_,_,_,_) -> ?nif_stub.
+select_nif(_,_,_,_,_) -> ?nif_stub.
pipe_nif() -> ?nif_stub.
write_nif(_,_) -> ?nif_stub.
read_nif(_,_) -> ?nif_stub.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index ee925512d2..6cf02c6efe 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -75,6 +75,7 @@ static ERL_NIF_TERM atom_init;
static ERL_NIF_TERM atom_stats;
static ERL_NIF_TERM atom_done;
static ERL_NIF_TERM atom_stop;
+static ERL_NIF_TERM atom_null;
typedef struct
{
@@ -242,6 +243,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
atom_stats = enif_make_atom(env,"stats");
atom_done = enif_make_atom(env,"done");
atom_stop = enif_make_atom(env,"stop");
+ atom_null = enif_make_atom(env,"null");
*priv_data = data;
return 0;
@@ -2119,6 +2121,7 @@ static ERL_NIF_TERM select_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
struct fd_resource* fdr;
enum ErlNifSelectFlags mode;
void* obj;
+ ErlNifPid nifpid, *pid = NULL;
ERL_NIF_TERM ref;
enum ErlNifSelectReturn retval;
@@ -2129,11 +2132,16 @@ static ERL_NIF_TERM select_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
return enif_make_badarg(env);
}
- ref = argv[3];
+ if (argv[3] != atom_null) {
+ if (!enif_get_local_pid(env, argv[3], &nifpid))
+ return enif_make_badarg(env);
+ pid = &nifpid;
+ }
+ ref = argv[4];
fdr->was_selected = 1;
enif_self(env, &fdr->pid);
- retval = enif_select(env, fdr->fd, mode, obj, ref);
+ retval = enif_select(env, fdr->fd, mode, obj, pid, ref);
return enif_make_int(env, (int)retval);
}
@@ -2160,7 +2168,9 @@ static ERL_NIF_TERM pipe_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
read_rsrc = enif_alloc_resource(fd_resource_type, sizeof(struct fd_resource));
write_rsrc = enif_alloc_resource(fd_resource_type, sizeof(struct fd_resource));
read_rsrc->fd = fds[0];
+ read_rsrc->was_selected = 0;
write_rsrc->fd = fds[1];
+ write_rsrc->was_selected = 0;
read_fd = enif_make_resource(env, read_rsrc);
write_fd = enif_make_resource(env, write_rsrc);
enif_release_resource(read_rsrc);
@@ -2845,7 +2855,7 @@ static ErlNifFunc nif_funcs[] =
{"binary_to_term_nif", 3, binary_to_term},
{"port_command_nif", 2, port_command},
{"format_term_nif", 2, format_term},
- {"select_nif", 4, select_nif},
+ {"select_nif", 5, select_nif},
{"pipe_nif", 0, pipe_nif},
{"write_nif", 2, write_nif},
{"read_nif", 2, read_nif},