Changed bdberl_tpool_run to set a pointer to the job structure

rather than return it.  There was an issue where the async thread cleanup
code finished before bdberl_tpool_run returned and wrote the address
of a freed TPoolJob structure into the ErlDrvPort.
This commit is contained in:
Jon Meredith 2009-02-09 15:01:25 -07:00
parent 567107ab37
commit d833ca708c
3 changed files with 10 additions and 9 deletions

View file

@ -447,7 +447,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
d->async_flags = UNPACK_INT(inbuf, 0); d->async_flags = UNPACK_INT(inbuf, 0);
} }
d->async_pool = G_TPOOL_TXNS; d->async_pool = G_TPOOL_TXNS;
d->async_job = bdberl_tpool_run(G_TPOOL_TXNS, &do_async_txnop, d, 0); bdberl_tpool_run(d->async_pool, &do_async_txnop, d, 0, &d->async_job);
// Outbuf is <<Rc:32>> // Outbuf is <<Rc:32>>
RETURN_INT(0, outbuf); RETURN_INT(0, outbuf);
@ -496,8 +496,8 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
fn = &do_async_get; fn = &do_async_get;
} }
d->async_pool = G_TPOOL_GENERAL; d->async_pool = G_TPOOL_GENERAL;
d->async_job = bdberl_tpool_run(G_TPOOL_GENERAL, fn, d, 0); bdberl_tpool_run(d->async_pool, fn, d, 0, &d->async_job);
// Let caller know that the operation is in progress // Let caller know that the operation is in progress
// Outbuf is: <<0:32>> // Outbuf is: <<0:32>>
RETURN_INT(0, outbuf); RETURN_INT(0, outbuf);
@ -561,7 +561,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
// Schedule the operation // Schedule the operation
d->async_op = cmd; d->async_op = cmd;
d->async_pool = G_TPOOL_GENERAL; d->async_pool = G_TPOOL_GENERAL;
d->async_job = bdberl_tpool_run(G_TPOOL_GENERAL, &do_async_cursor_get, d, 0); bdberl_tpool_run(d->async_pool, &do_async_cursor_get, d, 0, &d->async_job);
// Let caller know operation is in progress // Let caller know operation is in progress
RETURN_INT(0, outbuf); RETURN_INT(0, outbuf);
@ -628,7 +628,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
// Mark the port as busy and then schedule the appropriate async operation // Mark the port as busy and then schedule the appropriate async operation
d->async_op = cmd; d->async_op = cmd;
d->async_pool = G_TPOOL_GENERAL; d->async_pool = G_TPOOL_GENERAL;
d->async_job = bdberl_tpool_run(G_TPOOL_GENERAL, &do_async_truncate, d, 0); bdberl_tpool_run(d->async_pool, &do_async_truncate, d, 0, &d->async_job);
// Let caller know that the operation is in progress // Let caller know that the operation is in progress
// Outbuf is: <<0:32>> // Outbuf is: <<0:32>>

View file

@ -74,10 +74,11 @@ void bdberl_tpool_stop(TPool* tpool)
driver_free(tpool); driver_free(tpool);
} }
TPoolJob* bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFunc cancel_fn) void bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFunc cancel_fn,
TPoolJob** job_ptr)
{ {
// Allocate and fill a new job structure // Allocate and fill a new job structure
TPoolJob* job = driver_alloc(sizeof(TPoolJob)); TPoolJob* job = *job_ptr = driver_alloc(sizeof(TPoolJob));
memset(job, '\0', sizeof(TPoolJob)); memset(job, '\0', sizeof(TPoolJob));
job->main_fn = main_fn; job->main_fn = main_fn;
job->arg = arg; job->arg = arg;
@ -105,7 +106,6 @@ TPoolJob* bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJ
// pending jobs. Not sure ATM, however, so will be on safe side // pending jobs. Not sure ATM, however, so will be on safe side
erl_drv_cond_broadcast(tpool->work_cv); erl_drv_cond_broadcast(tpool->work_cv);
UNLOCK(tpool); UNLOCK(tpool);
return job;
} }
void bdberl_tpool_cancel(TPool* tpool, TPoolJob* job) void bdberl_tpool_cancel(TPool* tpool, TPoolJob* job)

View file

@ -60,7 +60,8 @@ TPool* bdberl_tpool_start(unsigned int thread_count);
void bdberl_tpool_stop(TPool* tpool); void bdberl_tpool_stop(TPool* tpool);
TPoolJob* bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFunc cancel_fn); void bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFunc cancel_fn,
TPoolJob** job_ptr);
void bdberl_tpool_cancel(TPool* tpool, TPoolJob* job); void bdberl_tpool_cancel(TPool* tpool, TPoolJob* job);