* [PATCH 1/3 v2] Add libtracker-sparql to obexd dependencies @ 2011-02-02 10:21 Radoslaw Jablonski 2011-02-02 10:21 ` [PATCH 2/3 v2] Move freeing contacts data to phonebook_req_finalize Radoslaw Jablonski 2011-02-02 10:21 ` [PATCH 3/3 v2] Use libtracker-sparql in PBAP Radoslaw Jablonski 0 siblings, 2 replies; 4+ messages in thread From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw) To: linux-bluetooth; +Cc: Radoslaw Jablonski In PBAP tracker is used only for reading and returns rather big parts of data, so using direct access libtracker-sparql is better solution than tracker D-Bus API(libtracker-sparql in most PBAP scenarios should be faster). --- Makefile.am | 4 +++- configure.ac | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/Makefile.am b/Makefile.am index a317556..fc996ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -79,7 +79,8 @@ src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) $(btio_sources) \ src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \ @EBOOK_LIBS@ @OPENOBEX_LIBS@ \ - @BLUEZ_LIBS@ @LIBICAL_LIBS@ -ldl + @BLUEZ_LIBS@ @LIBICAL_LIBS@ \ + @TRACKER_SPARQL_LIBS@ -ldl src_obexd_LDFLAGS = -Wl,--export-dynamic @@ -124,6 +125,7 @@ service_DATA = $(service_in_files:.service.in=.service) AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \ @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \ @LIBICAL_CFLAGS@ -D_FILE_OFFSET_BITS=64 \ + @TRACKER_SPARQL_CFLAGS@ \ -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\" INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \ diff --git a/configure.ac b/configure.ac index e48a3cc..aa8bfb0 100644 --- a/configure.ac +++ b/configure.ac @@ -136,6 +136,13 @@ if (test "${phonebook_driver}" = "ebook"); then AC_SUBST(GTHREAD_LIBS) fi +if (test "${phonebook_driver}" = "tracker"); then + PKG_CHECK_MODULES(TRACKER_SPARQL, tracker-sparql-0.9, dummy=yes, + AC_MSG_ERROR(libtracker-sparql is required)) + AC_SUBST(TRACKER_SPARQL_CFLAGS) + AC_SUBST(TRACKER_SPARQL_LIBS) +fi + AC_SUBST([PHONEBOOK_DRIVER], [phonebook-${phonebook_driver}.c]) AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server], -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3 v2] Move freeing contacts data to phonebook_req_finalize 2011-02-02 10:21 [PATCH 1/3 v2] Add libtracker-sparql to obexd dependencies Radoslaw Jablonski @ 2011-02-02 10:21 ` Radoslaw Jablonski 2011-02-02 10:21 ` [PATCH 3/3 v2] Use libtracker-sparql in PBAP Radoslaw Jablonski 1 sibling, 0 replies; 4+ messages in thread From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw) To: linux-bluetooth; +Cc: Radoslaw Jablonski Previously data used for generating vcards was freed only in gen_vcards body. This may result a memory leak, if fetching data from tracker was cancelled in the middle of process and gen_vcards wasn't called. Phonebook_req_finalize is better place for this kind of cleanup. --- plugins/phonebook-tracker.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c index e60cf74..3b61d6b 100644 --- a/plugins/phonebook-tracker.c +++ b/plugins/phonebook-tracker.c @@ -1326,10 +1326,6 @@ static GString *gen_vcards(GSList *contacts, struct contact_data *c_data = l->data; phonebook_add_contact(vcards, c_data->contact, params->filter, params->format); - - g_free(c_data->id); - phonebook_contact_free(c_data->contact); - g_free(c_data); } return vcards; @@ -1789,6 +1785,7 @@ done: void phonebook_req_finalize(void *request) { struct phonebook_data *data = request; + GSList *l; DBG(""); @@ -1800,6 +1797,15 @@ void phonebook_req_finalize(void *request) dbus_pending_call_unref(data->call); + /* freeing list of contacts used for generating vcards */ + for (l = data->contacts; l; l = l->next) { + struct contact_data *c_data = l->data; + + g_free(c_data->id); + phonebook_contact_free(c_data->contact); + g_free(c_data); + } + g_slist_free(data->contacts); g_free(data); } -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3 v2] Use libtracker-sparql in PBAP 2011-02-02 10:21 [PATCH 1/3 v2] Add libtracker-sparql to obexd dependencies Radoslaw Jablonski 2011-02-02 10:21 ` [PATCH 2/3 v2] Move freeing contacts data to phonebook_req_finalize Radoslaw Jablonski @ 2011-02-02 10:21 ` Radoslaw Jablonski 2011-02-02 18:15 ` Vinicius Costa Gomes 1 sibling, 1 reply; 4+ messages in thread From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw) To: linux-bluetooth; +Cc: Radoslaw Jablonski Now direct tracker connection for transporting retrieved parts of data is used, instead of D-Bus. This should result better performance for PBAP requests. Each part of results is now fetched from tracker asynchronously and getting more results can be stopped in any moment - GCancellable stored in phonebook_data is used for that purpose. If processing of data has finished (or it was cancelled) then cleanup of pending_reply is done in last invocation of async_query_cursor_next_cb. --- plugins/phonebook-tracker.c | 271 +++++++++++++++++++++++-------------------- 1 files changed, 147 insertions(+), 124 deletions(-) diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c index 3b61d6b..79bc1c6 100644 --- a/plugins/phonebook-tracker.c +++ b/plugins/phonebook-tracker.c @@ -29,6 +29,7 @@ #include <dbus/dbus.h> #include <openobex/obex.h> #include <openobex/obex_const.h> +#include <libtracker-sparql/tracker-sparql.h> #include "log.h" #include "obex.h" @@ -891,7 +892,7 @@ "} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) " \ "LIMIT 40" -typedef void (*reply_list_foreach_t) (char **reply, int num_fields, +typedef void (*reply_list_foreach_t) (const char **reply, int num_fields, void *user_data); typedef void (*add_field_t) (struct phonebook_contact *contact, @@ -918,7 +919,7 @@ struct phonebook_data { phonebook_cache_ready_cb ready_cb; phonebook_entry_cb entry_cb; int newmissedcalls; - DBusPendingCall *call; + GCancellable *query_canc; }; struct phonebook_index { @@ -926,7 +927,7 @@ struct phonebook_index { int index; }; -static DBusConnection *connection = NULL; +static TrackerSparqlConnection *connection = NULL; static const char *name2query(const char *name) { @@ -999,131 +1000,139 @@ static const char *folder2query(const char *folder) return NULL; } -static char **string_array_from_iter(DBusMessageIter iter, int array_len) +static const char **string_array_from_cursor(TrackerSparqlCursor *cursor, + int array_len) { - DBusMessageIter sub; - char **result; + const char **result; int i; - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) - return NULL; - - result = g_new0(char *, array_len); - - dbus_message_iter_recurse(&iter, &sub); - - i = 0; - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - char *arg; + result = g_new0(const char *, array_len); - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { - g_free(result); - return NULL; - } - - dbus_message_iter_get_basic(&sub, &arg); + for (i = 0; i < array_len; ++i) { + TrackerSparqlValueType type; - result[i] = arg; + type = tracker_sparql_cursor_get_value_type(cursor, i); - i++; - dbus_message_iter_next(&sub); + if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE || + type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND) + /* For null/unbound type filling result part with ""*/ + result[i] = ""; + else + /* Filling with string representation of content*/ + result[i] = tracker_sparql_cursor_get_string(cursor, i, + NULL); } return result; } -static void query_reply(DBusPendingCall *call, void *user_data) + +static void query_free_data(void *user_data) { - DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBG(""); struct pending_reply *pending = user_data; - DBusMessageIter iter, element; - DBusError derr; - int err; - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - error("Replied with an error: %s, %s", derr.name, - derr.message); - dbus_error_free(&derr); - - err = -1; - goto done; - } - - dbus_message_iter_init(reply, &iter); - - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { - error("SparqlQuery reply is not an array"); - err = -1; - goto done; - } - - dbus_message_iter_recurse(&iter, &element); - - err = 0; + if (!pending) + return; - while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) { - char **node; + g_free(pending); +} - if (dbus_message_iter_get_arg_type(&element) != - DBUS_TYPE_ARRAY) { - error("element is not an array"); - goto done; - } +static void update_cancellable(struct phonebook_data *pdata, + GCancellable *canc) +{ + if (pdata->query_canc) + g_object_unref(pdata->query_canc); - node = string_array_from_iter(element, pending->num_fields); - pending->callback(node, pending->num_fields, - pending->user_data); + pdata->query_canc = canc; +} - g_free(node); +static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result, + gpointer user_data) +{ + struct pending_reply *pending = user_data; + TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source); + GCancellable *cancellable; + GError *error = NULL; + gboolean success; + const char **node; + + success = tracker_sparql_cursor_next_finish( + TRACKER_SPARQL_CURSOR (source), + result, + &error); + + if (!success) { + if (error) { + DBG("cursor_next error: %s", error->message); + g_error_free(error); + } else + /* When tracker_sparql_cursor_next_finish ends with + * failure and no error is set, that means end of + * results returned by query */ + pending->callback(NULL, 0, pending->user_data); - dbus_message_iter_next(&element); + goto failed; } -done: - /* This is the last entry */ - pending->callback(NULL, err, pending->user_data); + node = string_array_from_cursor(cursor, pending->num_fields); + pending->callback(node, pending->num_fields, pending->user_data); + g_free(node); - dbus_message_unref(reply); - /* pending data is freed in query_free_data after call is unreffed. */ -} - -static void query_free_data(void *user_data) -{ - struct pending_reply *pending = user_data; - - if (!pending) - return; + /* getting next row from query results */ + cancellable = g_cancellable_new(); + update_cancellable(pending->user_data, cancellable); + tracker_sparql_cursor_next_async(cursor, cancellable, + async_query_cursor_next_cb, + pending); + return; - g_free(pending); +failed: + g_object_unref(cursor); + query_free_data(pending); } -static DBusPendingCall *query_tracker(const char *query, int num_fields, - reply_list_foreach_t callback, void *user_data, int *err) +static void query_tracker(const char *query, int num_fields, + reply_list_foreach_t callback, void *user_data, + int *err) + { struct pending_reply *pending; - DBusPendingCall *call; - DBusMessage *msg; + GCancellable *cancellable; + TrackerSparqlCursor *cursor; + GError *error = NULL; + + DBG(""); if (connection == NULL) - connection = obex_dbus_get_connection(); + connection = tracker_sparql_connection_get_direct( + NULL, &error); - msg = dbus_message_new_method_call(TRACKER_SERVICE, - TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE, - "SparqlQuery"); + if (!connection) { + if (error) { + DBG("direct-connection error: %s", error->message); + g_error_free(error); + } - dbus_message_append_args(msg, DBUS_TYPE_STRING, &query, - DBUS_TYPE_INVALID); + goto failed; + } - if (dbus_connection_send_with_reply(connection, msg, &call, - -1) == FALSE) { - error("Could not send dbus message"); - dbus_message_unref(msg); - if (err) - *err = -EPERM; - return NULL; + cancellable = g_cancellable_new(); + update_cancellable(user_data, cancellable); + cursor = tracker_sparql_connection_query(connection, query, + cancellable, &error); + + if (cursor == NULL) { + if (error) { + DBG("connection_query error: %s", error->message); + g_error_free(error); + } + + g_object_unref(cancellable); + g_object_unref(cursor); + + goto failed; } pending = g_new0(struct pending_reply, 1); @@ -1131,14 +1140,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields, pending->user_data = user_data; pending->num_fields = num_fields; - dbus_pending_call_set_notify(call, query_reply, pending, - query_free_data); - dbus_message_unref(msg); + /* Now asynchronously going through each row of results - callback + * async_query_cursor_next_cb will be called ALWAYS, even if async + * request was canceled */ + tracker_sparql_cursor_next_async(cursor, cancellable, + async_query_cursor_next_cb, + pending); if (err) *err = 0; - return call; + return; + +failed: + if (err) + *err = -EPERM; } static char *iso8601_utc_to_localtime(const char *datetime) @@ -1331,7 +1347,8 @@ static GString *gen_vcards(GSList *contacts, return vcards; } -static void pull_contacts_size(char **reply, int num_fields, void *user_data) +static void pull_contacts_size(const char **reply, int num_fields, + void *user_data) { struct phonebook_data *data = user_data; @@ -1363,7 +1380,8 @@ static void add_affiliation(char **field, const char *value) *field = g_strdup(value); } -static void contact_init(struct phonebook_contact *contact, char **reply) +static void contact_init(struct phonebook_contact *contact, + const char **reply) { contact->fullname = g_strdup(reply[COL_FULL_NAME]); @@ -1395,8 +1413,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation) return TEL_TYPE_OTHER; } -static void add_aff_number(struct phonebook_contact *contact, char *pnumber, - char *aff_type) +static void add_aff_number(struct phonebook_contact *contact, + const char *pnumber, const char *aff_type) { char **num_parts; char *type, *number; @@ -1433,7 +1451,7 @@ failed: } static void contact_add_numbers(struct phonebook_contact *contact, - char **reply) + const char **reply) { char **aff_numbers; int i; @@ -1459,8 +1477,8 @@ static enum phonebook_field_type get_field_type(const char *affilation) return FIELD_TYPE_OTHER; } -static void add_aff_field(struct phonebook_contact *contact, char *aff_email, - add_field_t add_field_cb) +static void add_aff_field(struct phonebook_contact *contact, + const char *aff_email, add_field_t add_field_cb) { char **email_parts; char *type, *email; @@ -1490,7 +1508,7 @@ failed: } static void contact_add_emails(struct phonebook_contact *contact, - char **reply) + const char **reply) { char **aff_emails; int i; @@ -1506,7 +1524,7 @@ static void contact_add_emails(struct phonebook_contact *contact, } static void contact_add_addresses(struct phonebook_contact *contact, - char **reply) + const char **reply) { char **aff_addr; int i; @@ -1522,7 +1540,8 @@ static void contact_add_addresses(struct phonebook_contact *contact, g_strfreev(aff_addr); } -static void contact_add_urls(struct phonebook_contact *contact, char **reply) +static void contact_add_urls(struct phonebook_contact *contact, + const char **reply) { char **aff_url; int i; @@ -1538,7 +1557,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply) } static void contact_add_organization(struct phonebook_contact *contact, - char **reply) + const char **reply) { /* Adding fields connected by nco:hasAffiliation - they may be in * separate replies */ @@ -1548,7 +1567,7 @@ static void contact_add_organization(struct phonebook_contact *contact, add_affiliation(&contact->role, reply[COL_ORG_ROLE]); } -static void pull_contacts(char **reply, int num_fields, void *user_data) +static void pull_contacts(const char **reply, int num_fields, void *user_data) { struct phonebook_data *data = user_data; const struct apparam_field *params = data->params; @@ -1649,7 +1668,7 @@ fail: */ } -static void add_to_cache(char **reply, int num_fields, void *user_data) +static void add_to_cache(const char **reply, int num_fields, void *user_data) { struct phonebook_data *data = user_data; char *formatted; @@ -1699,6 +1718,9 @@ done: int phonebook_init(void) { + g_thread_init(NULL); + g_type_init(); + return 0; } @@ -1792,12 +1814,13 @@ void phonebook_req_finalize(void *request) if (!data) return; - if (!dbus_pending_call_get_completed(data->call)) - dbus_pending_call_cancel(data->call); - - dbus_pending_call_unref(data->call); + /* canceling asynchronous operation on tracker if any is active */ + if (data->query_canc) { + g_cancellable_cancel(data->query_canc); + g_object_unref(data->query_canc); + } - /* freeing list of contacts used for generating vcards */ + /* freeing contacts */ for (l = data->contacts; l; l = l->next) { struct contact_data *c_data = l->data; @@ -1828,7 +1851,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data) g_string_free(data, TRUE); } -static void pull_newmissedcalls(char **reply, int num_fields, void *user_data) +static void pull_newmissedcalls(const char **reply, int num_fields, + void *user_data) { struct phonebook_data *data = user_data; reply_list_foreach_t pull_cb; @@ -1870,8 +1894,7 @@ done: pull_cb = pull_contacts; } - dbus_pending_call_unref(data->call); - data->call = query_tracker(query, col_amount, pull_cb, data, &err); + query_tracker(query, col_amount, pull_cb, data, &err); if (err < 0) data->cb(NULL, 0, err, 0, data->user_data); } @@ -1910,7 +1933,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params, data->params = params; data->user_data = user_data; data->cb = cb; - data->call = query_tracker(query, col_amount, pull_cb, data, err); + query_tracker(query, col_amount, pull_cb, data, err); return data; } @@ -1938,8 +1961,8 @@ void *phonebook_get_entry(const char *folder, const char *id, query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI, id, id, id); - data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts, - data, err); + query_tracker(query, PULL_QUERY_COL_AMOUNT, + pull_contacts, data, err); g_free(query); @@ -1965,7 +1988,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb, data->entry_cb = entry_cb; data->ready_cb = ready_cb; data->user_data = user_data; - data->call = query_tracker(query, 7, add_to_cache, data, err); + query_tracker(query, 7, add_to_cache, data, err); return data; } -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 3/3 v2] Use libtracker-sparql in PBAP 2011-02-02 10:21 ` [PATCH 3/3 v2] Use libtracker-sparql in PBAP Radoslaw Jablonski @ 2011-02-02 18:15 ` Vinicius Costa Gomes 0 siblings, 0 replies; 4+ messages in thread From: Vinicius Costa Gomes @ 2011-02-02 18:15 UTC (permalink / raw) To: Radoslaw Jablonski; +Cc: linux-bluetooth Hi Radoslaw, On 12:21 Wed 02 Feb, Radoslaw Jablonski wrote: > Now direct tracker connection for transporting retrieved > parts of data is used, instead of D-Bus. This should result better > performance for PBAP requests. > Each part of results is now fetched from tracker asynchronously > and getting more results can be stopped in any moment - > GCancellable stored in phonebook_data is used for that purpose. > If processing of data has finished (or it was cancelled) then cleanup > of pending_reply is done in last invocation of > async_query_cursor_next_cb. > --- > plugins/phonebook-tracker.c | 271 +++++++++++++++++++++++-------------------- > 1 files changed, 147 insertions(+), 124 deletions(-) > > diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c > index 3b61d6b..79bc1c6 100644 > --- a/plugins/phonebook-tracker.c > +++ b/plugins/phonebook-tracker.c > @@ -29,6 +29,7 @@ > #include <dbus/dbus.h> > #include <openobex/obex.h> > #include <openobex/obex_const.h> > +#include <libtracker-sparql/tracker-sparql.h> > > #include "log.h" > #include "obex.h" > @@ -891,7 +892,7 @@ > "} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) " \ > "LIMIT 40" > > -typedef void (*reply_list_foreach_t) (char **reply, int num_fields, > +typedef void (*reply_list_foreach_t) (const char **reply, int num_fields, > void *user_data); > > typedef void (*add_field_t) (struct phonebook_contact *contact, > @@ -918,7 +919,7 @@ struct phonebook_data { > phonebook_cache_ready_cb ready_cb; > phonebook_entry_cb entry_cb; > int newmissedcalls; > - DBusPendingCall *call; > + GCancellable *query_canc; > }; > > struct phonebook_index { > @@ -926,7 +927,7 @@ struct phonebook_index { > int index; > }; > > -static DBusConnection *connection = NULL; > +static TrackerSparqlConnection *connection = NULL; > > static const char *name2query(const char *name) > { > @@ -999,131 +1000,139 @@ static const char *folder2query(const char *folder) > return NULL; > } > > -static char **string_array_from_iter(DBusMessageIter iter, int array_len) > +static const char **string_array_from_cursor(TrackerSparqlCursor *cursor, > + int array_len) > { > - DBusMessageIter sub; > - char **result; > + const char **result; > int i; > > - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) > - return NULL; > - > - result = g_new0(char *, array_len); > - > - dbus_message_iter_recurse(&iter, &sub); > - > - i = 0; > - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { > - char *arg; > + result = g_new0(const char *, array_len); > > - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { > - g_free(result); > - return NULL; > - } > - > - dbus_message_iter_get_basic(&sub, &arg); > + for (i = 0; i < array_len; ++i) { > + TrackerSparqlValueType type; > > - result[i] = arg; > + type = tracker_sparql_cursor_get_value_type(cursor, i); > > - i++; > - dbus_message_iter_next(&sub); > + if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE || > + type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND) > + /* For null/unbound type filling result part with ""*/ > + result[i] = ""; > + else > + /* Filling with string representation of content*/ > + result[i] = tracker_sparql_cursor_get_string(cursor, i, > + NULL); > } > > return result; > } > > -static void query_reply(DBusPendingCall *call, void *user_data) > + Extra empty line here. > +static void query_free_data(void *user_data) > { > - DBusMessage *reply = dbus_pending_call_steal_reply(call); > + DBG(""); This statement should go after the declarations. > struct pending_reply *pending = user_data; > - DBusMessageIter iter, element; > - DBusError derr; > - int err; > - > - dbus_error_init(&derr); > - if (dbus_set_error_from_message(&derr, reply)) { > - error("Replied with an error: %s, %s", derr.name, > - derr.message); > - dbus_error_free(&derr); > - > - err = -1; > - goto done; > - } > - > - dbus_message_iter_init(reply, &iter); > - > - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { > - error("SparqlQuery reply is not an array"); > > - err = -1; > - goto done; > - } > - > - dbus_message_iter_recurse(&iter, &element); > - > - err = 0; > + if (!pending) > + return; g_free() already deals with the case where the pointer is NULL, so I don't see much point in having this function. > > - while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) { > - char **node; > + g_free(pending); > +} > > - if (dbus_message_iter_get_arg_type(&element) != > - DBUS_TYPE_ARRAY) { > - error("element is not an array"); > - goto done; > - } > +static void update_cancellable(struct phonebook_data *pdata, > + GCancellable *canc) > +{ > + if (pdata->query_canc) > + g_object_unref(pdata->query_canc); > > - node = string_array_from_iter(element, pending->num_fields); > - pending->callback(node, pending->num_fields, > - pending->user_data); > + pdata->query_canc = canc; > +} > > - g_free(node); > +static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result, > + gpointer user_data) > +{ > + struct pending_reply *pending = user_data; > + TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source); Extra space before "(". > + GCancellable *cancellable; > + GError *error = NULL; > + gboolean success; > + const char **node; > + > + success = tracker_sparql_cursor_next_finish( > + TRACKER_SPARQL_CURSOR (source), Same here. > + result, > + &error); Perhaps putting these two in the same line? > + > + if (!success) { > + if (error) { > + DBG("cursor_next error: %s", error->message); > + g_error_free(error); > + } else > + /* When tracker_sparql_cursor_next_finish ends with > + * failure and no error is set, that means end of > + * results returned by query */ > + pending->callback(NULL, 0, pending->user_data); > > - dbus_message_iter_next(&element); > + goto failed; > } > > -done: > - /* This is the last entry */ > - pending->callback(NULL, err, pending->user_data); > + node = string_array_from_cursor(cursor, pending->num_fields); > + pending->callback(node, pending->num_fields, pending->user_data); > + g_free(node); > > - dbus_message_unref(reply); > > - /* pending data is freed in query_free_data after call is unreffed. */ > -} > - > -static void query_free_data(void *user_data) > -{ > - struct pending_reply *pending = user_data; > - > - if (!pending) > - return; > + /* getting next row from query results */ > + cancellable = g_cancellable_new(); > + update_cancellable(pending->user_data, cancellable); > + tracker_sparql_cursor_next_async(cursor, cancellable, > + async_query_cursor_next_cb, > + pending); > + return; > > - g_free(pending); > +failed: > + g_object_unref(cursor); > + query_free_data(pending); > } > > -static DBusPendingCall *query_tracker(const char *query, int num_fields, > - reply_list_foreach_t callback, void *user_data, int *err) > +static void query_tracker(const char *query, int num_fields, > + reply_list_foreach_t callback, void *user_data, > + int *err) > + Extra empty line here. > { > struct pending_reply *pending; > - DBusPendingCall *call; > - DBusMessage *msg; > + GCancellable *cancellable; > + TrackerSparqlCursor *cursor; > + GError *error = NULL; > + > + DBG(""); > > if (connection == NULL) > - connection = obex_dbus_get_connection(); > + connection = tracker_sparql_connection_get_direct( > + NULL, &error); > > - msg = dbus_message_new_method_call(TRACKER_SERVICE, > - TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE, > - "SparqlQuery"); > + if (!connection) { > + if (error) { > + DBG("direct-connection error: %s", error->message); > + g_error_free(error); > + } > > - dbus_message_append_args(msg, DBUS_TYPE_STRING, &query, > - DBUS_TYPE_INVALID); > + goto failed; > + } > > - if (dbus_connection_send_with_reply(connection, msg, &call, > - -1) == FALSE) { > - error("Could not send dbus message"); > - dbus_message_unref(msg); > - if (err) > - *err = -EPERM; > - return NULL; > + cancellable = g_cancellable_new(); > + update_cancellable(user_data, cancellable); > + cursor = tracker_sparql_connection_query(connection, query, > + cancellable, &error); > + > + if (cursor == NULL) { > + if (error) { > + DBG("connection_query error: %s", error->message); > + g_error_free(error); > + } > + > + g_object_unref(cancellable); > + g_object_unref(cursor); This looks strange, calling unref on a NULL pointer. > + > + goto failed; > } > > pending = g_new0(struct pending_reply, 1); > @@ -1131,14 +1140,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields, > pending->user_data = user_data; > pending->num_fields = num_fields; > > - dbus_pending_call_set_notify(call, query_reply, pending, > - query_free_data); > - dbus_message_unref(msg); > + /* Now asynchronously going through each row of results - callback > + * async_query_cursor_next_cb will be called ALWAYS, even if async > + * request was canceled */ > + tracker_sparql_cursor_next_async(cursor, cancellable, > + async_query_cursor_next_cb, > + pending); > > if (err) > *err = 0; > > - return call; > + return; > + > +failed: > + if (err) > + *err = -EPERM; > } > > static char *iso8601_utc_to_localtime(const char *datetime) > @@ -1331,7 +1347,8 @@ static GString *gen_vcards(GSList *contacts, > return vcards; > } > > -static void pull_contacts_size(char **reply, int num_fields, void *user_data) > +static void pull_contacts_size(const char **reply, int num_fields, > + void *user_data) > { > struct phonebook_data *data = user_data; > > @@ -1363,7 +1380,8 @@ static void add_affiliation(char **field, const char *value) > *field = g_strdup(value); > } > > -static void contact_init(struct phonebook_contact *contact, char **reply) > +static void contact_init(struct phonebook_contact *contact, > + const char **reply) > { > > contact->fullname = g_strdup(reply[COL_FULL_NAME]); > @@ -1395,8 +1413,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation) > return TEL_TYPE_OTHER; > } > > -static void add_aff_number(struct phonebook_contact *contact, char *pnumber, > - char *aff_type) > +static void add_aff_number(struct phonebook_contact *contact, > + const char *pnumber, const char *aff_type) > { > char **num_parts; > char *type, *number; > @@ -1433,7 +1451,7 @@ failed: > } > > static void contact_add_numbers(struct phonebook_contact *contact, > - char **reply) > + const char **reply) > { > char **aff_numbers; > int i; > @@ -1459,8 +1477,8 @@ static enum phonebook_field_type get_field_type(const char *affilation) > return FIELD_TYPE_OTHER; > } > > -static void add_aff_field(struct phonebook_contact *contact, char *aff_email, > - add_field_t add_field_cb) > +static void add_aff_field(struct phonebook_contact *contact, > + const char *aff_email, add_field_t add_field_cb) > { > char **email_parts; > char *type, *email; > @@ -1490,7 +1508,7 @@ failed: > } > > static void contact_add_emails(struct phonebook_contact *contact, > - char **reply) > + const char **reply) > { > char **aff_emails; > int i; > @@ -1506,7 +1524,7 @@ static void contact_add_emails(struct phonebook_contact *contact, > } > > static void contact_add_addresses(struct phonebook_contact *contact, > - char **reply) > + const char **reply) > { > char **aff_addr; > int i; > @@ -1522,7 +1540,8 @@ static void contact_add_addresses(struct phonebook_contact *contact, > g_strfreev(aff_addr); > } > > -static void contact_add_urls(struct phonebook_contact *contact, char **reply) > +static void contact_add_urls(struct phonebook_contact *contact, > + const char **reply) > { > char **aff_url; > int i; > @@ -1538,7 +1557,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply) > } > > static void contact_add_organization(struct phonebook_contact *contact, > - char **reply) > + const char **reply) > { > /* Adding fields connected by nco:hasAffiliation - they may be in > * separate replies */ > @@ -1548,7 +1567,7 @@ static void contact_add_organization(struct phonebook_contact *contact, > add_affiliation(&contact->role, reply[COL_ORG_ROLE]); > } > > -static void pull_contacts(char **reply, int num_fields, void *user_data) > +static void pull_contacts(const char **reply, int num_fields, void *user_data) > { > struct phonebook_data *data = user_data; > const struct apparam_field *params = data->params; > @@ -1649,7 +1668,7 @@ fail: > */ > } > > -static void add_to_cache(char **reply, int num_fields, void *user_data) > +static void add_to_cache(const char **reply, int num_fields, void *user_data) > { > struct phonebook_data *data = user_data; > char *formatted; > @@ -1699,6 +1718,9 @@ done: > > int phonebook_init(void) > { > + g_thread_init(NULL); > + g_type_init(); > + > return 0; > } > > @@ -1792,12 +1814,13 @@ void phonebook_req_finalize(void *request) > if (!data) > return; > > - if (!dbus_pending_call_get_completed(data->call)) > - dbus_pending_call_cancel(data->call); > - > - dbus_pending_call_unref(data->call); > + /* canceling asynchronous operation on tracker if any is active */ > + if (data->query_canc) { > + g_cancellable_cancel(data->query_canc); > + g_object_unref(data->query_canc); > + } > > - /* freeing list of contacts used for generating vcards */ > + /* freeing contacts */ > for (l = data->contacts; l; l = l->next) { > struct contact_data *c_data = l->data; > > @@ -1828,7 +1851,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data) > g_string_free(data, TRUE); > } > > -static void pull_newmissedcalls(char **reply, int num_fields, void *user_data) > +static void pull_newmissedcalls(const char **reply, int num_fields, > + void *user_data) > { > struct phonebook_data *data = user_data; > reply_list_foreach_t pull_cb; > @@ -1870,8 +1894,7 @@ done: > pull_cb = pull_contacts; > } > > - dbus_pending_call_unref(data->call); > - data->call = query_tracker(query, col_amount, pull_cb, data, &err); > + query_tracker(query, col_amount, pull_cb, data, &err); > if (err < 0) > data->cb(NULL, 0, err, 0, data->user_data); > } > @@ -1910,7 +1933,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params, > data->params = params; > data->user_data = user_data; > data->cb = cb; > - data->call = query_tracker(query, col_amount, pull_cb, data, err); > + query_tracker(query, col_amount, pull_cb, data, err); > > return data; > } > @@ -1938,8 +1961,8 @@ void *phonebook_get_entry(const char *folder, const char *id, > query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI, > id, id, id); > > - data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts, > - data, err); > + query_tracker(query, PULL_QUERY_COL_AMOUNT, > + pull_contacts, data, err); > > g_free(query); > > @@ -1965,7 +1988,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb, > data->entry_cb = entry_cb; > data->ready_cb = ready_cb; > data->user_data = user_data; > - data->call = query_tracker(query, 7, add_to_cache, data, err); > + query_tracker(query, 7, add_to_cache, data, err); > > return data; > } > -- > 1.7.0.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Cheers, -- Vinicius ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-02-02 18:15 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-02-02 10:21 [PATCH 1/3 v2] Add libtracker-sparql to obexd dependencies Radoslaw Jablonski 2011-02-02 10:21 ` [PATCH 2/3 v2] Move freeing contacts data to phonebook_req_finalize Radoslaw Jablonski 2011-02-02 10:21 ` [PATCH 3/3 v2] Use libtracker-sparql in PBAP Radoslaw Jablonski 2011-02-02 18:15 ` Vinicius Costa Gomes
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.