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:
parent
30b89d7808
commit
d7659ea8c1
|
@ -263,6 +263,9 @@ DRIVER_INIT(bdberl_drv)
|
||||||
DB_RECOVER | /* Enable support for recovering from failures */
|
DB_RECOVER | /* Enable support for recovering from failures */
|
||||||
DB_CREATE | /* Create files as necessary */
|
DB_CREATE | /* Create files as necessary */
|
||||||
DB_REGISTER | /* Run recovery if needed */
|
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_USE_ENVIRON | /* Use DB_HOME environment variable */
|
||||||
DB_THREAD; /* Make the environment free-threaded */
|
DB_THREAD; /* Make the environment free-threaded */
|
||||||
|
|
||||||
|
@ -285,9 +288,30 @@ DRIVER_INIT(bdberl_drv)
|
||||||
}
|
}
|
||||||
else
|
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);
|
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);
|
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);
|
G_DB_ENV_ERROR = G_DB_ENV->open(G_DB_ENV, 0, flags, 0);
|
||||||
DBG(" = %d\n", G_DB_ENV_ERROR);
|
DBG(" = %d\n", G_DB_ENV_ERROR);
|
||||||
|
|
|
@ -25,11 +25,19 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------- */
|
* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
#include "bdberl_drv.h"
|
||||||
#include "bdberl_tpool.h"
|
#include "bdberl_tpool.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 void* bdberl_tpool_main(void* tpool);
|
||||||
static TPoolJob* next_job(TPool* 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;
|
*active_count_ptr = tpool->active_job_count;
|
||||||
UNLOCK(tpool);
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue