From d833ca708c98405ee42a33750782128c670a6e6b Mon Sep 17 00:00:00 2001 From: Jon Meredith Date: Mon, 9 Feb 2009 15:01:25 -0700 Subject: [PATCH] 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. --- c_src/bdberl_drv.c | 10 +++++----- c_src/bdberl_tpool.c | 6 +++--- c_src/bdberl_tpool.h | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/c_src/bdberl_drv.c b/c_src/bdberl_drv.c index 7b7f22f..564e5eb 100644 --- a/c_src/bdberl_drv.c +++ b/c_src/bdberl_drv.c @@ -447,7 +447,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd, d->async_flags = UNPACK_INT(inbuf, 0); } 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 <> RETURN_INT(0, outbuf); @@ -496,8 +496,8 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd, fn = &do_async_get; } 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 // Outbuf is: <<0:32>> RETURN_INT(0, outbuf); @@ -561,7 +561,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd, // Schedule the operation d->async_op = cmd; 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 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 d->async_op = cmd; 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 // Outbuf is: <<0:32>> diff --git a/c_src/bdberl_tpool.c b/c_src/bdberl_tpool.c index 22dd6db..147f134 100644 --- a/c_src/bdberl_tpool.c +++ b/c_src/bdberl_tpool.c @@ -74,10 +74,11 @@ void bdberl_tpool_stop(TPool* 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 - TPoolJob* job = driver_alloc(sizeof(TPoolJob)); + TPoolJob* job = *job_ptr = driver_alloc(sizeof(TPoolJob)); memset(job, '\0', sizeof(TPoolJob)); job->main_fn = main_fn; 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 erl_drv_cond_broadcast(tpool->work_cv); UNLOCK(tpool); - return job; } void bdberl_tpool_cancel(TPool* tpool, TPoolJob* job) diff --git a/c_src/bdberl_tpool.h b/c_src/bdberl_tpool.h index 6f6e23a..f1ebee8 100644 --- a/c_src/bdberl_tpool.h +++ b/c_src/bdberl_tpool.h @@ -60,7 +60,8 @@ TPool* bdberl_tpool_start(unsigned int thread_count); 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);