implement evsql_destroy, although it's still not callable from any callbacks
authorTero Marttila <terom@fixme.fi>
Mon, 16 Mar 2009 23:33:38 +0200
changeset 64 83d53afa2551
parent 63 76a782abddca
child 65 8b8de7f6e0e9
implement evsql_destroy, although it's still not callable from any callbacks
src/core.c
src/include/evsql.h
src/internal.h
src/result.c
--- a/src/core.c	Mon Mar 16 21:48:13 2009 +0200
+++ b/src/core.c	Mon Mar 16 23:33:38 2009 +0200
@@ -86,10 +86,11 @@
  */
 static void _evsql_query_done (struct evsql_query *query, struct evsql_result *res) {
     if (res) {
-        if (query->cb_fn)
+        if (query->cb_fn) {
             // call the callback
             query->cb_fn(res, query->cb_arg);
-        else {
+
+        } else {
             WARNING("supressing cb_fn because query was aborted");
             
             // free the results
@@ -155,6 +156,7 @@
     LIST_REMOVE(conn, entry);
     
     // catch deadlocks
+    // XXX: still just assert?
     assert(!LIST_EMPTY(&conn->evsql->conn_list) || TAILQ_EMPTY(&conn->evsql->query_queue));
 
     // free
@@ -570,7 +572,7 @@
     return evsql;
 
 error:
-    // XXX: more complicated than this?
+    // there's no other state yet
     free(evsql); 
 
     return NULL;
@@ -913,3 +915,53 @@
     }
 }
 
+void evsql_destroy (struct evsql *evsql) {
+    struct evsql_query *query;
+    struct evsql_conn *conn;
+
+    // kill off all queued queries
+    while ((query = TAILQ_FIRST(&evsql->query_queue)) != NULL) {
+        // just free it, command first
+        free(query->command); query->command = NULL;
+        _evsql_query_free(query);
+    }
+    
+    // kill off all connections
+    while ((conn = LIST_FIRST(&evsql->conn_list)) != NULL) {
+        // kill off the query
+        if (conn->query) {
+            free(query->command); query->command = NULL;
+            _evsql_query_free(query);
+
+            conn->query = NULL;
+        }
+
+        // kill off the transaction
+        if (conn->trans) {
+            conn->trans->query = NULL;
+            _evsql_trans_release(conn->trans);
+        }
+
+        // kill it off
+        _evsql_conn_release(conn);
+    }
+
+    // then free the evsql itself
+    free(evsql);
+}
+
+void _evsql_destroy_handler (int fd, short what, void *arg)
+{
+    struct evsql *evsql = arg;
+
+    evsql_destroy(evsql);
+}
+
+evsql_err_t evsql_destroy_next (struct evsql *evsql)
+{
+    struct timeval tv = {0, 0};
+
+    // schedule a one-time event
+    return event_base_once(evsql->ev_base, 0, EV_TIMEOUT, &_evsql_destroy_handler, evsql, &tv);
+}
+
--- a/src/include/evsql.h	Mon Mar 16 21:48:13 2009 +0200
+++ b/src/include/evsql.h	Mon Mar 16 23:33:38 2009 +0200
@@ -415,16 +415,25 @@
     void *cb_arg
 );
 
-// @}
-
 /**
- * Close a connection. Callbacks for waiting queries will not be run.
+ * Close the evsql handle. IMPORTANT: There are severe restrictions on the use of this function. It must *NOT* be
+ * called from any evsql_*_cb callback, or the program will probably crash after the callback returns.
  *
- * XXX: not implemented yet.
+ * Currently, the evsql handle can only be free'd if the entire evsql is idle, so this will silently abort any
+ * pending queries and transactions, which may lead to nasty things.
+ *
+ * As a workaround to the callback-issue, you can call evsql_destroy from the next event loop iteration, which is
+ * what evsql_destroy_next does for you.
  *
  * @param evsql the context handle from \ref evsql_new_
  */
-void evsql_close (struct evsql *evsql);
+void evsql_destroy (struct evsql *evsql);
+
+/**
+ * Call evsql_destroy in the next event loop iteration. If scheduling this fails, we return -1 (not a meaningful error
+ * code, but nonzero).
+ */
+evsql_err_t evsql_destroy_next (struct evsql *evsql);
 
 // @}
 
--- a/src/internal.h	Mon Mar 16 21:48:13 2009 +0200
+++ b/src/internal.h	Mon Mar 16 23:33:38 2009 +0200
@@ -93,7 +93,6 @@
 
     // our current query
     struct evsql_query *query;
-
 };
 
 /*
--- a/src/result.c	Mon Mar 16 21:48:13 2009 +0200
+++ b/src/result.c	Mon Mar 16 23:33:38 2009 +0200
@@ -255,4 +255,3 @@
     }
 }
 
-