};
struct _EBookClientCursorPrivate {
- /* Weak reference to the EBookClient and
+ /* Strong reference to the EBookClient and
* to the GMainContext in which notifications
* should be delivered to the EBookClientCursor user */
- GWeakRef client;
+ EBookClient *client;
GMainContext *main_context;
GMutex main_context_lock;
EBookClientCursorPrivate *priv = cursor->priv;
gint i;
+ book_client_cursor_set_direct_cursor (cursor, NULL);
book_client_cursor_set_client (cursor, NULL);
book_client_cursor_set_proxy (cursor, NULL);
- book_client_cursor_set_direct_cursor (cursor, NULL);
book_client_cursor_set_connection (cursor, NULL);
book_client_cursor_set_context (cursor, NULL);
EBookClient *client)
{
EBookClientCursorPrivate *priv = cursor->priv;
- EBookClient *current_client;
g_return_if_fail (client == NULL || E_IS_BOOK_CLIENT (client));
- current_client = e_book_client_cursor_ref_client (cursor);
-
/* Clients can't really change, but we set up this
* mutator style code just to manage the signal connections
* we watch on the client, we need to disconnect them properly.
*/
- if (current_client != client) {
+ if (priv->client != client) {
- if (current_client) {
+ if (priv->client) {
/* Disconnect signals */
- g_signal_handler_disconnect (current_client, priv->revision_changed_id);
- g_signal_handler_disconnect (current_client, priv->locale_changed_id);
+ g_signal_handler_disconnect (priv->client, priv->revision_changed_id);
+ g_signal_handler_disconnect (priv->client, priv->locale_changed_id);
priv->revision_changed_id = 0;
priv->locale_changed_id = 0;
+ g_object_unref (priv->client);
}
/* Set the new client */
- g_weak_ref_set (&priv->client, client);
+ priv->client = client;
- if (client) {
+ if (priv->client) {
gchar *revision = NULL;
/* Connect signals */
0);
/* Load initial locale & revision */
- book_client_cursor_set_locale (cursor, e_book_client_get_locale (client));
+ book_client_cursor_set_locale (cursor, e_book_client_get_locale (priv->client));
/* This loads a cached D-Bus property, no D-Bus activity */
- e_client_get_backend_property_sync (E_CLIENT (client),
+ e_client_get_backend_property_sync (E_CLIENT (priv->client),
CLIENT_BACKEND_PROPERTY_REVISION,
&revision, NULL, NULL);
book_client_cursor_set_revision (cursor, revision);
g_free (revision);
+
+ g_object_ref (priv->client);
}
}
-
- /* e_book_client_cursor_ref_client() gave us a ref */
- g_clear_object (¤t_client);
}
static void
return is_current;
}
+/* Secretly shared API */
+void book_client_delete_direct_cursor (EBookClient *client,
+ EDataBookCursor *cursor);
+
static void
book_client_cursor_set_direct_cursor (EBookClientCursor *cursor,
EDataBookCursor *direct_cursor)
priv->dra_total_changed_id = 0;
priv->dra_position_changed_id = 0;
+ /* Tell EBookClient to delete the cursor
+ *
+ * This should only happen in ->dispose()
+ * before releasing our strong reference to the EBookClient
+ */
+ g_warn_if_fail (priv->client != NULL);
+ book_client_delete_direct_cursor (priv->client,
+ priv->direct_cursor);
+
g_object_unref (priv->direct_cursor);
}
{
g_return_val_if_fail (E_IS_BOOK_CLIENT_CURSOR (cursor), NULL);
- return g_weak_ref_get (&cursor->priv->client);
+ return g_object_ref (cursor->priv->client);
}
/**
}
g_clear_object (&data_book);
+
}
return backend;
return array;
}
+/* This is ugly and should change yes, currently EBookClientCursor
+ * needs to keep a strong reference to the EBookClient to keep it alive
+ * long enough to ask the EBookClient to delete a direct cursor on
+ * the EBookClientCursor's behalf, otherwise direct cursors are leaked.
+ */
+void book_client_delete_direct_cursor (EBookClient *client,
+ EDataBookCursor *cursor);
+
+void
+book_client_delete_direct_cursor (EBookClient *client,
+ EDataBookCursor *cursor)
+{
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
+ g_return_if_fail (E_IS_DATA_BOOK_CURSOR (cursor));
+
+ if (!client->priv->direct_backend) {
+ g_warning ("Tried to delete a cursor in DRA mode but the direct backend is missing");
+ return;
+ }
+
+ e_book_backend_delete_cursor (client->priv->direct_backend,
+ cursor, NULL);
+}
+
+
static void
book_client_get_cursor_in_dbus_thread (GSimpleAsyncResult *simple,
GObject *source_object,