Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ADF81184BC for ; Mon, 13 Jul 2015 18:45:01 +0000 (UTC) Received: (qmail 84367 invoked by uid 500); 13 Jul 2015 18:45:01 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 84175 invoked by uid 500); 13 Jul 2015 18:45:01 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 84110 invoked by uid 99); 13 Jul 2015 18:45:01 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 13 Jul 2015 18:45:01 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id DB1ADE08EF; Mon, 13 Jul 2015 18:45:00 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: kxepal@apache.org To: commits@couchdb.apache.org Date: Mon, 13 Jul 2015 18:45:04 -0000 Message-Id: In-Reply-To: <9be4c77905ae4fe0a4f2a108e023e74d@git.apache.org> References: <9be4c77905ae4fe0a4f2a108e023e74d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [05/43] jiffy commit: updated refs/heads/upstream to 446e284 Use a resource for the decoder structure This is ground work to allow Jiffy to yield back to the scheduler. Creating a decoder resource will allow for the necessary state to be carried across NIF function invocations. Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/79d24e96 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/79d24e96 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/79d24e96 Branch: refs/heads/upstream Commit: 79d24e9639e1c721e1a520da7e41715ea9907022 Parents: c5c794e Author: Paul J. Davis Authored: Thu Jun 12 14:46:01 2014 -0500 Committer: Paul J. Davis Committed: Fri Jun 13 16:56:24 2014 -0500 ---------------------------------------------------------------------- c_src/decoder.c | 97 ++++++++++++++++++++++++++++++++++++++++++---------- c_src/jiffy.c | 12 ++++++- c_src/jiffy.h | 7 +++- src/jiffy.erl | 8 +++-- 4 files changed, 102 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/79d24e96/c_src/decoder.c ---------------------------------------------------------------------- diff --git a/c_src/decoder.c b/c_src/decoder.c index fc892da..45ea329 100644 --- a/c_src/decoder.c +++ b/c_src/decoder.c @@ -61,21 +61,25 @@ typedef struct { int st_top; } Decoder; -void -dec_init(Decoder* d, ErlNifEnv* env, ERL_NIF_TERM arg, ErlNifBinary* bin) +Decoder* +dec_new(ErlNifEnv* env) { + jiffy_st* st = (jiffy_st*) enif_priv_data(env); + Decoder* d = enif_alloc_resource(st->res_dec, sizeof(Decoder)); int i; - d->env = env; - d->atoms = enif_priv_data(env); - d->arg = arg; + if(d == NULL) { + return NULL; + } + + d->atoms = st; d->is_partial = 0; - d->p = (char*) bin->data; - d->u = bin->data; - d->len = bin->size; - d->i = 0; + d->p = NULL; + d->u = NULL; + d->len = -1; + d->i = -1; d->st_data = (char*) enif_alloc(STACK_SIZE_INC * sizeof(char)); d->st_size = STACK_SIZE_INC; @@ -87,11 +91,36 @@ dec_init(Decoder* d, ErlNifEnv* env, ERL_NIF_TERM arg, ErlNifBinary* bin) d->st_data[0] = st_value; d->st_top++; + + return d; } void -dec_destroy(Decoder* d) +dec_init(Decoder* d, ErlNifEnv* env, ERL_NIF_TERM arg, ErlNifBinary* bin) { + d->env = env; + d->arg = arg; + + d->p = (char*) bin->data; + d->u = bin->data; + d->len = bin->size; + + // I'd like to be more forceful on this check so that when + // we run a second iteration of the decoder we are sure + // that we're using the same binary. Unfortunately, I don't + // think there's a value to base this assertion on. + if(d->i < 0) { + d->i = 0; + } else { + assert(d->i <= d->len && "mismatched binary lengths"); + } +} + +void +dec_destroy(ErlNifEnv* env, void* obj) +{ + Decoder* d = (Decoder*) obj; + if(d->st_data != NULL) { enif_free(d->st_data); } @@ -605,25 +634,59 @@ make_array(ErlNifEnv* env, ERL_NIF_TERM list) } ERL_NIF_TERM -decode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { - Decoder dec; - Decoder* d = &dec; + Decoder* d; + jiffy_st* st = (jiffy_st*) enif_priv_data(env); + ERL_NIF_TERM tmp_argv[4]; + + if(argc != 1) { + return enif_make_badarg(env); + } + + d = dec_new(env); + if(d == NULL) { + return make_error(st, env, "internal_error"); + } + + tmp_argv[0] = argv[0]; + tmp_argv[1] = enif_make_resource(env, d); + tmp_argv[2] = enif_make_list(env, 0); + tmp_argv[3] = enif_make_list(env, 0); + + enif_release_resource(d); + + return decode_iter(env, 4, tmp_argv); +} + +ERL_NIF_TERM +decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + Decoder* d; + jiffy_st* st = (jiffy_st*) enif_priv_data(env); ErlNifBinary bin; - ERL_NIF_TERM objs = enif_make_list(env, 0); - ERL_NIF_TERM curr = enif_make_list(env, 0); + ERL_NIF_TERM objs; + ERL_NIF_TERM curr; ERL_NIF_TERM val; ERL_NIF_TERM ret; - if(argc != 1) { + if(argc != 4) { return enif_make_badarg(env); } else if(!enif_inspect_binary(env, argv[0], &bin)) { return enif_make_badarg(env); + } else if(!enif_get_resource(env, argv[1], st->res_dec, (void**) &d)) { + return enif_make_badarg(env); + } else if(!enif_is_list(env, argv[2])) { + return enif_make_badarg(env); + } else if(!enif_is_list(env, argv[3])) { + return enif_make_badarg(env); } dec_init(d, env, argv[0], &bin); + objs = argv[2]; + curr = argv[3]; //fprintf(stderr, "Parsing:\r\n"); while(d->i < bin.size) { @@ -908,7 +971,5 @@ decode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) } done: - dec_destroy(d); - return ret; } http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/79d24e96/c_src/jiffy.c ---------------------------------------------------------------------- diff --git a/c_src/jiffy.c b/c_src/jiffy.c index 964222c..e0c1f20 100644 --- a/c_src/jiffy.c +++ b/c_src/jiffy.c @@ -28,6 +28,15 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) st->ref_object = make_atom(env, "$object_ref$"); st->ref_array = make_atom(env, "$array_ref$"); + st->res_dec = enif_open_resource_type( + env, + NULL, + "decoder", + dec_destroy, + ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER, + NULL + ); + *priv = (void*) st; return 0; @@ -54,7 +63,8 @@ unload(ErlNifEnv* env, void* priv) static ErlNifFunc funcs[] = { - {"nif_decode", 1, decode}, + {"nif_decode_init", 1, decode_init}, + {"nif_decode_iter", 4, decode_iter}, {"nif_encode", 2, encode} }; http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/79d24e96/c_src/jiffy.h ---------------------------------------------------------------------- diff --git a/c_src/jiffy.h b/c_src/jiffy.h index 3dda545..bfd5940 100644 --- a/c_src/jiffy.h +++ b/c_src/jiffy.h @@ -22,15 +22,20 @@ typedef struct { ERL_NIF_TERM ref_object; ERL_NIF_TERM ref_array; + + ErlNifResourceType* res_dec; } jiffy_st; ERL_NIF_TERM make_atom(ErlNifEnv* env, const char* name); ERL_NIF_TERM make_ok(jiffy_st* st, ErlNifEnv* env, ERL_NIF_TERM data); ERL_NIF_TERM make_error(jiffy_st* st, ErlNifEnv* env, const char* error); -ERL_NIF_TERM decode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +void dec_destroy(ErlNifEnv* env, void* obj); + int int_from_hex(const unsigned char* p); int int_to_hex(int val, char* p); int utf8_len(int c); http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/79d24e96/src/jiffy.erl ---------------------------------------------------------------------- diff --git a/src/jiffy.erl b/src/jiffy.erl index c4b3d69..c9e65e4 100644 --- a/src/jiffy.erl +++ b/src/jiffy.erl @@ -8,7 +8,7 @@ -on_load(init/0). decode(Data) when is_binary(Data) -> - case nif_decode(Data) of + case nif_decode_init(Data) of {error, _} = Error -> throw(Error); {partial, EJson} -> @@ -99,7 +99,11 @@ init() -> not_loaded(Line) -> erlang:nif_error({not_loaded, [{module, ?MODULE}, {line, Line}]}). -nif_decode(_Data) -> +nif_decode_init(_Data) -> + ?NOT_LOADED, + nif_decode_iter(w, x, y, z). + +nif_decode_iter(_Data, _Decoder, _, _) -> ?NOT_LOADED. nif_encode(_Data, _Options) ->