Skip to content

Commit

Permalink
Fix for segfault durring init:reload().
Browse files Browse the repository at this point in the history
  • Loading branch information
davisp committed Aug 8, 2010
1 parent 2dfb020 commit 761326a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
2 changes: 1 addition & 1 deletion c_src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ rem_worker(ErlNifEnv* env, int argc, CENTERM argv[])
{
state_ptr state = (state_ptr) enif_priv_data(env);

if(!state_rem_worker(state))
if(!state_rem_worker(state, FALSE))
{
return state_error(state);
}
Expand Down
20 changes: 9 additions & 11 deletions c_src/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,25 +83,23 @@ state_create(ErlNifEnv* env)
}

void
vm_dtor(void* obj)
blank_dtor(void* obj)
{
// VM's are ref counted. They'll die later.
// VM's are ref counted.
// Workers are handled by state_rem_worker.
}

void
state_destroy(state_ptr state)
{
int w;

if(state == NULL)
{
return;
}

for(w = 0; w < state->num_workers; w++)
while(state->num_workers > 0)
{
worker_destroy(state->workers[w]);
state->workers[w] = NULL;
state_rem_worker(state, TRUE);
}

if(state->topts != NULL)
Expand All @@ -111,12 +109,12 @@ state_destroy(state_ptr state)

if(state->dth_q != NULL)
{
queue_destroy(state->dth_q, worker_destroy);
queue_destroy(state->dth_q, blank_dtor);
}

if(state->req_q != NULL)
{
queue_destroy(state->req_q, vm_dtor);
queue_destroy(state->req_q, blank_dtor);
}

// XXX: Big assumption that we can't call this destructor with
Expand Down Expand Up @@ -231,7 +229,7 @@ state_add_worker(state_ptr state)
}

int
state_rem_worker(state_ptr state)
state_rem_worker(state_ptr state, int closing)
{
worker_ptr worker;
int w, found;
Expand All @@ -244,7 +242,7 @@ state_rem_worker(state_ptr state)
// Check if we have a worker to remove. We keep at least one worker.

assert(state->num_workers > 0 && "Invalid state: No workers.");
if(state->num_workers < 2)
if(state->num_workers < 2 && !closing)
{
enif_mutex_unlock(state->lock);
return 0;
Expand Down
10 changes: 9 additions & 1 deletion c_src/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
#include "alias.h"
#include "queue.h"

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

typedef struct state_t* state_ptr;

state_ptr state_create(ErlNifEnv* env);
Expand All @@ -21,6 +29,6 @@ ENTERM state_error(state_ptr state);

unsigned int state_num_workers(state_ptr state);
int state_add_worker(state_ptr state);
int state_rem_worker(state_ptr state);
int state_rem_worker(state_ptr state, int closing);

#endif // Included state.h
18 changes: 18 additions & 0 deletions test/smoke/restarts.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-module(restarts).

-export([run/0]).

run(0) ->
ok;
run(N) ->
{ok, Ctx} = emonk:create_ctx(),
emonk:eval(Ctx, <<"var f = function(x) {return x*3;};">>),
{ok, 27} = emonk:call(Ctx, <<"f">>, [9]),
run(N-1).

run() ->
io:format(".", []),
code:add_path("ebin"),
run(5),
init:restart().

0 comments on commit 761326a

Please sign in to comment.