#include <fcntl.h>
#include <unistd.h>
#include <cassandra.h>
+#include <pthread.h>
#define IS_CONNECTED(db) \
((db)->api.state != SQL_DB_STATE_DISCONNECTED && \
.name = "cassandra"
};
+static pthread_t main_thread_id;
+static bool main_thread_id_set;
+
static void driver_cassandra_prepare_pending(struct cassandra_db *db);
static void
prepare_finish_pending_statements(struct cassandra_sql_prepared_statement *prep_stmt);
{
struct cassandra_callback *cb = context;
- if (cb->id == 0) {
+ if (pthread_equal(pthread_self(), main_thread_id) != 0) {
/* called immediately from the main thread. */
+ cassandra_callback_detach(cb->db, cb->id);
cb->to = timeout_add_short(0, cassandra_callback_run, cb);
return;
}
cb->context = context;
cb->db = db;
- /* NOTE: The callback may be called immediately. This is checked by
- seeing whether cb->id==0, so set it only after this call. */
- cass_future_set_callback(future, driver_cassandra_future_callback, cb);
-
- if (cb->to == NULL) {
- /* callback will be called later */
- array_push_back(&db->callbacks, &cb);
+ array_push_back(&db->callbacks, &cb);
+ cb->id = ++db->callback_ids;
+ if (cb->id == 0)
cb->id = ++db->callback_ids;
- if (cb->id == 0)
- cb->id = ++db->callback_ids;
- }
+
+ /* NOTE: The callback may be called immediately by this same thread.
+ This is checked within the callback. It may also be called at any
+ time after this call by another thread. So we must not access "cb"
+ again after this call. */
+ cass_future_set_callback(future, driver_cassandra_future_callback, cb);
}
static void connect_callback(CassFuture *future, void *context)
i_array_init(&db->results, 16);
i_array_init(&db->callbacks, 16);
i_array_init(&db->pending_prepares, 16);
+ if (!main_thread_id_set) {
+ main_thread_id = pthread_self();
+ main_thread_id_set = TRUE;
+ }
+
*db_r = &db->api;
return 0;
}