[tracker/async-get-connection: 5/5] libtracker-sparql: Added locking to sync/async connection_get() methods
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/async-get-connection: 5/5] libtracker-sparql: Added locking to sync/async connection_get() methods
- Date: Wed, 29 Sep 2010 15:37:21 +0000 (UTC)
commit 25073e54a568981d88ac5dd74491a7d9011f908b
Author: Martyn Russell <martyn lanedo com>
Date: Wed Sep 29 16:27:06 2010 +0100
libtracker-sparql: Added locking to sync/async connection_get() methods
src/libtracker-sparql/tracker-connection.vala | 24 +++++++---
tests/libtracker-sparql/tracker-test.c | 59 +++++++++++++++++++++++++
2 files changed, 75 insertions(+), 8 deletions(-)
---
diff --git a/src/libtracker-sparql/tracker-connection.vala b/src/libtracker-sparql/tracker-connection.vala
index 333f5f7..d67e361 100644
--- a/src/libtracker-sparql/tracker-connection.vala
+++ b/src/libtracker-sparql/tracker-connection.vala
@@ -83,56 +83,63 @@ public abstract class Tracker.Sparql.Connection : Object {
static bool direct_only;
static weak Connection? singleton;
static bool log_initialized;
+ static StaticMutex door;
private static new Connection get_internal (bool is_direct_only = false, Cancellable? cancellable = null) throws Sparql.Error, IOError {
+ door.lock ();
+
if (singleton != null) {
assert (direct_only == is_direct_only);
+ door.unlock ();
return singleton;
}
log_init ();
- if (cancellable != null && cancellable.is_cancelled ()) {
- throw new IOError.CANCELLED ("Operation was cancelled");
- }
-
/* the True is to assert that direct only is required */
Connection result = new Backend (is_direct_only);
result.init ();
if (cancellable != null && cancellable.is_cancelled ()) {
+ door.unlock ();
throw new IOError.CANCELLED ("Operation was cancelled");
}
direct_only = is_direct_only;
singleton = result;
result.add_weak_pointer ((void**) (&singleton));
+
+ door.unlock ();
+
return singleton;
}
private async static new Connection get_internal_async (bool is_direct_only = false, Cancellable? cancellable = null) throws Sparql.Error, IOError {
+ door.lock ();
+
if (singleton != null) {
assert (direct_only == is_direct_only);
+ door.unlock ();
return singleton;
}
log_init ();
- if (cancellable != null && cancellable.is_cancelled ()) {
- throw new IOError.CANCELLED ("Operation was cancelled");
- }
-
/* the True is to assert that direct only is required */
Connection result = new Backend (is_direct_only);
yield result.init_async ();
if (cancellable != null && cancellable.is_cancelled ()) {
+ door.unlock ();
throw new IOError.CANCELLED ("Operation was cancelled");
}
direct_only = is_direct_only;
singleton = result;
result.add_weak_pointer ((void**) (&singleton));
+
+ door.unlock ();
+
return singleton;
}
@@ -147,6 +154,7 @@ public abstract class Tracker.Sparql.Connection : Object {
* object when no longer used.
*/
public async static new Connection get_async (Cancellable? cancellable = null) throws Sparql.Error, IOError {
+
return yield get_internal_async (false, cancellable);
}
diff --git a/tests/libtracker-sparql/tracker-test.c b/tests/libtracker-sparql/tracker-test.c
index 7be6933..073cbcc 100644
--- a/tests/libtracker-sparql/tracker-test.c
+++ b/tests/libtracker-sparql/tracker-test.c
@@ -221,6 +221,61 @@ test_tracker_sparql_cursor_next_async (void)
test_tracker_sparql_cursor_next_async_query (0);
}
+static void
+test_tracker_sparql_connection_locking_sync (void)
+{
+ TrackerSparqlConnection *c1, *c2, *c3;
+
+ c1 = tracker_sparql_connection_get (NULL, NULL);
+ c2 = tracker_sparql_connection_get (NULL, NULL);
+ c3 = tracker_sparql_connection_get (NULL, NULL);
+ g_assert (c1 == c2);
+ g_assert (c2 == c3);
+
+ g_object_unref (c1);
+ g_object_unref (c2);
+ g_object_unref (c3);
+}
+
+static TrackerSparqlConnection *c1 = NULL;
+static TrackerSparqlConnection *c2 = NULL;
+static TrackerSparqlConnection *c3 = NULL;
+
+static void
+test_tracker_sparql_connection_locking_async_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ TrackerSparqlConnection *connection;
+ TrackerSparqlConnection *connection_waiting;
+ GError *error = NULL;
+
+ g_assert (result != NULL);
+ connection = tracker_sparql_connection_get_finish (result, &error);
+ g_assert_no_error (error);
+ g_assert (connection != NULL);
+
+ if (!c1) {
+ g_message ("GOT connection #1, waiting connection:%p (expecting NULL)", user_data);
+ c1 = connection;
+ } else if (!c2) {
+ g_message ("GOT connection #2, waiting connection:%p (expecting NULL)", user_data);
+ c2 = connection;
+ }
+
+ connection_waiting = user_data;
+ g_assert (connection_waiting == NULL);
+}
+
+static void
+test_tracker_sparql_connection_locking_async (void)
+{
+ tracker_sparql_connection_get_async (NULL, test_tracker_sparql_connection_locking_async_cb, c2);
+ tracker_sparql_connection_get_async (NULL, test_tracker_sparql_connection_locking_async_cb, c3);
+ c3 = tracker_sparql_connection_get (NULL, NULL);
+ g_assert (c3 != NULL);
+}
+
#endif
gint
@@ -248,6 +303,10 @@ main (gint argc, gchar **argv)
test_tracker_sparql_escape_string);
g_test_add_func ("/libtracker-sparql/tracker/tracker_sparql_escape_uri_vprintf",
test_tracker_sparql_escape_uri_vprintf);
+ g_test_add_func ("/libtracker-sparql/tracker/tracker_sparql_connection_locking_sync",
+ test_tracker_sparql_connection_locking_sync);
+ g_test_add_func ("/libtracker-sparql/tracker/tracker_sparql_connection_locking_async",
+ test_tracker_sparql_connection_locking_async);
#if HAVE_TRACKER_FTS
g_test_add_func ("/libtracker-sparql/tracker/tracker_sparql_cursor_next_async",
test_tracker_sparql_cursor_next_async);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]