Commit 58942c3e authored by Martyn Russell's avatar Martyn Russell

libtracker-sparql: Fixed waiting for service for connection.get_async()

parent 4b430f76
......@@ -7,7 +7,7 @@ Name: tracker-sparql
Description: Tracker : A library to perform SPARQL queries and updates in the
Tracker Store
Version: @VERSION@
Requires: glib-2.0 gobject-2.0 gio-2.0 gmodule-2.0
Requires: dbus-glib-1 glib-2.0 gobject-2.0 gio-2.0 gmodule-2.0
Libs: -L${libdir} -ltracker-sparql-@TRACKER_API_VERSION@
Cflags: -I${includedir}/tracker-@TRACKER_API_VERSION@ -I${includedir}/tracker-@TRACKER_API_VERSION@/libtracker-sparql
......@@ -17,12 +17,6 @@
* Boston, MA 02110-1301, USA.
*/
[DBus (name = "org.freedesktop.Tracker1.Status", timeout = 2147483647 /* INT_MAX */)]
interface Tracker.Direct.Status : GLib.Object {
public abstract void wait () throws DBus.Error;
public abstract async void wait_async () throws DBus.Error;
}
public class Tracker.Direct.Connection : Tracker.Sparql.Connection {
// only single connection is currently supported per process
static bool initialized;
......@@ -33,11 +27,6 @@ public class Tracker.Direct.Connection : Tracker.Sparql.Connection {
try {
var connection = DBus.Bus.get (DBus.BusType.SESSION);
var status = (Status) connection.get_object (TRACKER_DBUS_SERVICE,
TRACKER_DBUS_OBJECT_STATUS,
TRACKER_DBUS_INTERFACE_STATUS);
status.wait ();
} catch (DBus.Error e) {
throw new Sparql.Error.INTERNAL ("Unable to initialize database");
}
......
......@@ -9,6 +9,7 @@ INCLUDES = \
-I$(top_srcdir)/src \
-I$(top_builddir)/src \
$(WARN_CFLAGS) \
$(DBUS_CFLAGS) \
$(GLIB2_CFLAGS) \
$(GCOV_CFLAGS)
......@@ -59,6 +60,7 @@ vapi_DATA = \
libtracker_sparql_@TRACKER_API_VERSION@_la_LIBADD = \
$(GLIB2_LIBS) \
$(DBUS_LIBS) \
$(GCOV_LIBS) \
$(GIO_LIBS)
......
......@@ -17,8 +17,16 @@
* Boston, MA 02110-1301, USA.
*/
[DBus (name = "org.freedesktop.Tracker1.Status", timeout = 2147483647 /* INT_MAX */)]
interface Tracker.Backend.Status : GLib.Object {
public abstract void wait () throws DBus.Error;
[DBus (name = "Wait")]
public abstract async void wait_async () throws DBus.Error;
}
class Tracker.Sparql.Backend : Connection {
static bool initialized = false;
static bool is_constructed = false;
static bool is_initialized = false;
static Tracker.Sparql.Connection direct = null;
static Tracker.Sparql.Connection bus = null;
static enum Backend {
......@@ -29,46 +37,64 @@ class Tracker.Sparql.Backend : Connection {
private delegate Tracker.Sparql.Connection ModuleInitFunc ();
public Backend () throws Sparql.Error
public Backend (bool direct_only = false) throws Sparql.Error
requires (Module.supported ()) {
}
public override void init (bool direct_only = false, Cancellable? cancellable = null) throws Sparql.Error, IOError {
if (initialized) {
if (is_constructed) {
// Don't error or require this, > 1 new Tracker.Sparql.Connection
// objects can be created and if they are, then we don't need to do
// anything on subsequent init() calls. We just return the already
// created direct or bus objects
return;
}
try {
debug ("%s(): direct_only=%s", Log.METHOD, direct_only ? "true" : "false");
debug ("Constructing connection, direct_only=%s", direct_only ? "true" : "false");
load_plugins (direct_only);
} catch (GLib.Error e) {
throw new Sparql.Error.INTERNAL (e.message);
}
initialized = true;
is_constructed = true;
}
public async override void init_async (bool direct_only = false, Cancellable? cancellable = null) throws Sparql.Error, IOError {
if (initialized) {
// Don't error or require this, > 1 new Tracker.Sparql.Connection
// objects can be created and if they are, then we don't need to do
// anything on subsequent init() calls. We just return the already
// created direct or bus objects
return;
public override void init () throws Sparql.Error
requires (is_constructed) {
try {
var connection = DBus.Bus.get (DBus.BusType.SESSION);
var status = (Tracker.Backend.Status) connection.get_object (TRACKER_DBUS_SERVICE,
TRACKER_DBUS_OBJECT_STATUS,
TRACKER_DBUS_INTERFACE_STATUS);
// Makes sure the sevice is available
debug ("Waiting for service to become available synchronously...");
status.wait ();
debug ("Service is ready");
} catch (DBus.Error e) {
warning ("Could not connect to D-Bus service:'%s': %s", TRACKER_DBUS_INTERFACE_RESOURCES, e.message);
throw new Sparql.Error.INTERNAL (e.message);
}
is_initialized = true;
}
public async override void init_async () throws Sparql.Error
requires (is_constructed) {
try {
debug ("%s(): direct_only=%s", Log.METHOD, direct_only ? "true" : "false");
load_plugins (direct_only);
} catch (GLib.Error e) {
var connection = DBus.Bus.get (DBus.BusType.SESSION);
var status = (Tracker.Backend.Status) connection.get_object (TRACKER_DBUS_SERVICE,
TRACKER_DBUS_OBJECT_STATUS,
TRACKER_DBUS_INTERFACE_STATUS);
// Makes sure the sevice is available
debug ("Waiting for service to become available asynchronously...");
yield status.wait_async ();
debug ("Service is ready");
} catch (DBus.Error e) {
warning ("Could not connect to D-Bus service:'%s': %s", TRACKER_DBUS_INTERFACE_RESOURCES, e.message);
throw new Sparql.Error.INTERNAL (e.message);
}
initialized = true;
is_initialized = true;
}
public override Cursor query (string sparql, Cancellable? cancellable = null) throws Sparql.Error, IOError
......
......@@ -97,8 +97,8 @@ public abstract class Tracker.Sparql.Connection : Object {
}
/* the True is to assert that direct only is required */
Connection result = new Backend ();
result.init (is_direct_only, cancellable);
Connection result = new Backend (is_direct_only);
result.init ();
if (cancellable != null && cancellable.is_cancelled ()) {
throw new IOError.CANCELLED ("Operation was cancelled");
......@@ -123,8 +123,8 @@ public abstract class Tracker.Sparql.Connection : Object {
}
/* the True is to assert that direct only is required */
Connection result = new Backend ();
yield result.init_async (is_direct_only, cancellable);
Connection result = new Backend (is_direct_only);
yield result.init_async ();
if (cancellable != null && cancellable.is_cancelled ()) {
throw new IOError.CANCELLED ("Operation was cancelled");
......@@ -259,11 +259,11 @@ public abstract class Tracker.Sparql.Connection : Object {
/* do nothing */
}
public virtual void init (bool direct_only = false, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public virtual void init () throws Sparql.Error {
warning ("Interface 'init' not implemented");
}
public async virtual void init_async (bool direct_only = false, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public async virtual void init_async () throws Sparql.Error {
warning ("Interface 'init_async' not implemented");
}
......
......@@ -3,22 +3,42 @@ using Tracker.Sparql;
private static int res;
private static MainLoop loop;
private async void get_connection (bool? direct_only = false) {
private async void test_async () {
// Quite this loo because we start another one in app.run ()
loop.quit ();
try {
Connection c;
// Test async
print ("Getting connection async (direct=%s)\n", direct_only ? "yes" : "no");
if (direct_only) {
c = yield Connection.get_direct_async ();
} else {
c = yield Connection.get_async ();
}
print ("Getting connection async\n");
c = yield Connection.get_async ();
print ("Got it %p\n", c);
// Quite this loo because we start another one in app.run ()
loop.quit ();
print ("Creating app with connection\n");
TestApp app = new TestApp (c);
print ("Running app\n");
res = app.run();
} catch (GLib.IOError e1) {
warning ("Couldn't perform test: %s", e1.message);
} catch (Tracker.Sparql.Error e2) {
warning ("Couldn't perform test: %s", e2.message);
}
print ("\n");
}
private void test_sync () {
try {
Connection c;
// Test async
print ("Getting connection\n");
c = Connection.get ();
print ("Got it %p\n", c);
print ("Creating app with connection\n");
TestApp app = new TestApp (c);
......@@ -30,6 +50,8 @@ private async void get_connection (bool? direct_only = false) {
} catch (Tracker.Sparql.Error e2) {
warning ("Couldn't perform test: %s", e2.message);
}
print ("\n");
}
int
......@@ -38,13 +60,14 @@ main( string[] args )
print ("Starting...\n");
loop = new MainLoop (null, false);
// Test non-direct first
get_connection.begin (false);
test_sync ();
loop.run ();
if (res < 0) {
return res;
}
// Test direct first
get_connection.begin (true);
// Do async second
test_async.begin ();
loop.run ();
......
using Tracker;
using Tracker.Sparql;
private static int res;
private static MainLoop loop;
private async void test_async () {
// Quite this loo because we start another one in app.run ()
loop.quit ();
try {
Connection c;
// Test async
print ("Getting connection asynchronously\n");
c = yield Connection.get_async ();
print ("Got it %p\n", c);
print ("Creating app with connection\n");
TestApp app = new TestApp (c);
print ("Running app\n");
res = app.run();
} catch (GLib.IOError e1) {
warning ("Couldn't perform test: %s", e1.message);
} catch (Tracker.Sparql.Error e2) {
warning ("Couldn't perform test: %s", e2.message);
}
print ("\n");
}
private void test_sync () {
try {
Connection c;
// Test async
print ("Getting connection synchronously\n");
c = Connection.get ();
print ("Got it %p\n", c);
print ("Creating app with connection\n");
TestApp app = new TestApp (c);
print ("Running app\n");
res = app.run();
} catch (GLib.IOError e1) {
warning ("Couldn't perform test: %s", e1.message);
} catch (Tracker.Sparql.Error e2) {
warning ("Couldn't perform test: %s", e2.message);
}
print ("\n");
}
int
main( string[] args )
{
int res = -1;
print ("Starting...\n");
loop = new MainLoop (null, false);
try {
TestApp app = new TestApp (new Tracker.Direct.Connection ());
res = app.run ();
} catch (Sparql.Error e) {
warning ("Couldn't perform test: %s", e.message);
test_sync ();
if (res < 0) {
return res;
}
test_async.begin ();
loop.run ();
return res;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment