Allow driver instances to use different threads
This commit is contained in:
@@ -93,6 +93,37 @@ static void driver_free_binary_fun(void *ptr) {
|
|||||||
driver_free_binary((ErlDrvBinary *) ptr);
|
driver_free_binary((ErlDrvBinary *) ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sdbm from http://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
unsigned int hash(const char *str) {
|
||||||
|
unsigned int hash = 0;
|
||||||
|
unsigned int c = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
|
c = *str++;
|
||||||
|
} while (c);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a key determined by the file name for an on-disk database,
|
||||||
|
// determined by the port for a private database.
|
||||||
|
// This way all access to a single DB will go through one async thread.
|
||||||
|
static inline unsigned int sql_async_key(char *db_name, ErlDrvPort port) {
|
||||||
|
const char *memory_db_name = ":memory:";
|
||||||
|
|
||||||
|
if (strcmp(db_name, memory_db_name)) {
|
||||||
|
return hash(db_name);
|
||||||
|
} else {
|
||||||
|
#if ERL_DRV_EXTENDED_MAJOR_VERSION > 2 || \
|
||||||
|
(ERL_DRV_EXTENDED_MAJOR_VERSION == 2 && ERL_DRV_EXTENDED_MINOR_VERSION >= 2)
|
||||||
|
return driver_async_port_key(port);
|
||||||
|
#else
|
||||||
|
return (unsigned int) (uintptr_t) port;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ErlDrvEntry sqlite3_driver_entry = {
|
static ErlDrvEntry sqlite3_driver_entry = {
|
||||||
NULL, /* init */
|
NULL, /* init */
|
||||||
start, /* startup (defined below) */
|
start, /* startup (defined below) */
|
||||||
@@ -186,9 +217,7 @@ static ErlDrvData start(ErlDrvPort port, char* cmd) {
|
|||||||
drv->port = port;
|
drv->port = port;
|
||||||
drv->db = db;
|
drv->db = db;
|
||||||
drv->db_name = db_name_copy;
|
drv->db_name = db_name_copy;
|
||||||
drv->key = 42;
|
drv->key = sql_async_key(db_name_copy, port);
|
||||||
// FIXME Any way to get canonical path to the DB?
|
|
||||||
// We need to ensure equal keys for different paths to the same file
|
|
||||||
drv->async_handle = 0;
|
drv->async_handle = 0;
|
||||||
drv->prepared_stmts = NULL;
|
drv->prepared_stmts = NULL;
|
||||||
drv->prepared_count = 0;
|
drv->prepared_count = 0;
|
||||||
|
|||||||
@@ -50,10 +50,6 @@ typedef int ErlDrvSSizeT;
|
|||||||
#define CMD_SQL_EXEC_SCRIPT 12
|
#define CMD_SQL_EXEC_SCRIPT 12
|
||||||
#define CMD_ENABLE_LOAD_EXTENSION 13
|
#define CMD_ENABLE_LOAD_EXTENSION 13
|
||||||
|
|
||||||
// Number of bytes for each key
|
|
||||||
// (160 bits for SHA1 hash)
|
|
||||||
#define KEY_SIZE 20
|
|
||||||
|
|
||||||
typedef struct ptr_list {
|
typedef struct ptr_list {
|
||||||
void *head;
|
void *head;
|
||||||
struct ptr_list *tail;
|
struct ptr_list *tail;
|
||||||
|
|||||||
Reference in New Issue
Block a user