diff --git a/src/markdown.c b/src/markdown.c index 617cb68..6589933 100644 --- a/src/markdown.c +++ b/src/markdown.c @@ -8,6 +8,7 @@ #include "html.h" #define OUTPUT_UNIT 128 +#define MAX_INPUT_SIZE_SHORT_JOB 20000 typedef struct { ERL_NIF_TERM atom_true; @@ -17,16 +18,31 @@ typedef struct { ERL_NIF_TERM atom_fenced_code; } markdown_priv; +static int +is_short_job(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { + ErlNifBinary input; + if (enif_inspect_binary(env, argv[0], &input) == 0) { + return -1; + } + + return input.size < MAX_INPUT_SIZE_SHORT_JOB; +} + static ERL_NIF_TERM -to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { +do_job(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary input; ErlNifBinary output; - - markdown_priv* priv; + ERL_NIF_TERM options; + ERL_NIF_TERM atom_true; + ERL_NIF_TERM atom_tables; + ERL_NIF_TERM atom_autolink; + ERL_NIF_TERM atom_fenced_code; + ERL_NIF_TERM term; const ERL_NIF_TERM* tuple; int tuple_size; + unsigned int extensions; hoedown_buffer* ob; @@ -41,29 +57,32 @@ to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return argv[0]; } - priv = enif_priv_data(env); options = argv[1]; extensions = 0; + atom_true = enif_make_atom(env, "true"); + atom_tables = enif_make_atom(env, "tables"); + atom_autolink = enif_make_atom(env, "autolink"); + atom_fenced_code = enif_make_atom(env, "fenced_code"); while (enif_get_list_cell(env, options, &term, &options) != 0) { if (enif_get_tuple(env, term, &tuple_size, &tuple) != 0) { if (tuple_size > 1) { - if (enif_compare(tuple[0], priv->atom_tables) == 0) { - if (enif_compare(tuple[1], priv->atom_true) == 0) { + if (enif_compare(tuple[0], atom_tables) == 0) { + if (enif_compare(tuple[1], atom_true) == 0) { extensions |= HOEDOWN_EXT_TABLES; continue; } } - if (enif_compare(tuple[0], priv->atom_autolink) == 0) { - if (enif_compare(tuple[1], priv->atom_true) == 0) { + if (enif_compare(tuple[0], atom_autolink) == 0) { + if (enif_compare(tuple[1], atom_true) == 0) { extensions |= HOEDOWN_EXT_AUTOLINK; continue; } } - if (enif_compare(tuple[0], priv->atom_fenced_code) == 0) { - if (enif_compare(tuple[1], priv->atom_true) == 0) { + if (enif_compare(tuple[0], atom_fenced_code) == 0) { + if (enif_compare(tuple[1], atom_true) == 0) { extensions |= HOEDOWN_EXT_FENCED_CODE; continue; } @@ -77,7 +96,6 @@ to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { markdown = hoedown_markdown_new(extensions, 16, renderer); hoedown_markdown_render(ob, (uint8_t*) input.data, input.size, markdown); - enif_release_binary(&input); hoedown_html_renderer_free(renderer); hoedown_markdown_free(markdown); @@ -88,40 +106,28 @@ to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_binary(env, &output); } -static ErlNifFunc funcs[] = { - { "to_html", 2, to_html } -}; - -static int -load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) { - markdown_priv* data = enif_alloc(sizeof(markdown_priv)); - if (data == NULL) { - return 1; - } - - data->atom_true = enif_make_atom(env, "true"); - data->atom_false = enif_make_atom(env, "false"); - data->atom_tables = enif_make_atom(env, "tables"); - data->atom_autolink = enif_make_atom(env, "autolink"); - data->atom_fenced_code = enif_make_atom(env, "fenced_code"); - - *priv = (void*) data; - return 0; -} - -static int -reload(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) { - return 0; +static ERL_NIF_TERM +do_dirty_job(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { + ERL_NIF_TERM result = do_job(env, argc, argv); + return enif_schedule_dirty_nif_finalizer(env, result, enif_dirty_nif_finalizer); } -static int -upgrade(ErlNifEnv* env, void** priv, void** old_priv, ERL_NIF_TERM info) { - return load(env, priv, info); +static ERL_NIF_TERM +to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { +#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT + if(is_short_job(env, argc, argv)) { + return do_job(env, argc, argv); + } + else { + return enif_schedule_dirty_nif(env, ERL_NIF_DIRTY_JOB_CPU_BOUND, do_dirty_job, argc, argv); + } +#else + return do_job(env, argc, argv); +#endif } -static void -unload(ErlNifEnv* env, void* priv) { - enif_free(priv); -} +static ErlNifFunc funcs[] = { + { "to_html", 2, to_html } +}; -ERL_NIF_INIT(Elixir.Markdown, funcs, &load, &reload, &upgrade, &unload) +ERL_NIF_INIT(Elixir.Markdown, funcs, NULL, NULL, NULL, NULL)