The problem was that I originally had the caller define the instance
structure (well, kind of... ;)). I discovered this didn't work (I was
too much rsyslog-minded, especially in my assumptions), changed things
and forgot to re-test with the old interface. New patch attached,
replaces the old one. I have done some limited testing with rsyslog
itself.
As a side-note, one must be careful when converting to the new
interface. If just the dbi_initialize_r() is used but the others use the
old functions, there is a lot of trouble. I ran myself into it.
Unfortunately, I have no smart idea how to circumvent it. The deprecated
macros will probably help... ;)
Rainer
On Sat, 2008-02-16 at 17:07 +0100, Markus Hoenicka wrote:
> Rainer Gerhards writes:
> > Please review the patch, comments are of course welcome.
> >
>
> Thanks for the patch, which looks pretty clean and useful. However, a
> quick test on FreeBSD using libdbi-drivers "make check" (which
> still uses the *old* interface) causes a coredump:
>
> 5 drivers available: /usr/local/bin/bash: line 4: 5147 Segmentation fault:
> 11 (core dumped) ${dir}$tst
>
> and gdb says:
>
> (gdb) bt
> #0 0x28080561 in dbi_driver_get_name () from /usr/local/lib/libdbi.so.0
> #1 0x0804a8df in ask_for_conninfo (ptr_cinfo=0xbfbfe240) at test_dbi.c:525
> #2 0x08049883 in main (argc=1, argv=0xbfbfe758) at test_dbi.c:69
>
> I'll further investigate, but if you see an obvious error in the code
> based on this observation, let me know.
>
> regards,
> Markus
>
diff -ru -x '*.Log' -x '*.log' -x Entries -x '*.sh' -x configure libdbi/include/dbi/dbi-dev.h libdbi.new/include/dbi/dbi-dev.h
--- libdbi/include/dbi/dbi-dev.h 2008-01-15 01:21:25.000000000 +0100
+++ libdbi.new/include/dbi/dbi-dev.h 2008-02-15 19:26:24.000000000 +0100
@@ -35,6 +35,7 @@
/* to fool the compiler into letting us use the following structs before they're actually defined: */
typedef struct dbi_driver_s *dbi_driver_t_pointer;
+typedef struct dbi_inst_s *dbi_inst_t_pointer;
typedef struct dbi_conn_s *dbi_conn_t_pointer;
typedef struct _field_binding_s *_field_binding_t_pointer;
@@ -147,6 +148,7 @@
dbi_custom_function_t *custom_functions;
const char **reserved_words;
_capability_t *caps;
+ dbi_inst_t_pointer dbi_inst; /* engine instance we are called from */
struct dbi_driver_s *next;
} dbi_driver_t;
@@ -180,6 +182,16 @@
int _get_field_flag(dbi_row_t *row, unsigned int fieldidx, unsigned char flag);
+/******************************
+ * DBI INSTANCE RELATED TYPES *
+ ******************************/
+typedef struct dbi_inst_s {
+ dbi_driver_t *rootdriver;
+ dbi_conn_t *rootconn;
+ int dbi_verbosity;
+} dbi_inst_t;
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff -ru -x '*.Log' -x '*.log' -x Entries -x '*.sh' -x configure libdbi/include/dbi/dbi.h libdbi.new/include/dbi/dbi.h
--- libdbi/include/dbi/dbi.h 2008-02-15 20:11:03.000000000 +0100
+++ libdbi.new/include/dbi/dbi.h 2008-02-16 13:10:19.000000000 +0100
@@ -41,6 +41,7 @@
#endif
/* opaque type definitions */
+typedef void * dbi_inst;
typedef void * dbi_driver;
typedef void * dbi_conn;
typedef void * dbi_result;
@@ -159,13 +160,18 @@
/* needed by get_engine_version functions */
#define VERSIONSTRING_LENGTH 32
-int dbi_initialize(const char *driverdir);
-void dbi_shutdown();
+int dbi_initialize_r(const char *driverdir, dbi_inst **Inst);
+int LIBDBI_API_DEPRECATED dbi_initialize(const char *driverdir);
+void dbi_shutdown_r(dbi_inst Inst);
+void LIBDBI_API_DEPRECATED dbi_shutdown();
const char *dbi_version();
-int dbi_set_verbosity(int verbosity);
+int dbi_set_verbosity_r(int verbosity, dbi_inst Inst);
+int LIBDBI_API_DEPRECATED dbi_set_verbosity(int verbosity);
-dbi_driver dbi_driver_list(dbi_driver Current); /* returns next driver. if current is NULL, return first driver. */
-dbi_driver dbi_driver_open(const char *name); /* goes thru linked list until it finds the right one */
+dbi_driver dbi_driver_list_r(dbi_driver Current, dbi_inst Inst);
+dbi_driver LIBDBI_API_DEPRECATED dbi_driver_list(dbi_driver Current); /* returns next driver. if current is NULL, return first driver. */
+dbi_driver dbi_driver_open_r(const char *name, dbi_inst Inst);
+dbi_driver LIBDBI_API_DEPRECATED dbi_driver_open(const char *name); /* goes thru linked list until it finds the right one */
int dbi_driver_is_reserved_word(dbi_driver Driver, const char *word);
void *dbi_driver_specific_function(dbi_driver Driver, const char *name);
size_t LIBDBI_API_DEPRECATED dbi_driver_quote_string_copy(dbi_driver Driver, const char *orig, char **newstr);
@@ -182,7 +188,8 @@
const char *dbi_driver_get_version(dbi_driver Driver);
const char *dbi_driver_get_date_compiled(dbi_driver Driver);
-dbi_conn dbi_conn_new(const char *name); /* shortcut for dbi_conn_open(dbi_driver_open("foo")) */
+dbi_conn dbi_conn_new_r(const char *name, dbi_inst Inst);
+dbi_conn LIBDBI_API_DEPRECATED dbi_conn_new(const char *name); /* shortcut for dbi_conn_open(dbi_driver_open("foo")) */
dbi_conn dbi_conn_open(dbi_driver Driver); /* returns an actual instance of the conn */
dbi_driver dbi_conn_get_driver(dbi_conn Conn);
int dbi_conn_set_option(dbi_conn Conn, const char *key, const char *value); /* if value is NULL, remove option from list */
diff -ru -x '*.Log' -x '*.log' -x Entries -x '*.sh' -x configure libdbi/src/dbi_main.c libdbi.new/src/dbi_main.c
--- libdbi/src/dbi_main.c 2008-02-06 17:21:29.000000000 +0100
+++ libdbi.new/src/dbi_main.c 2008-02-16 15:01:26.000000000 +0100
@@ -113,7 +113,7 @@
#endif
/* declarations for internal functions -- anything declared as static won't be accessible by name from client programs */
-static dbi_driver_t *_get_driver(const char *filename);
+static dbi_driver_t *_get_driver(const char *filename, dbi_inst_t *inst);
static void _free_custom_functions(dbi_driver_t *driver);
static dbi_option_t *_find_or_create_option_node(dbi_conn Conn, const char *key);
static int _update_internal_conn_list(dbi_conn_t *conn, int operation);
@@ -131,13 +131,12 @@
/* must not be called "ERROR" due to a name clash on Windoze */
static const char *my_ERROR = "ERROR";
-static dbi_driver_t *rootdriver;
-static dbi_conn_t *rootconn;
-int dbi_verbosity = 1;
+static dbi_inst *dbi_inst_legacy;
/* XXX DBI CORE FUNCTIONS XXX */
-int dbi_initialize(const char *driverdir) {
+int dbi_initialize_r(const char *driverdir, dbi_inst **Inst) {
+ dbi_inst_t *inst;
DIR *dir;
struct dirent *driver_dirent = NULL;
struct stat statbuf;
@@ -150,7 +149,16 @@
#if HAVE_LTDL_H
(void)lt_dlinit();
#endif
- rootdriver = NULL;
+ /* init the instance */
+ inst = malloc(sizeof(dbi_inst_t));
+ if (!inst) {
+ return -1;
+ }
+ *Inst = (void*) inst;
+ inst->rootdriver = NULL;
+ inst->rootconn = NULL;
+ inst->dbi_verbosity = 1; /* TODO: is this really the right default? */
+ /* end instance init */
effective_driverdir = (driverdir ? (char *)driverdir : DBI_DRIVER_DIR);
dir = opendir(effective_driverdir);
@@ -163,10 +171,10 @@
snprintf(fullpath, FILENAME_MAX, "%s%s%s", effective_driverdir, DBI_PATH_SEPARATOR, driver_dirent->d_name);
if ((stat(fullpath, &statbuf) == 0) && S_ISREG(statbuf.st_mode) && strrchr(driver_dirent->d_name, '.') && (!strcmp(strrchr(driver_dirent->d_name, '.'), DRIVER_EXT))) {
/* file is a stat'able regular file that ends in .so (or appropriate dynamic library extension) */
- driver = _get_driver(fullpath);
+ driver = _get_driver(fullpath, inst);
if (driver && (driver->functions->initialize(driver) != -1)) {
- if (!rootdriver) {
- rootdriver = driver;
+ if (!inst->rootdriver) {
+ inst->rootdriver = driver;
}
if (prevdriver) {
prevdriver->next = driver;
@@ -179,7 +187,7 @@
if (driver && driver->functions) free(driver->functions);
if (driver) free(driver);
driver = NULL; /* don't include in linked list */
- if (dbi_verbosity) fprintf(stderr, "libdbi: Failed to load driver: %s\n", fullpath);
+ if (inst->dbi_verbosity) fprintf(stderr, "libdbi: Failed to load driver: %s\n", fullpath);
}
}
}
@@ -189,11 +197,16 @@
return num_loaded;
}
-void dbi_shutdown() {
- dbi_conn_t *curconn = rootconn;
+int dbi_initialize(const char *driverdir) {
+ dbi_initialize_r(driverdir, &dbi_inst_legacy);
+}
+
+void dbi_shutdown_r(dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
+ dbi_conn_t *curconn = inst->rootconn;
dbi_conn_t *nextconn;
- dbi_driver_t *curdriver = rootdriver;
+ dbi_driver_t *curdriver = inst->rootdriver;
dbi_driver_t *nextdriver;
while (curconn) {
@@ -215,37 +228,50 @@
#if HAVE_LTDL_H
(void)lt_dlexit();
#endif
- rootdriver = NULL;
+ free(inst);
+}
+
+void dbi_shutdown() {
+ dbi_shutdown_r(dbi_inst_legacy);
}
const char *dbi_version() {
return "libdbi v" VERSION;
}
-int dbi_set_verbosity(int verbosity) {
+int dbi_set_verbosity_r(int verbosity, dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
/* whether or not to spew stderr messages when something bad happens (and
* isn't handled through the normal connection-oriented DBI error
* mechanisms) */
- int prev = dbi_verbosity;
- dbi_verbosity = verbosity;
+ int prev = inst->dbi_verbosity;
+ inst->dbi_verbosity = verbosity;
return prev;
}
+int dbi_set_verbosity(int verbosity) {
+ return dbi_set_verbosity_r(verbosity, dbi_inst_legacy);
+}
/* XXX DRIVER FUNCTIONS XXX */
-dbi_driver dbi_driver_list(dbi_driver Current) {
+dbi_driver dbi_driver_list_r(dbi_driver Current, dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
dbi_driver_t *current = Current;
if (current == NULL) {
- return (dbi_driver)rootdriver;
+ return (dbi_driver)inst->rootdriver;
}
return (dbi_driver)current->next;
}
+dbi_driver dbi_driver_list(dbi_driver Current) {
+ return dbi_driver_list_r(Current, dbi_inst_legacy);
+}
-dbi_driver dbi_driver_open(const char *name) {
- dbi_driver_t *driver = rootdriver;
+dbi_driver dbi_driver_open_r(const char *name, dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
+ dbi_driver_t *driver = inst->rootdriver;
while (driver && strcasecmp(name, driver->info->name)) {
driver = driver->next;
@@ -253,6 +279,9 @@
return driver;
}
+dbi_driver dbi_driver_open(const char *name) {
+ return dbi_driver_open_r(name, dbi_inst_legacy);
+}
int dbi_driver_is_reserved_word(dbi_driver Driver, const char *word) {
unsigned int idx = 0;
@@ -445,15 +474,18 @@
/* XXX DRIVER FUNCTIONS XXX */
-dbi_conn dbi_conn_new(const char *name) {
+dbi_conn dbi_conn_new_r(const char *name, dbi_inst Inst) {
dbi_driver driver;
dbi_conn conn;
- driver = dbi_driver_open(name);
+ driver = dbi_driver_open_r(name, Inst);
conn = dbi_conn_open(driver);
return conn;
}
+dbi_conn dbi_conn_new(const char *name) {
+ dbi_conn_new_r(name, dbi_inst_legacy);
+}
dbi_conn dbi_conn_open(dbi_driver Driver) {
dbi_driver_t *driver = Driver;
@@ -1162,7 +1194,7 @@
/* XXX INTERNAL PRIVATE IMPLEMENTATION FUNCTIONS XXX */
-static dbi_driver_t *_get_driver(const char *filename) {
+static dbi_driver_t *_get_driver(const char *filename, dbi_inst_t *inst) {
dbi_driver_t *driver;
void *dlhandle;
const char **custom_functions_list;
@@ -1183,6 +1215,7 @@
driver->dlhandle = dlhandle;
driver->filename = strdup(filename);
+ driver->dbi_inst = inst;
driver->next = NULL;
driver->caps = NULL;
driver->functions = malloc(sizeof(dbi_functions_t));
@@ -1289,7 +1322,7 @@
* operation = -1: remove conn
* = 0: just look for conn (return 1 if found, -1 if not)
* = 1: add conn */
- dbi_conn_t *curconn = rootconn;
+ dbi_conn_t *curconn = conn->driver->dbi_inst->rootconn;
dbi_conn_t *prevconn = NULL;
if ((operation == -1) || (operation == 0)) {
@@ -1301,7 +1334,7 @@
if (operation == 0) return 1;
else if (operation == -1) {
if (prevconn) prevconn->next = curconn->next;
- else rootconn = NULL;
+ else conn->driver->dbi_inst->rootconn = NULL;
return 0;
}
}
@@ -1313,7 +1346,7 @@
curconn->next = conn;
}
else {
- rootconn = conn;
+ conn->driver->dbi_inst->rootconn = conn;
}
conn->next = NULL;
return 0;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
libdbi-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libdbi-devel