diff options
-rw-r--r-- | erts/doc/src/socket.xml | 31 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_catree.c | 5 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_tree.c | 13 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_tree_util.h | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 44 | ||||
-rw-r--r-- | erts/emulator/test/timer_bif_SUITE.erl | 31 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_connection.xml | 2 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection.erl | 34 | ||||
-rw-r--r-- | lib/stdlib/test/ets_SUITE.erl | 20 |
9 files changed, 112 insertions, 72 deletions
diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml index 08a9889146..c54fe38bfd 100644 --- a/erts/doc/src/socket.xml +++ b/erts/doc/src/socket.xml @@ -471,20 +471,13 @@ <fsummary>Get an option on a socket.</fsummary> <desc> <p>Get an option on a socket.</p> - <p>What properties are valid depend both on <c>Level</c> and - on what kind of socket it is (<c>domain</c>, <c>type</c> and - <c>protocol</c>).</p> + <p>When specifying <c>Level</c> as an integer, and therefor using "native mode", it is *currently* up to the caller to know how to interpret the result.</p> - <p>See the - <seealso marker="socket_usage#socket_options">socket options</seealso> - chapter of the users guide for more info. </p> - - <note><p>Not all options are valid on all platforms. That is, - even if "we" support an option, that does not mean that the - underlying OS does.</p></note> + <p>For more info, see + <seealso marker="#getopt/3">getopt</seealso> above. </p> </desc> </func> @@ -876,21 +869,13 @@ <fsummary>Set options on a socket.</fsummary> <desc> <p>Set options on a socket.</p> - <p>What properties are valid depend both on <c>Level</c> and on - what kind of socket it is (<c>domain</c>, <c>type</c> and - <c>protocol</c>).</p> - <p>See the - <seealso marker="socket_usage#socket_options">socket options</seealso> - chapter of the users guide for more info. </p> - - <note><p>Not all options are valid on all platforms. That is, - even if "we" support an option, that does not mean that the - underlying OS does.</p></note> + <p>When specifying <c>Level</c> as an integer, and therefor + using "native mode", it is *currently* up to the caller to + know how to encode the <c>Value</c>.</p> - <note><p>Sockets are set 'non-blocking' when created, so this option - is *not* available (as it would adversely effect the Erlang VM - to set a socket 'blocking').</p></note> + <p>For more info, see + <seealso marker="#setopt/4">setopt</seealso> above. </p> </desc> </func> diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c index 176966edb5..4e08f89692 100644 --- a/erts/emulator/beam/erl_db_catree.c +++ b/erts/emulator/beam/erl_db_catree.c @@ -2289,7 +2289,10 @@ static int db_lookup_dbterm_catree(Process *p, DbTable *tbl, Eterm key, Eterm ob static void db_finalize_dbterm_catree(int cret, DbUpdateHandle *handle) { DbTableCATree *tb = &(handle->tb->catree); - db_finalize_dbterm_tree_common(cret, handle, NULL); + db_finalize_dbterm_tree_common(cret, + handle, + &handle->u.catree.base_node->u.base.root, + NULL); wunlock_adapt_base_node(tb, handle->u.catree.base_node, handle->u.catree.parent, handle->u.catree.current_level); diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 723b3c5d29..49158108a2 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -3287,7 +3287,9 @@ db_lookup_dbterm_tree(Process *p, DbTable *tbl, Eterm key, Eterm obj, return db_lookup_dbterm_tree_common(p, tbl, &tb->root, key, obj, handle, tb); } -void db_finalize_dbterm_tree_common(int cret, DbUpdateHandle *handle, +void db_finalize_dbterm_tree_common(int cret, + DbUpdateHandle *handle, + TreeDbTerm **root, DbTableTree *stack_container) { DbTable *tbl = handle->tb; @@ -3295,7 +3297,12 @@ void db_finalize_dbterm_tree_common(int cret, DbUpdateHandle *handle, if (handle->flags & DB_NEW_OBJECT && cret != DB_ERROR_NONE) { Eterm ret; - db_erase_tree(tbl, GETKEY(&tbl->common, bp->dbterm.tpl), &ret); + db_erase_tree_common(tbl, + root, + GETKEY(&tbl->common, bp->dbterm.tpl), + &ret, + (stack_container == NULL ? + NULL : &stack_container->static_stack)); } else if (handle->flags & DB_MUST_RESIZE) { db_finalize_resize(handle, offsetof(TreeDbTerm,dbterm)); reset_static_stack(stack_container); @@ -3313,7 +3320,7 @@ db_finalize_dbterm_tree(int cret, DbUpdateHandle *handle) { DbTable *tbl = handle->tb; DbTableTree *tb = &tbl->tree; - db_finalize_dbterm_tree_common(cret, handle, tb); + db_finalize_dbterm_tree_common(cret, handle, &tb->root, tb); } static int db_get_binary_info_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret) diff --git a/erts/emulator/beam/erl_db_tree_util.h b/erts/emulator/beam/erl_db_tree_util.h index 14afbd56f7..90ac8c7ba7 100644 --- a/erts/emulator/beam/erl_db_tree_util.h +++ b/erts/emulator/beam/erl_db_tree_util.h @@ -167,7 +167,9 @@ void db_foreach_offheap_tree_common(TreeDbTerm *root, int db_lookup_dbterm_tree_common(Process *p, DbTable *tbl, TreeDbTerm **root, Eterm key, Eterm obj, DbUpdateHandle* handle, DbTableTree *stack_container); -void db_finalize_dbterm_tree_common(int cret, DbUpdateHandle *handle, +void db_finalize_dbterm_tree_common(int cret, + DbUpdateHandle *handle, + TreeDbTerm **root, DbTableTree *stack_container); Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 4c91c60220..acb5ebdfd3 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -7462,11 +7462,16 @@ msb_scheduler_type_switch(ErtsSchedType sched_type, } static ERTS_INLINE void -suspend_normal_scheduler_sleep(ErtsSchedulerData *esdp) +suspend_scheduler_sleep(ErtsSchedulerData *esdp, + int normal_sched, + ErtsMonotonicTime initial_time, + ErtsMonotonicTime timeout_time) { ErtsSchedulerSleepInfo *ssi = esdp->ssi; erts_aint32_t flgs = sched_spin_suspended(ssi, ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT); + ASSERT(!normal_sched || esdp->type == ERTS_SCHED_NORMAL); + ASSERT(esdp->type != ERTS_SCHED_NORMAL || normal_sched); if (flgs == (ERTS_SSI_FLG_SLEEPING | ERTS_SSI_FLG_WAITING | ERTS_SSI_FLG_SUSPENDED)) { @@ -7475,21 +7480,34 @@ suspend_normal_scheduler_sleep(ErtsSchedulerData *esdp) | ERTS_SSI_FLG_TSE_SLEEPING | ERTS_SSI_FLG_WAITING | ERTS_SSI_FLG_SUSPENDED)) { - int res; + if (!normal_sched) { + while (1) { + int res = erts_tse_wait(ssi->event); + if (res != EINTR) + break; + } + } + else { + ErtsMonotonicTime current_time = initial_time; + while (1) { + int res; + Sint64 timeout; - do { - res = erts_tse_wait(ssi->event); - } while (res == EINTR); + timeout = ERTS_MONOTONIC_TO_NSEC(timeout_time + - current_time + - 1) + 1; + res = erts_tse_twait(ssi->event, timeout); + if (res != EINTR) + break; + current_time = erts_get_monotonic_time(esdp); + if (current_time >= timeout_time) + break; + } + } } } } -static ERTS_INLINE void -suspend_dirty_scheduler_sleep(ErtsSchedulerData *esdp) -{ - suspend_normal_scheduler_sleep(esdp); -} - static void suspend_scheduler(ErtsSchedulerData *esdp) { @@ -7684,7 +7702,7 @@ suspend_scheduler(ErtsSchedulerData *esdp) while (1) { if (sched_type != ERTS_SCHED_NORMAL) - suspend_dirty_scheduler_sleep(esdp); + suspend_scheduler_sleep(esdp, 0, 0, 0); else { ErtsMonotonicTime current_time, timeout_time; @@ -7729,7 +7747,7 @@ suspend_scheduler(ErtsSchedulerData *esdp) sched_wall_time_change(esdp, 0); } erts_thr_progress_prepare_wait(erts_thr_prgr_data(NULL)); - suspend_normal_scheduler_sleep(esdp); + suspend_scheduler_sleep(esdp, !0, current_time, timeout_time); erts_thr_progress_finalize_wait(erts_thr_prgr_data(NULL)); current_time = erts_get_monotonic_time(esdp); } diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl index 15fe13c8c0..cdfc4f2882 100644 --- a/erts/emulator/test/timer_bif_SUITE.erl +++ b/erts/emulator/test/timer_bif_SUITE.erl @@ -30,7 +30,8 @@ cleanup/1, evil_timers/1, registered_process/1, same_time_yielding/1, same_time_yielding_with_cancel/1, same_time_yielding_with_cancel_other/1, % same_time_yielding_with_cancel_other_accessor/1, - auto_cancel_yielding/1]). + auto_cancel_yielding/1, + suspended_scheduler_timeout/1]). -include_lib("common_test/include/ct.hrl"). @@ -68,7 +69,8 @@ all() -> same_time_yielding, same_time_yielding_with_cancel, same_time_yielding_with_cancel_other, % same_time_yielding_with_cancel_other_accessor, - auto_cancel_yielding]. + auto_cancel_yielding, + suspended_scheduler_timeout]. %% Basic start_timer/3 functionality @@ -630,6 +632,31 @@ auto_cancel_yielding(Config) when is_list(Config) -> Mem = mem(), ok. +suspended_scheduler_timeout(Config) when is_list(Config) -> + Ref = make_ref(), + SchdlrsOnln = erlang:system_info(schedulers_online), + lists:foreach(fun (Sched) -> + process_flag(scheduler, Sched), + erlang:send_after(1000, self(), {Ref, Sched}) + end, + lists:seq(1, SchdlrsOnln)), + process_flag(scheduler, 0), + erlang:system_flag(schedulers_online, 1), + try + lists:foreach(fun (Sched) -> + receive + {Ref, Sched} -> + ok + after 2000 -> + ct:fail({missing_timeout, Sched}) + end + end, + lists:seq(1, SchdlrsOnln)) + after + erlang:system_flag(schedulers_online, SchdlrsOnln) + end, + ok. + process_is_cleaned_up(P) when is_pid(P) -> undefined == erts_debug:get_internal_state({process_status, P}). diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml index 65c0347c40..e1689b68ba 100644 --- a/lib/ssh/doc/src/ssh_connection.xml +++ b/lib/ssh/doc/src/ssh_connection.xml @@ -383,7 +383,7 @@ <type> <v>ConnectionRef = <seealso marker="ssh:ssh#type-connection_ref">ssh:connection_ref()</seealso></v> <v>ChannelId = <seealso marker="ssh:ssh#type-channel_id">ssh:channel_id()</seealso></v> - <v>Data = binary()</v> + <v>Data = iodata()</v> <v>Type = <seealso marker="#type-ssh_data_type_code">ssh_data_type_code()</seealso></v> <v>Timeout = timeout()</v> <v>Error = {error, <seealso marker="#type-reason">reason()</seealso>}</v> diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index c5316bf133..bef1927f53 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -412,14 +412,17 @@ exit_status(ConnectionHandler, Channel, Status) -> %%% ssh_connection:send (executed in the ssh_connection_state machine) %%% -channel_data(ChannelId, DataType, Data, Connection, From) when is_list(Data)-> - channel_data(ChannelId, DataType, l2b(Data), Connection, From); - -channel_data(ChannelId, DataType, Data, +channel_data(ChannelId, DataType, Data0, #connection{channel_cache = Cache} = Connection, From) -> case ssh_client_channel:cache_lookup(Cache, ChannelId) of #channel{remote_id = Id, sent_close = false} = Channel0 -> + Data = + try iolist_to_binary(Data0) + catch + _:_ -> + unicode:characters_to_binary(Data0) + end, {SendList, Channel} = update_send_window(Channel0#channel{flow_control = From}, DataType, Data, Connection), @@ -1365,26 +1368,3 @@ request_reply_or_data(#channel{local_id = ChannelId, user = ChannelPid}, false -> {[{channel_data, ChannelPid, Reply}], Connection} end. - - - -%%%---------------------------------------------------------------- -%%% l(ist)2b(inary) -%%% -l2b(L) when is_integer(hd(L)) -> - try list_to_binary(L) - of - B -> B - catch - _:_ -> - unicode:characters_to_binary(L) - end; -l2b([H|T]) -> - << (l2b(H))/binary, (l2b(T))/binary >>; -l2b(B) when is_binary(B) -> - B; -l2b([]) -> - <<>>. - - - diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index b7fe664f12..aa98f8f9e4 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -50,6 +50,7 @@ fixtable_next/1, fixtable_insert/1, rename/1, rename_unnamed/1, evil_rename/1, update_element/1, update_counter/1, evil_update_counter/1, partly_bound/1, match_heavy/1]). -export([update_counter_with_default/1]). +-export([update_counter_with_default_bad_pos/1]). -export([update_counter_table_growth/1]). -export([member/1]). -export([memory/1]). @@ -131,7 +132,9 @@ all() -> interface_equality, fixtable_next, fixtable_insert, rename, rename_unnamed, evil_rename, update_element, update_counter, evil_update_counter, - update_counter_with_default, partly_bound, + update_counter_with_default, + update_counter_with_default_bad_pos, + partly_bound, update_counter_table_growth, match_heavy, {group, fold}, member, t_delete_object, select_bound_chunk, @@ -2407,6 +2410,21 @@ update_counter_with_default_do(Opts) -> ok. +%% ERL-1125 +update_counter_with_default_bad_pos(Config) when is_list(Config) -> + repeat_for_all_ord_set_table_types(fun update_counter_with_default_bad_pos_do/1). + +update_counter_with_default_bad_pos_do(Opts) -> + T = ets_new(a, Opts), + 0 = ets:info(T, size), + ok = try ets:update_counter(T, 101065, {1, 1}, {101065, 0}) + catch + error:badarg -> ok; + Class:Reason -> {Class, Reason} + end, + 0 = ets:info(T, size), + ok. + update_counter_table_growth(_Config) -> repeat_for_opts(fun update_counter_table_growth_do/1). |