summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 18a3621)
raw | patch | inline | side by side (parent: 18a3621)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 15 Nov 2012 06:43:02 +0000 (07:43 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Thu, 15 Nov 2012 06:43:02 +0000 (07:43 +0100) |
This will make sure that all pending transactions will be committed. Else, the
open transactions would be rolled back by the PostgreSQL backend when closing
the connection.
In order to do so, all database connections are now stored in a plugin-global
array (this will also make further changes possible). Also, a ref-count has
been added to the database object in order to support "deleting" an object
twice when having it in use by a connection doing queries and writes.
open transactions would be rolled back by the PostgreSQL backend when closing
the connection.
In order to do so, all database connections are now stored in a plugin-global
array (this will also make further changes possible). Also, a ref-count has
been added to the database object in order to support "deleting" an object
twice when having it in use by a connection doing queries and writes.
src/postgresql.c | patch | blob | history |
diff --git a/src/postgresql.c b/src/postgresql.c
index 4d9fc564ff5f143a9aa88fdc43f9ae023b9f38cd..4d2436056fd76cac09f2b6a92a2304125ddab715 100644 (file)
--- a/src/postgresql.c
+++ b/src/postgresql.c
char *krbsrvname;
char *service;
+
+ int ref_cnt;
} c_psql_database_t;
static char *def_queries[] = {
};
static int def_queries_num = STATIC_ARRAY_SIZE (def_queries);
+static c_psql_database_t *databases = NULL;
+static size_t databases_num = 0;
+
static udb_query_t **queries = NULL;
static size_t queries_num = 0;
{
c_psql_database_t *db;
- db = (c_psql_database_t *)malloc (sizeof (*db));
+ db = (c_psql_database_t *)realloc (databases,
+ (databases_num + 1) * sizeof (*db));
if (NULL == db) {
log_err ("Out of memory.");
return NULL;
}
+ databases = db;
+ db = databases + databases_num;
+ ++databases_num;
+
db->conn = NULL;
C_COMPLAIN_INIT (&db->conn_complaint);
db->krbsrvname = NULL;
db->service = NULL;
+
+ db->ref_cnt = 0;
return db;
} /* c_psql_database_new */
c_psql_database_t *db = data;
+ --db->ref_cnt;
+ /* readers and writers may access this database */
+ if (db->ref_cnt > 0)
+ return;
+
/* wait for the lock to be released by the last writer */
pthread_mutex_lock (&db->db_lock);
sfree (db->krbsrvname);
sfree (db->service);
+
+ /* don't care about freeing or reordering the 'databases' array
+ * this is done in 'shutdown' */
return;
} /* c_psql_database_delete */
int buf_len = sizeof (conninfo);
int status;
- if (! db)
+ if ((! db) || (! db->database))
return -1;
status = ssnprintf (buf, buf_len, "dbname = '%s'", db->database);
static int c_psql_shutdown (void)
{
+ size_t i = 0;
+
plugin_unregister_read_group ("postgresql");
+ for (i = 0; i < databases_num; ++i) {
+ c_psql_database_t *db = databases + i;
+ size_t j = 0;
+
+ for (j = 0; j < db->writers_num; ++j) {
+ char cb_name[DATA_MAX_NAME_LEN];
+
+ ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s",
+ db->database);
+ plugin_unregister_write (cb_name);
+ }
+ }
+
udb_query_free (queries, queries_num);
queries = NULL;
queries_num = 0;
writers = NULL;
writers_num = 0;
+ sfree (databases);
+ databases = NULL;
+ databases_num = 0;
+
return 0;
} /* c_psql_shutdown */
if (db->queries_num > 0) {
CDTIME_T_TO_TIMESPEC (db->interval, &cb_interval);
+ ++db->ref_cnt;
plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
/* interval = */ (db->interval > 0) ? &cb_interval : NULL,
&ud);
}
if (db->writers_num > 0) {
+ ++db->ref_cnt;
plugin_register_write (cb_name, c_psql_write, &ud);
}
else if (db->commit_interval > 0) {