Add BDB failchk support which requires thread_id and is_alive (implement thread_id_string while we're at it).

This commit is contained in:
Gregory Burd 2011-12-04 14:45:30 -05:00
parent 30b89d7808
commit d7659ea8c1
2 changed files with 71 additions and 1 deletions

View file

@ -263,6 +263,9 @@ DRIVER_INIT(bdberl_drv)
DB_RECOVER | /* Enable support for recovering from failures */
DB_CREATE | /* Create files as necessary */
DB_REGISTER | /* Run recovery if needed */
DB_FAILCHK | /* Release any database reads locks held by the
thread of control that exited and, if needed,
abort unresolved transaction. */
DB_USE_ENVIRON | /* Use DB_HOME environment variable */
DB_THREAD; /* Make the environment free-threaded */
@ -285,9 +288,30 @@ DRIVER_INIT(bdberl_drv)
}
else
{
// DB should use the safe allocation routines provided by the Erlang VM
DBG("G_DB_ENV->set_alloc(%p, ...)", &G_DB_ENV);
G_DB_ENV_ERROR = G_DB_ENV->set_alloc(G_DB_ENV, driver_alloc, driver_realloc, driver_free);
DBG(" = %d", G_DB_ENV_ERROR);
DBG(" = %d\n", G_DB_ENV_ERROR);
// Inform DB of the number of threads that will be operating on the DB Environment
unsigned int nthreads = G_NUM_GENERAL_THREADS + G_NUM_TXN_THREADS;
DBG("G_DB_ENV->set_thread_count(%p, %d, ...)", &G_DB_ENV, nthreads);
G_DB_ENV_ERROR = G_DB_ENV->set_thread_count(G_DB_ENV, nthreads);
DBG(" = %d\n", G_DB_ENV_ERROR);
DBG("G_DB_ENV->set_thread_id(%p, ...)", &G_DB_ENV);
G_DB_ENV_ERROR = G_DB_ENV->set_thread_id(G_DB_ENV, &bdberl_tpool_thread_id);
DBG(" = %d\n", G_DB_ENV_ERROR);
DBG("G_DB_ENV->set_thread_id_string(%p, ...)", &G_DB_ENV);
G_DB_ENV_ERROR = G_DB_ENV->set_thread_id_string(G_DB_ENV, &bdberl_tpool_thread_id_string);
DBG(" = %d\n", G_DB_ENV_ERROR);
DBG("G_DB_ENV->set_is_alive(%p, ...)", &G_DB_ENV);
G_DB_ENV_ERROR = G_DB_ENV->set_isalive(G_DB_ENV, &bdberl_tpool_thread_is_alive);
DBG(" = %d\n", G_DB_ENV_ERROR);
// Open the DB Environment
DBG("G_DB_ENV->open(%p, 0, %08X, 0)", &G_DB_ENV, flags);
G_DB_ENV_ERROR = G_DB_ENV->open(G_DB_ENV, 0, flags, 0);
DBG(" = %d\n", G_DB_ENV_ERROR);

View file

@ -25,11 +25,19 @@
* THE SOFTWARE.
*
* ------------------------------------------------------------------- */
#include <db.h>
#include "bdberl_drv.h"
#include "bdberl_tpool.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
static void* bdberl_tpool_main(void* tpool);
static TPoolJob* next_job(TPool* tpool);
@ -356,3 +364,41 @@ void bdberl_tpool_job_count(TPool* tpool, unsigned int *pending_count_ptr,
*active_count_ptr = tpool->active_job_count;
UNLOCK(tpool);
}
// Returns a unique identifier pair for the current thread of control
void bdberl_tpool_thread_id(DB_ENV *env, pid_t *pid, db_threadid_t *tid)
{
if (pid)
*pid = getpid();
if (tid)
*tid = (db_threadid_t)pthread_self();
}
char *bdberl_tpool_thread_id_string(DB_ENV *dbenv, pid_t pid, db_threadid_t tid, char *buf)
{
snprintf(buf, DB_THREADID_STRLEN, "[pid:%08X/tid:%08X]", (unsigned int)pid, (unsigned int)tid);
return buf;
}
// Returns non-zero if the thread of control, identified by the pid and tid arguments,
// is still running.
// If DB_MUTEX_PROCESS_ONLY is set in flags then return only if the process (pid) is
// alive, ignore the thread ID.
int bdberl_tpool_thread_is_alive(DB_ENV *dbenv, pid_t pid, db_threadid_t tid, u_int32_t flags)
{
static char path[200];
static struct stat sb;
int alive = 0;
snprintf(path, 200, "/dev/%d/status", pid);
if (stat(path, &sb))
{
if (flags & DB_MUTEX_PROCESS_ONLY)
alive = 1;
else
if (pthread_kill(tid, 0) != ESRCH)
alive = 1;
}
DBG("bdberl_tpool_thread_is_alive(%08X, %08X, %d) = %d\n", pid, tid, flags, alive);
return alive;
}