diff options
author | Lukas Larsson <lukas@erlang.org> | 2021-04-27 10:53:50 +0200 |
---|---|---|
committer | Lukas Larsson <lukas@erlang.org> | 2021-05-03 09:22:12 +0200 |
commit | e867f51f9ed482daa5c4c525ab9c25111eb20642 (patch) | |
tree | 08707d781aff6f3b2e7e4b7f566f1af00abcd197 | |
parent | 7fe7fa3dde556b5b92522f8279d465bb52baf1f6 (diff) | |
download | erlang-e867f51f9ed482daa5c4c525ab9c25111eb20642.tar.gz |
ei: Correctly check timeout value vs EI_SCLBK_INF_TMO
For the timeout (passed as `ms`) zero does not represent
infinity, but rather no sleeping at all. So that is what
we should check against and not 0.
-rw-r--r-- | lib/erl_interface/doc/src/ei_connect.xml | 2 | ||||
-rw-r--r-- | lib/erl_interface/src/misc/ei_portio.c | 26 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_connect_SUITE.erl | 18 |
3 files changed, 34 insertions, 12 deletions
diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml index 2dd0a285fe..8402787c67 100644 --- a/lib/erl_interface/doc/src/ei_connect.xml +++ b/lib/erl_interface/doc/src/ei_connect.xml @@ -1073,7 +1073,7 @@ self->num = fd; </func> <func> - <name since=""><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name> + <name since=""><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len, unsigned timeout_ms)</nametext></name> <fsummary>Obsolete function to send a message to a registered name with time-out.</fsummary> <desc> diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c index bccc86c1b1..a076e1ef7d 100644 --- a/lib/erl_interface/src/misc/ei_portio.c +++ b/lib/erl_interface/src/misc/ei_portio.c @@ -404,6 +404,12 @@ static int writev_ctx_t__(ei_socket_callbacks *cbs, void *ctx, do { error = cbs->writev(ctx, (const void *) iov, iovcnt, len, ms); } while (error == EINTR); + + /* It should not be possible for writev_ctx_t__ to return EAGAIN, + because when the fd is set in non-blocking we always do a select on + the fd before trying to write. And if we do not do the select the fd + is always in blocking mode. */ + return error; } @@ -417,7 +423,8 @@ int ei_writev_fill_ctx_t__(ei_socket_callbacks *cbs, void *ctx, struct iovec *current_iov; int current_iovcnt; int fd, error; - int basic; + int non_blocking = !(cbs->flags & EI_SCLBK_FLG_FULL_IMPL) && + ms != EI_SCLBK_INF_TMO; if (!cbs->writev) return ENOTSUP; @@ -426,12 +433,10 @@ int ei_writev_fill_ctx_t__(ei_socket_callbacks *cbs, void *ctx, if (error) return error; - basic = !(cbs->flags & EI_SCLBK_FLG_FULL_IMPL); - for (sum = 0, i = 0; i < iovcnt; ++i) { sum += iov[i].iov_len; } - if (basic && ms != 0U) { + if (non_blocking) { SET_NONBLOCKING(fd); } current_iovcnt = iovcnt; @@ -442,7 +447,7 @@ int ei_writev_fill_ctx_t__(ei_socket_callbacks *cbs, void *ctx, error = writev_ctx_t__(cbs, ctx, current_iov, current_iovcnt, &i, ms); if (error) { *len = done; - if (ms != 0U) { + if (non_blocking) { SET_BLOCKING(fd); } if (iov_base != NULL) { @@ -478,7 +483,7 @@ int ei_writev_fill_ctx_t__(ei_socket_callbacks *cbs, void *ctx, break; } } - if (basic && ms != 0U) { + if (non_blocking) { SET_BLOCKING(fd); } if (iov_base != NULL) { @@ -752,9 +757,10 @@ int ei_read_fill_ctx__(ei_socket_callbacks *cbs, void *ctx, char* buf, ssize_t * int ei_write_fill_ctx_t__(ei_socket_callbacks *cbs, void *ctx, const char *buf, ssize_t *len, unsigned ms) { ssize_t tot = *len, done = 0; - int error, fd = -1, basic = !(cbs->flags & EI_SCLBK_FLG_FULL_IMPL); + int error, fd = -1, non_blocking = !(cbs->flags & EI_SCLBK_FLG_FULL_IMPL) && + ms != EI_SCLBK_INF_TMO; - if (basic && ms != 0U) { + if (non_blocking) { error = EI_GET_FD__(cbs, ctx, &fd); if (error) return error; @@ -765,14 +771,14 @@ int ei_write_fill_ctx_t__(ei_socket_callbacks *cbs, void *ctx, const char *buf, error = write_ctx_t__(cbs, ctx, buf+done, &write_len, ms); if (error) { *len = done; - if (basic && ms != 0U) { + if (non_blocking) { SET_BLOCKING(fd); } return error; } done += write_len; } while (done < tot); - if (basic && ms != 0U) { + if (non_blocking) { SET_BLOCKING(fd); } *len = done; diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl index 75b6bf18da..a219d35ed6 100644 --- a/lib/erl_interface/test/ei_connect_SUITE.erl +++ b/lib/erl_interface/test/ei_connect_SUITE.erl @@ -28,6 +28,7 @@ init_per_testcase/2, ei_send/1, ei_reg_send/1, + ei_reg_send_large/1, ei_format_pid/1, ei_rpc/1, rpc_test/1, @@ -42,7 +43,7 @@ suite() -> {timetrap, {seconds, 30}}]. all() -> - [ei_send, ei_reg_send, ei_rpc, ei_format_pid, ei_send_funs, + [ei_send, ei_reg_send, ei_reg_send_large, ei_rpc, ei_format_pid, ei_send_funs, ei_threaded_send, ei_set_get_tracelevel]. init_per_testcase(Case, Config) -> @@ -105,6 +106,21 @@ ei_reg_send(Config) when is_list(Config) -> runner:recv_eot(P), ok. +ei_reg_send_large(Config) when is_list(Config) -> + P = runner:start(Config, ?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), + + ARegName = a_strange_registred_name, + register(ARegName, self()), + ok = ei_reg_send(P, Fd, ARegName, AMsg={another,[strange],message, + <<0:(32*1024*1024*8)>>}), + receive AMsg -> ok end, + + runner:send_eot(P), + runner:recv_eot(P), + ok. + ei_threaded_send(Config) when is_list(Config) -> Einode = filename:join(proplists:get_value(data_dir, Config), "einode"), N = 15, |