Skip to content

Commit

Permalink
Merge branch 'maint'
Browse files Browse the repository at this point in the history
* maint:
  Updated OTP version
  Update release notes
  Update version numbers
  erts: Fix so that bind correct schedulers
  Update version
  Fix error handling when decoding an AVP with an alternate dictionary
  Remove unused function arguments
  Fix faulty recursion
  vsn -> 2.1.2
  Update appup for ERIERL-14684
  Fix speling error 'sndbuf' -> 'recbuf'
  Add zlib:set_controlling_process/2
  • Loading branch information
jhogberg committed Oct 25, 2017
2 parents 9bbe588 + c26f0e5 commit 40e787f
Show file tree
Hide file tree
Showing 17 changed files with 189 additions and 74 deletions.
23 changes: 23 additions & 0 deletions erts/doc/src/notes.xml
Expand Up @@ -31,6 +31,29 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>

<section><title>Erts 9.1.3</title>

<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
<p>Added zlib:set_controlling_process/2 to move a
zstream() between processes.</p>
<p>
Own Id: OTP-14672 Aux Id: ERL-494 </p>
</item>
<item>
<p>
Fix so that schedulers are bound correctly when the first
available cpu is not the first detected cpu. e.g. when
using "taskset -c X..Y" when X is not equal to 0.</p>
<p>
Own Id: OTP-14694</p>
</item>
</list>
</section>

</section>

<section><title>Erts 9.1.2</title>

<section><title>Fixed Bugs and Malfunctions</title>
Expand Down
14 changes: 14 additions & 0 deletions erts/doc/src/zlib.xml
Expand Up @@ -71,6 +71,11 @@ list_to_binary([Compressed|Last])</pre>
called prior to a call to
<seealso marker="#inflate/2"><c>inflate/2</c></seealso>.
</item>
<tag><c>not_on_controlling_process</c></tag>
<item>The stream was used by a process that doesn't control it. Use
<seealso marker="#set_controlling_process/2">
<c>set_controlling_process/2</c></seealso> if you need to transfer
a stream to a different process.</item>
<tag><c>data_error</c></tag>
<item>The data contains errors.
</item>
Expand Down Expand Up @@ -739,6 +744,15 @@ loop(Z, Handler, {finished, Output}) ->
</desc>
</func>

<func>
<name name="set_controlling_process" arity="2"/>
<fsummary>Transfers ownership of a zlib stream.</fsummary>
<desc>
<p>Changes the controlling process of <c><anno>Z</anno></c> to
<c><anno>Pid</anno></c>, which must be a local process.</p>
</desc>
</func>

<func>
<name name="uncompress" arity="1"/>
<fsummary>Uncompress data with standard zlib functionality.</fsummary>
Expand Down
2 changes: 1 addition & 1 deletion erts/emulator/beam/erl_cpu_topology.c
Expand Up @@ -602,7 +602,7 @@ write_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size)

cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1);

for (cpu_ix = 0; cpu_ix < size && cpu_ix < erts_no_schedulers; cpu_ix++)
for (cpu_ix = 0; cpu_ix < size && s_ix <= erts_no_schedulers; cpu_ix++)
if (erts_is_cpu_available(cpuinfo, cpudata[cpu_ix].logical))
scheduler2cpu_map[s_ix++].bind_id = cpudata[cpu_ix].logical;
}
Expand Down
64 changes: 53 additions & 11 deletions erts/emulator/nifs/common/zlib_nif.c
Expand Up @@ -106,6 +106,7 @@ typedef struct {
int inflateChunk_buffer_size;

ErlNifPid controlling_process;
ErlNifMutex *controller_lock;

ErlNifIOQueue *input_queue;

Expand All @@ -117,6 +118,8 @@ typedef struct {

static ERL_NIF_TERM zlib_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_set_controller(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);

static ERL_NIF_TERM zlib_deflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_deflateSetDictionary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_deflateReset(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
Expand All @@ -143,6 +146,11 @@ static ERL_NIF_TERM zlib_setBufSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM
static ERL_NIF_TERM zlib_enqueue_input(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);

static ErlNifFunc nif_funcs[] = {
{"close_nif", 1, zlib_close},
{"open_nif", 0, zlib_open},

{"set_controller_nif", 2, zlib_set_controller},

/* deflate */
{"deflateInit_nif", 6, zlib_deflateInit},
{"deflateSetDictionary_nif", 2, zlib_deflateSetDictionary},
Expand All @@ -162,10 +170,6 @@ static ErlNifFunc nif_funcs[] = {
/* running checksum */
{"crc32_nif", 1, zlib_crc32},

/* open & close */
{"close_nif", 1, zlib_close},
{"open_nif", 0, zlib_open},

/* The stash keeps a single term alive across calls, and is used in
* exception_on_need_dict/1 to retain the old error behavior, and for
* saving data flushed through deflateParams/3. */
Expand Down Expand Up @@ -281,18 +285,14 @@ static ERL_NIF_TERM zlib_return(ErlNifEnv *env, int code) {
return reason;
}

static void gc_zlib(ErlNifEnv *env, void* data) {
zlib_data_t *d = (zlib_data_t*)data;

static void zlib_internal_close(zlib_data_t *d) {
if(d->state == ST_DEFLATE) {
deflateEnd(&d->s);
} else if(d->state == ST_INFLATE) {
inflateEnd(&d->s);
}

if(d->state != ST_CLOSED) {
enif_ioq_destroy(d->input_queue);

if(d->stash_env != NULL) {
enif_free_env(d->stash_env);
}
Expand All @@ -301,17 +301,36 @@ static void gc_zlib(ErlNifEnv *env, void* data) {
}
}

static void gc_zlib(ErlNifEnv *env, void* data) {
zlib_data_t *d = (zlib_data_t*)data;

enif_mutex_destroy(d->controller_lock);
enif_ioq_destroy(d->input_queue);

zlib_internal_close(d);

(void)env;
}

static int get_zlib_data(ErlNifEnv *env, ERL_NIF_TERM opaque, zlib_data_t **d) {
return enif_get_resource(env, opaque, rtype_zlib, (void **)d);
}

static int zlib_process_check(ErlNifEnv *env, zlib_data_t *d) {
int is_controlling_process;
ErlNifPid current_process;

enif_self(env, &current_process);

return enif_is_identical(enif_make_pid(env, &current_process),
enif_mutex_lock(d->controller_lock);

is_controlling_process = enif_is_identical(
enif_make_pid(env, &current_process),
enif_make_pid(env, &d->controlling_process));

enif_mutex_unlock(d->controller_lock);

return is_controlling_process;
}

static void zlib_reset_input(zlib_data_t *d) {
Expand Down Expand Up @@ -516,6 +535,8 @@ static ERL_NIF_TERM zlib_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[

d->input_queue = enif_ioq_create(ERL_NIF_IOQ_NORMAL);

d->controller_lock = enif_mutex_create("zlib_controller_lock");

d->s.zalloc = zlib_alloc;
d->s.zfree = zlib_free;
d->s.opaque = d;
Expand Down Expand Up @@ -556,7 +577,28 @@ static ERL_NIF_TERM zlib_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv
return enif_raise_exception(env, am_not_initialized);
}

gc_zlib(env, d);
zlib_internal_close(d);

return am_ok;
}

static ERL_NIF_TERM zlib_set_controller(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
zlib_data_t *d;

ErlNifPid new_owner;

if(argc != 2 || !get_zlib_data(env, argv[0], &d)
|| !enif_get_local_pid(env, argv[1], &new_owner)) {
return enif_make_badarg(env);
} else if(!zlib_process_check(env, d)) {
return enif_raise_exception(env, am_not_on_controlling_process);
}

enif_mutex_lock(d->controller_lock);

d->controlling_process = new_owner;

enif_mutex_unlock(d->controller_lock);

return am_ok;
}
Expand Down
Binary file modified erts/preloaded/ebin/zlib.beam
Binary file not shown.
11 changes: 10 additions & 1 deletion erts/preloaded/src/zlib.erl
Expand Up @@ -20,7 +20,8 @@

-module(zlib).

-export([open/0,close/1,deflateInit/1,deflateInit/2,deflateInit/6,
-export([open/0,close/1,set_controlling_process/2,
deflateInit/1,deflateInit/2,deflateInit/6,
deflateSetDictionary/2,deflateReset/1,deflateParams/3,
deflate/2,deflate/3,deflateEnd/1,
inflateInit/1,inflateInit/2,inflateInit/3,
Expand Down Expand Up @@ -128,6 +129,14 @@ close(Z) ->
close_nif(_Z) ->
erlang:nif_error(undef).

-spec set_controlling_process(Z, Pid) -> 'ok' when
Z :: zstream(),
Pid :: pid().
set_controlling_process(Z, Pid) ->
set_controller_nif(Z, Pid).
set_controller_nif(_Z, _Pid) ->
erlang:nif_error(undef).

-spec deflateInit(Z) -> 'ok' when
Z :: zstream().
deflateInit(Z) ->
Expand Down
2 changes: 1 addition & 1 deletion erts/vsn.mk
Expand Up @@ -18,7 +18,7 @@
# %CopyrightEnd%
#

VSN = 9.1.2
VSN = 9.1.3

# Port number 4365 in 4.2
# Port number 4366 in 4.3
Expand Down
17 changes: 17 additions & 0 deletions lib/diameter/doc/src/notes.xml
Expand Up @@ -43,6 +43,23 @@ first.</p>

<!-- ===================================================================== -->

<section><title>diameter 2.1.2</title>

<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
<p>
A fault introduced in diameter 2.1 could cause decode
errors to be ignored in AVPs following the header of a
Grouped AVP.</p>
<p>
Own Id: OTP-14684 Aux Id: ERIERL-85 </p>
</item>
</list>
</section>

</section>

<section><title>diameter 2.1.1</title>

<section><title>Fixed Bugs and Malfunctions</title>
Expand Down
44 changes: 23 additions & 21 deletions lib/diameter/src/base/diameter_gen.erl
Expand Up @@ -320,8 +320,8 @@ decode(Bin, Code, Vid, DataLen, Pad, M, P, Name, Mod, Fmt, Strict, Opts0,
index = Idx},

Dec = dec(Data, Name, NameT, Mod, Fmt, Opts, Avp),
Acc = decode(T, Name, Mod, Fmt, Strict, Opts, Idx+1, AM),%% recurse
acc(Acc, Dec, I, Field, Arity, Strict, Mod, Opts);
Acc = decode(T, Name, Mod, Fmt, Strict, Opts0, Idx+1, AM),%% recurse
acc(Acc, Dec, I, Field, Arity, Strict, Mod);
_ ->
{NameT, _Field, _Arity, {_, AM}}
= incr(Name, Code, Vid, M, Mod, Strict, Opts0, AM0),
Expand Down Expand Up @@ -574,15 +574,17 @@ dec_AVP(Dicts, Data, Name, Mod, Fmt, Opts, #diameter_avp{code = Code,
%% Try to decode an AVP in the first alternate dictionary that defines
%% it.

dec_AVP([Dict | Rest], Data, Name, Mod, Fmt, Opts, Code, Vid, Avp) ->
dec_AVP([Dict | Rest], Data, Name, Mod, Fmt, Opts0, Code, Vid, Avp) ->
case Dict:avp_name(Code, Vid) of
{AvpName, Type} ->
{AvpName, Type} = NameT ->
A = Avp#diameter_avp{name = AvpName,
type = Type},
#{failed_avp := Failed} = Opts,
#{failed_avp := Failed}
= Opts
= setopts(NameT, Name, Avp#diameter_avp.is_mandatory, Opts0),
dec(Data, Name, AvpName, Type, Mod, Dict, Fmt, Failed, Opts, A);
_ ->
dec_AVP(Rest, Data, Name, Mod, Fmt, Opts, Code, Vid, Avp)
dec_AVP(Rest, Data, Name, Mod, Fmt, Opts0, Code, Vid, Avp)
end;

dec_AVP([], _, _, _, _, _, _, _, Avp) ->
Expand Down Expand Up @@ -680,30 +682,30 @@ set_failed('Failed-AVP', #{failed_avp := false} = Opts) ->
set_failed(_, Opts) ->
Opts.

%% acc/8
%% acc/7

acc([AM | Acc], As, I, Field, Arity, Strict, Mod, Opts) ->
[AM | acc1(Acc, As, I, Field, Arity, Strict, Mod, Opts)].
acc([AM | Acc], As, I, Field, Arity, Strict, Mod) ->
[AM | acc1(Acc, As, I, Field, Arity, Strict, Mod)].

%% acc1/8
%% acc1/7

%% Faulty AVP, not grouped.
acc1(Acc, {_RC, Avp} = E, _, _, _, _, _, _) ->
acc1(Acc, {_RC, Avp} = E, _, _, _, _, _) ->
[Avps, Failed | Rec] = Acc,
[[Avp | Avps], [E | Failed] | Rec];

%% Faulty component in grouped AVP.
acc1(Acc, {RC, As, Avp}, _, _, _, _, _, _) ->
acc1(Acc, {RC, As, Avp}, _, _, _, _, _) ->
[Avps, Failed | Rec] = Acc,
[[As | Avps], [{RC, Avp} | Failed] | Rec];

%% Grouped AVP ...
acc1([Avps | Acc], [Avp|_] = As, I, Field, Arity, Strict, Mod, Opts) ->
[[As|Avps] | acc2(Acc, Avp, I, Field, Arity, Strict, Mod, Opts)];
acc1([Avps | Acc], [Avp|_] = As, I, Field, Arity, Strict, Mod) ->
[[As|Avps] | acc2(Acc, Avp, I, Field, Arity, Strict, Mod)];

%% ... or not.
acc1([Avps | Acc], Avp, I, Field, Arity, Strict, Mod, Opts) ->
[[Avp|Avps] | acc2(Acc, Avp, I, Field, Arity, Strict, Mod, Opts)].
acc1([Avps | Acc], Avp, I, Field, Arity, Strict, Mod) ->
[[Avp|Avps] | acc2(Acc, Avp, I, Field, Arity, Strict, Mod)].

%% The component list of a Grouped AVP is discarded when packing into
%% the record (or equivalent): the values in an 'AVP' field are
Expand All @@ -713,24 +715,24 @@ acc1([Avps | Acc], Avp, I, Field, Arity, Strict, Mod, Opts) ->
%% retain the same structure as in diameter_packet.avps, but an 'AVP'
%% list has always been flat.

%% acc2/8
%% acc2/7

%% No errors, but nowhere to pack.
acc2(Acc, Avp, _, 'AVP', 0, _, _, _) ->
acc2(Acc, Avp, _, 'AVP', 0, _, _) ->
[Failed | Rec] = Acc,
[[{rc(Avp), Avp} | Failed] | Rec];

%% Relaxed arities.
acc2(Acc, Avp, _, Field, Arity, Strict, Mod, _)
acc2(Acc, Avp, _, Field, Arity, Strict, Mod)
when Strict /= decode ->
pack(Arity, Field, Avp, Mod, Acc);

%% No maximum arity.
acc2(Acc, Avp, _, Field, {_,'*'} = Arity, _, Mod, _) ->
acc2(Acc, Avp, _, Field, {_,'*'} = Arity, _, Mod) ->
pack(Arity, Field, Avp, Mod, Acc);

%% Or check.
acc2(Acc, Avp, I, Field, Arity, _, Mod, _) ->
acc2(Acc, Avp, I, Field, Arity, _, Mod) ->
Mx = max_arity(Arity),
if Mx =< I ->
[Failed | Rec] = Acc,
Expand Down
7 changes: 5 additions & 2 deletions lib/diameter/src/diameter.appup.src
Expand Up @@ -54,7 +54,9 @@
{"1.12.1", [{restart_application, diameter}]}, %% 19.1
{"1.12.2", [{restart_application, diameter}]}, %% 19.3
{"2.0", [{restart_application, diameter}]}, %% 20.0
{"2.1", [{update, diameter_reg, {advanced, "2.1"}}]} %% 20.1
{"2.1", [{load_module, diameter_gen}, %% 20.1
{update, diameter_reg, {advanced, "2.1"}}]},
{"2.1.1", [{load_module, diameter_gen}]}
],
[
{"0.9", [{restart_application, diameter}]},
Expand Down Expand Up @@ -90,6 +92,7 @@
{"1.12.1", [{restart_application, diameter}]},
{"1.12.2", [{restart_application, diameter}]},
{"2.0", [{restart_application, diameter}]},
{"2.1", [{restart_application, diameter}]}
{"2.1", [{restart_application, diameter}]},
{"2.1.1", [{load_module, diameter_gen}]}
]
}.
2 changes: 1 addition & 1 deletion lib/diameter/vsn.mk
Expand Up @@ -17,5 +17,5 @@
# %CopyrightEnd%

APPLICATION = diameter
DIAMETER_VSN = 2.1.1
DIAMETER_VSN = 2.1.2
APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)

0 comments on commit 40e787f

Please sign in to comment.