[evolution-patches] e-d-s patch for various addressbook issues.
- From: Chris Toshok <toshok hungry com>
- To: evolution-patches ximian com
- Subject: [evolution-patches] e-d-s patch for various addressbook issues.
- Date: Thu, 15 Apr 2004 10:19:35 -0700
This plugs a few leaks in libebook, and adds code to the
e_book_view_listener to start and stop handling of requests.
The big change, though, is the change in poa policy for EDataBookView's
from PER_REQUEST to PER_OBJECT. This means that backends that want to
search synchronously need to start their own thread. Spawning another
thread, though, is *much* simpler than all the race prevention crap we
had to deal with before. Check out the file backend after this change.
start_book_view and stop_book_view are much, much simpler. The ldap
backend is even easier.
Chris
? backends/groupwise/Makefile
? backends/groupwise/Makefile.in
? backends/groupwise/create-account
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/ChangeLog,v
retrieving revision 1.127
diff -u -r1.127 ChangeLog
--- ChangeLog 15 Apr 2004 08:38:59 -0000 1.127
+++ ChangeLog 15 Apr 2004 16:56:13 -0000
@@ -1,3 +1,70 @@
+2004-04-15 Chris Toshok <toshok ximian com>
+
+ * backends/ldap/e-book-backend-ldap.c
+ (e_book_backend_ldap_start_book_view): remove the race prevention
+ stuff from here, since we set up everything before returning and
+ we know that stop_book_view won't be called before we return.
+ (e_book_backend_ldap_stop_book_view): same.
+
+ * backends/file/e-book-backend-file.c (FileBackendSearchClosure):
+ add slots for a GCond and GThread, as well as for our backend
+ here.
+ (closure_destroy): destroy the cvar.
+ (init_closure): init the cvar, thread, and backend slots.
+ (book_view_thread): new function - this contains the majority of
+ the code in the old ::start_book_view, except it lacks any of the
+ race prevention code, which it no longer needs. We use the cvar
+ to keep the ::start_book_view thread waiting until the view is
+ actually set up and is about to enter the loop, so we know that
+ the search closure has been initialized.
+ (e_book_backend_file_start_book_view): start up the
+ book_view_thread with the closure's mutex locked so it'll pause
+ until we wait on the condition variable. by the time we return
+ from this method we know the book view thread has started and is
+ at the point where the loop starts.
+ (e_book_backend_file_stop_book_view): set the stopped closure
+ field to TRUE and join on the thread. remove all the race
+ prevention code from here too. yay.
+
+ * libedata-book/e-data-book-view.c (e_data_book_view_new): switch
+ from PER_REQUEST to PER_OBJECT. This means that all requests are
+ serialized per object, but come in on a thread specific to this
+ object.
+ (e_data_book_view_dispose): destroy the id's hash table.
+
+ * libebook/e-book-view.c (e_book_view_start): start our
+ EBookViewListener.
+ (e_book_view_stop): stop the listener.
+
+ * libebook/e-book-view-listener.h: add prototypes for
+ e_book_view_listener_start and _stop.
+
+ * libebook/e-book-view-listener.c
+ (impl_BookViewListener_notify_contacts_added): add the thread id
+ to the spew.
+ (impl_BookViewListener_notify_contacts_removed): same.
+ (impl_BookViewListener_notify_contacts_changed): same.
+ (impl_BookViewListener_notify_sequence_complete): same.
+ (impl_BookViewListener_notify_progress): same.
+ (e_book_view_listener_init): we start off in a stopped state.
+ (e_book_view_listener_start): new function - set stopped to FALSE.
+ The next message queued will create the idle handler.
+ (e_book_view_listener_stop): remove the idle handler and set
+ stopped to TRUE - this will cause all _queue_message calls to drop
+ the messages.
+
+ * libebook/e-contact.c (struct _EContactPrivate): add "int
+ padding", just so that g_new (EContactPrivate, 1) doesn't return
+ NULL.
+ (e_contact_dispose): similar change to e-vcard's dispose method.
+ don't return early if ->priv == NULL, as we need to chain up to
+ the parent's dispoes method. this and/or the struct
+ _EContactPrivate change plug a memory leak as well that was
+ causing the EVCardPrivate to go unfreed.
+
+ * libebook/e-vcard.c (e_vcard_dispose): don't return if evc->priv
+ is NULL - we still need to chain up the parent's dispose method.
+
2004-04-15 Sivaiah Nallagatla <snallagatla novell com>
* backends/groupwise/e-book-backend-groupwise.c
Index: backends/file/e-book-backend-file.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/backends/file/e-book-backend-file.c,v
retrieving revision 1.15
diff -u -r1.15 e-book-backend-file.c
--- backends/file/e-book-backend-file.c 14 Apr 2004 18:28:29 -0000 1.15
+++ backends/file/e-book-backend-file.c 15 Apr 2004 16:56:14 -0000
@@ -32,7 +32,7 @@
#include <libedata-book/e-data-book-view.h>
#include "e-book-backend-file.h"
-#define d(x)
+#define d(x) x
#define CHANGES_DB_SUFFIX ".changes.db"
@@ -364,7 +364,10 @@
}
typedef struct {
+ EBookBackendFile *bf;
GMutex *mutex;
+ GCond *cond;
+ GThread *thread;
gboolean stopped;
} FileBackendSearchClosure;
@@ -373,15 +376,19 @@
{
d(printf ("destroying search closure\n"));
g_mutex_free (closure->mutex);
+ g_cond_free (closure->cond);
g_free (closure);
}
static FileBackendSearchClosure*
-init_closure (EDataBookView *book_view)
+init_closure (EDataBookView *book_view, EBookBackendFile *bf)
{
FileBackendSearchClosure *closure = g_new (FileBackendSearchClosure, 1);
- closure->mutex = g_mutex_new();
+ closure->bf = bf;
+ closure->mutex = g_mutex_new ();
+ closure->cond = g_cond_new ();
+ closure->thread = NULL;
closure->stopped = FALSE;
g_object_set_data_full (G_OBJECT (book_view), "EBookBackendFile.BookView::closure",
@@ -396,12 +403,12 @@
return g_object_get_data (G_OBJECT (book_view), "EBookBackendFile.BookView::closure");
}
-static void
-e_book_backend_file_start_book_view (EBookBackend *backend,
- EDataBookView *book_view)
+static gpointer
+book_view_thread (gpointer data)
{
- FileBackendSearchClosure *closure;
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+ EDataBookView *book_view = data;
+ FileBackendSearchClosure *closure = get_closure (book_view);
+ EBookBackendFile *bf = closure->bf;
const char *query;
DB *db;
DBT id_dbt, vcard_dbt;
@@ -410,30 +417,9 @@
d(printf ("starting initial population of book view\n"));
- g_mutex_lock (e_data_book_view_get_mutex (book_view));
-
- closure = get_closure (book_view);
- if (closure) {
- /* the only way op can be set here is if we raced with
- stop_book_view and lost. make sure by checking
- op->stopped. */
- if (!closure->stopped) {
- g_warning ("lost race with stop_book_view, but op->stopped != TRUE");
- }
- g_object_set_data (G_OBJECT (book_view), "EBookBackendFile.BookView::closure", NULL);
- g_mutex_unlock (e_data_book_view_get_mutex (book_view));
- return;
- }
- else {
- closure = init_closure (book_view);
- closure->stopped = FALSE;
- }
-
/* ref the book view because it'll be removed and unrefed
when/if it's stopped */
bonobo_object_ref (book_view);
-
- g_mutex_unlock (e_data_book_view_get_mutex (book_view));
db = bf->priv->file_db;
query = e_data_book_view_get_card_query (book_view);
@@ -443,6 +429,11 @@
else
e_data_book_view_notify_status_message (book_view, _("Searching..."));
+ d(printf ("signalling parent thread\n"));
+ g_mutex_lock (closure->mutex);
+ g_cond_signal (closure->cond);
+ g_mutex_unlock (closure->mutex);
+
if (e_book_backend_summary_is_summary_query (bf->priv->summary, query)) {
/* do a summary query */
GPtrArray *ids = e_book_backend_summary_search (bf->priv->summary, e_data_book_view_get_card_query (book_view));
@@ -516,32 +507,45 @@
/* unref the */
bonobo_object_unref (book_view);
- d(printf ("finished initial population of book view\n"));
+ d(printf ("finished population of book view\n"));
+
+ return NULL;
}
static void
-e_book_backend_file_stop_book_view (EBookBackend *backend,
- EDataBookView *book_view)
+e_book_backend_file_start_book_view (EBookBackend *backend,
+ EDataBookView *book_view)
{
- FileBackendSearchClosure *closure;
+ FileBackendSearchClosure *closure = init_closure (book_view, E_BOOK_BACKEND_FILE (backend));
- g_mutex_lock (e_data_book_view_get_mutex (book_view));
+ g_mutex_lock (closure->mutex);
- closure = get_closure (book_view);
+ d(printf ("starting book view thread\n"));
+ closure->thread = g_thread_create (book_view_thread, book_view, TRUE, NULL);
- if (closure) {
- d(printf ("stopping running query!\n"));
- g_mutex_lock (closure->mutex);
- closure->stopped = TRUE;
- g_mutex_unlock (closure->mutex);
- }
- else {
- d(printf ("either the query is already finished or hasn't started yet (we won the race)\n"));
- closure = init_closure (book_view);
- closure->stopped = TRUE;
- }
+ g_cond_wait (closure->cond, closure->mutex);
+
+ /* at this point we know the book view thread is actually running */
+ g_mutex_unlock (closure->mutex);
+ d(printf ("returning from start_book_view\n"));
+}
+
+static void
+e_book_backend_file_stop_book_view (EBookBackend *backend,
+ EDataBookView *book_view)
+{
+ FileBackendSearchClosure *closure = get_closure (book_view);
+ gboolean need_join = FALSE;
+
+ d(printf ("stopping query\n"));
+ g_mutex_lock (closure->mutex);
+ if (!closure->stopped)
+ need_join = TRUE;
+ closure->stopped = TRUE;
+ g_mutex_unlock (closure->mutex);
- g_mutex_unlock (e_data_book_view_get_mutex (book_view));
+ if (need_join)
+ g_thread_join (closure->thread);
}
typedef struct {
Index: backends/ldap/e-book-backend-ldap.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/backends/ldap/e-book-backend-ldap.c,v
retrieving revision 1.15
diff -u -r1.15 e-book-backend-ldap.c
--- backends/ldap/e-book-backend-ldap.c 14 Apr 2004 18:32:02 -0000 1.15
+++ backends/ldap/e-book-backend-ldap.c 15 Apr 2004 16:56:15 -0000
@@ -2986,30 +2986,10 @@
EDataBookView *view)
{
EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
- LDAPSearchOp *op;
d(printf ("start_book_view (%p)\n", view));
- g_mutex_lock (e_data_book_view_get_mutex (view));
-
- op = g_object_get_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op");
-
- if (op) {
- /* the only way op can be set here is if we raced with
- stop_book_view and lost. make sure by checking
- op->aborted. */
- if (!op->aborted) {
- g_warning ("lost race with stop_book_view, but op->aborted != TRUE");
- }
-
- g_free (op);
- g_object_set_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op", NULL);
- }
- else {
- e_book_backend_ldap_search (bl, NULL /* XXX ugh */, view);
- }
-
- g_mutex_unlock (e_data_book_view_get_mutex (view));
+ e_book_backend_ldap_search (bl, NULL /* XXX ugh */, view);
}
static void
@@ -3020,19 +3000,9 @@
d(printf ("stop_book_view (%p)\n", view));
- g_mutex_lock (e_data_book_view_get_mutex (view));
-
op = g_object_get_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op");
- if (op) {
+ if (op)
ldap_op_finished ((LDAPOp*)op);
- }
- else {
- op = g_new0 (LDAPSearchOp, 1);
- op->aborted = TRUE;
- g_object_set_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op", op);
- }
-
- g_mutex_unlock (e_data_book_view_get_mutex (view));
}
static void
Index: libebook/e-book-listener.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-book-listener.c,v
retrieving revision 1.8
diff -u -r1.8 e-book-listener.c
--- libebook/e-book-listener.c 24 Feb 2004 23:44:39 -0000 1.8
+++ libebook/e-book-listener.c 15 Apr 2004 16:56:16 -0000
@@ -173,7 +173,7 @@
g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
- bonobo_object_release_unref (book_view, ev);
+ bonobo_object_release_unref (response.book_view, ev);
}
static void
Index: libebook/e-book-view-listener.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-book-view-listener.c,v
retrieving revision 1.6
diff -u -r1.6 e-book-view-listener.c
--- libebook/e-book-view-listener.c 20 Mar 2004 02:22:16 -0000 1.6
+++ libebook/e-book-view-listener.c 15 Apr 2004 16:56:16 -0000
@@ -17,7 +17,7 @@
#include "e-contact.h"
#include "e-book-marshal.h"
-#define d(x)
+#define d(x) x
static EBookViewStatus e_book_view_listener_convert_status (GNOME_Evolution_Addressbook_CallStatus status);
@@ -197,7 +197,7 @@
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- d(printf ("impl_BookViewListener_notify_contacts_added\n"));
+ d(printf ("%p: impl_BookViewListener_notify_contacts_added (%p)\n", pthread_self(), listener));
e_book_view_listener_queue_sequence_event (
listener, ContactsAddedEvent, vcards);
@@ -210,7 +210,7 @@
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- d(printf ("impl_BookViewListener_notify_contacts_removed\n"));
+ d(printf ("%p: impl_BookViewListener_notify_contacts_removed (%p)\n", pthread_self(), listener));
e_book_view_listener_queue_idlist_event (listener, ContactsRemovedEvent, ids);
}
@@ -222,7 +222,7 @@
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- d(printf ("impl_BookViewListener_notify_contacts_changed\n"));
+ d(printf ("%p: impl_BookViewListener_notify_contacts_changed (%p)\n", pthread_self(), listener));
e_book_view_listener_queue_sequence_event (
listener, ContactsModifiedEvent, vcards);
@@ -235,7 +235,7 @@
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- d(printf ("impl_BookViewListener_notify_sequence_complete\n"));
+ d(printf ("%p: impl_BookViewListener_notify_sequence_complete (%p)\n", pthread_self(), listener));
e_book_view_listener_queue_status_event (listener, SequenceCompleteEvent,
e_book_view_listener_convert_status (status));
@@ -249,7 +249,7 @@
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- d(printf ("impl_BookViewListener_notify_progress\n"));
+ d(printf ("%p: impl_BookViewListener_notify_progress (%p,`%s')\n", pthread_self(), listener, message));
e_book_view_listener_queue_message_event (listener, StatusMessageEvent, message);
}
@@ -287,7 +287,7 @@
EBookViewListener *listener;
listener = g_object_new (E_TYPE_BOOK_VIEW_LISTENER,
- "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_OBJECT, NULL),
NULL);
listener->priv->queue = g_async_queue_new();
@@ -301,14 +301,28 @@
e_book_view_listener_init (EBookViewListener *listener)
{
listener->priv = g_new0 (EBookViewListenerPrivate, 1);
- listener->priv->stopped = FALSE;
+ listener->priv->stopped = TRUE;
+}
+
+void
+e_book_view_listener_start (EBookViewListener *listener)
+{
+ g_return_if_fail (E_IS_BOOK_VIEW_LISTENER (listener));
+ d(printf ("%p: e_book_view_listener_start (%p)\n", pthread_self(), listener));
+ listener->priv->stopped = FALSE;
}
void
e_book_view_listener_stop (EBookViewListener *listener)
{
g_return_if_fail (E_IS_BOOK_VIEW_LISTENER (listener));
+ d(printf ("%p: e_book_view_listener_stop (%p)\n", pthread_self(), listener));
listener->priv->stopped = TRUE;
+
+ if (listener->priv->idle_id != -1) {
+ g_source_remove (listener->priv->idle_id);
+ listener->priv->idle_id = -1;
+ }
}
static void
Index: libebook/e-book-view-listener.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-book-view-listener.h,v
retrieving revision 1.3
diff -u -r1.3 e-book-view-listener.h
--- libebook/e-book-view-listener.h 23 Dec 2003 22:36:53 -0000 1.3
+++ libebook/e-book-view-listener.h 15 Apr 2004 16:56:16 -0000
@@ -84,6 +84,7 @@
EBookViewListener *e_book_view_listener_new (void);
GType e_book_view_listener_get_type (void);
+void e_book_view_listener_start (EBookViewListener *listener);
void e_book_view_listener_stop (EBookViewListener *listener);
G_END_DECLS
Index: libebook/e-book-view.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-book-view.c,v
retrieving revision 1.4
diff -u -r1.4 e-book-view.c
--- libebook/e-book-view.c 11 Feb 2004 17:34:20 -0000 1.4
+++ libebook/e-book-view.c 15 Apr 2004 16:56:16 -0000
@@ -179,6 +179,8 @@
CORBA_exception_init (&ev);
+ e_book_view_listener_start (book_view->priv->listener);
+
GNOME_Evolution_Addressbook_BookView_start (book_view->priv->corba_book_view, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
@@ -194,6 +196,8 @@
g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
CORBA_exception_init (&ev);
+
+ e_book_view_listener_stop (book_view->priv->listener);
GNOME_Evolution_Addressbook_BookView_stop (book_view->priv->corba_book_view, &ev);
Index: libebook/e-contact.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-contact.c,v
retrieving revision 1.30
diff -u -r1.30 e-contact.c
--- libebook/e-contact.c 14 Apr 2004 18:33:30 -0000 1.30
+++ libebook/e-contact.c 15 Apr 2004 16:56:17 -0000
@@ -33,6 +33,7 @@
#define d(x)
struct _EContactPrivate {
+ int padding;
};
#define E_CONTACT_FIELD_TYPE_STRING 0x00000001 /* used for simple single valued attributes */
@@ -251,13 +252,13 @@
{
EContact *ec = E_CONTACT (object);
- if (!ec->priv)
- return;
+ if (ec->priv) {
- /* XXX free instance specific stuff */
+ /* XXX free instance specific stuff */
- g_free (ec->priv);
- ec->priv = NULL;
+ g_free (ec->priv);
+ ec->priv = NULL;
+ }
if (G_OBJECT_CLASS (parent_class)->dispose)
G_OBJECT_CLASS (parent_class)->dispose (object);
Index: libebook/e-vcard.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-vcard.c,v
retrieving revision 1.12
diff -u -r1.12 e-vcard.c
--- libebook/e-vcard.c 2 Apr 2004 07:23:20 -0000 1.12
+++ libebook/e-vcard.c 15 Apr 2004 16:56:17 -0000
@@ -68,14 +68,14 @@
{
EVCard *evc = E_VCARD (object);
- if (!evc->priv)
- return;
+ if (evc->priv) {
- g_list_foreach (evc->priv->attributes, (GFunc)e_vcard_attribute_free, NULL);
- g_list_free (evc->priv->attributes);
+ g_list_foreach (evc->priv->attributes, (GFunc)e_vcard_attribute_free, NULL);
+ g_list_free (evc->priv->attributes);
- g_free (evc->priv);
- evc->priv = NULL;
+ g_free (evc->priv);
+ evc->priv = NULL;
+ }
if (G_OBJECT_CLASS (parent_class)->dispose)
G_OBJECT_CLASS (parent_class)->dispose (object);
Index: libedata-book/e-data-book-view.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libedata-book/e-data-book-view.c,v
retrieving revision 1.7
diff -u -r1.7 e-data-book-view.c
--- libedata-book/e-data-book-view.c 31 Mar 2004 17:18:34 -0000 1.7
+++ libedata-book/e-data-book-view.c 15 Apr 2004 16:56:18 -0000
@@ -454,7 +454,7 @@
EDataBookView *book_view;
book_view = g_object_new (E_TYPE_DATA_BOOK_VIEW,
- "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_OBJECT, NULL),
NULL);
e_data_book_view_construct (book_view, backend, listener, card_query, card_sexp, max_results);
@@ -482,10 +482,10 @@
g_object_unref (book_view->priv->card_sexp);
g_mutex_free (book_view->priv->pending_mutex);
- book_view->priv->pending_mutex = NULL;
g_mutex_free (book_view->priv->mutex);
- book_view->priv->mutex = NULL;
+
+ g_hash_table_destroy (book_view->priv->ids);
g_free (book_view->priv);
book_view->priv = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]