diff options
author | Sverker Eriksson <[email protected]> | 2017-02-09 15:23:11 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2017-02-09 15:51:27 +0100 |
commit | d85e74e0c0e4bc66c875e2fd5f54d89255df0047 (patch) | |
tree | 181a24e041b4439f01170ac9db9302bb0fa7df89 /erts/emulator/test | |
parent | 2d3de607e346e6b965f410e8c4e126cd38c6603e (diff) | |
download | otp-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.erl | 54 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 16 |
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}, |