summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/socket.xml31
-rw-r--r--erts/emulator/beam/erl_db_catree.c5
-rw-r--r--erts/emulator/beam/erl_db_tree.c13
-rw-r--r--erts/emulator/beam/erl_db_tree_util.h4
-rw-r--r--erts/emulator/beam/erl_process.c44
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl31
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml2
-rw-r--r--lib/ssh/src/ssh_connection.erl34
-rw-r--r--lib/stdlib/test/ets_SUITE.erl20
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).