summaryrefslogtreecommitdiff
path: root/addressbook
diff options
context:
space:
mode:
authorChris Toshok <toshok@ximian.com>2004-03-13 22:40:45 +0000
committerChris Toshok <toshok@src.gnome.org>2004-03-13 22:40:45 +0000
commit8ae2141438451c3107c5e3184655a6bf8e25ebd8 (patch)
tree1931c23e4e0c073cce0682cef5f10a458a7e8814 /addressbook
parent74c1d3e808fd0e3b62352d069bc136a6cd0f0464 (diff)
downloadevolution-data-server-8ae2141438451c3107c5e3184655a6bf8e25ebd8.tar.gz
add prototype for e_data_book_view_get_mutex.
2004-03-12 Chris Toshok <toshok@ximian.com> * libedata-book/e-data-book-view.h: add prototype for e_data_book_view_get_mutex. * libedata-book/e-data-book-view.c (e_data_book_view_get_mutex): new function, return the book view's mutex. (e_data_book_view_dispose): free priv->mutex. (e_data_book_view_init): init priv->mutex. * backends/file/e-book-backend-file.c (closure_destroy): GDestroyNotify to clear up the search closure. (init_closure): initialize the object data we use to store search information (just a "stopped" flag at the moment) (get_closure): return the object data. (e_book_backend_file_start_book_view): add code to deal with the race between start and stop, locking the book_view's mutex around the initial get/set of the closure. also, switch from using g_object_ref to bonobo_object_ref on the book_view, and don't do any freeing of the search closure here. it's handled automatically for us by virtue of the GDestroyNotify. (e_book_backend_file_stop_book_view): flesh this out to fix the race between start/stop.
Diffstat (limited to 'addressbook')
-rw-r--r--addressbook/ChangeLog24
-rw-r--r--addressbook/backends/file/e-book-backend-file.c102
-rw-r--r--addressbook/libedata-book/e-data-book-view.c18
-rw-r--r--addressbook/libedata-book/e-data-book-view.h23
4 files changed, 129 insertions, 38 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index f3e274c09..e26064f1e 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,5 +1,29 @@
2004-03-12 Chris Toshok <toshok@ximian.com>
+ * libedata-book/e-data-book-view.h: add prototype for
+ e_data_book_view_get_mutex.
+
+ * libedata-book/e-data-book-view.c (e_data_book_view_get_mutex):
+ new function, return the book view's mutex.
+ (e_data_book_view_dispose): free priv->mutex.
+ (e_data_book_view_init): init priv->mutex.
+
+ * backends/file/e-book-backend-file.c (closure_destroy):
+ GDestroyNotify to clear up the search closure.
+ (init_closure): initialize the object data we use to store search
+ information (just a "stopped" flag at the moment)
+ (get_closure): return the object data.
+ (e_book_backend_file_start_book_view): add code to deal with the
+ race between start and stop, locking the book_view's mutex around
+ the initial get/set of the closure. also, switch from using
+ g_object_ref to bonobo_object_ref on the book_view, and don't do
+ any freeing of the search closure here. it's handled
+ automatically for us by virtue of the GDestroyNotify.
+ (e_book_backend_file_stop_book_view): flesh this out to fix the
+ race between start/stop.
+
+2004-03-12 Chris Toshok <toshok@ximian.com>
+
* libebook/e-contact.c (e_contact_set_property): in the CATEGORIES
case when we're adding a new attribute to the vcard, make sure to
call e_vcard_add_attribute after creating it. also, use
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index 189fbd129..b3ae524e4 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -32,6 +32,8 @@
#include <libedata-book/e-data-book-view.h>
#include "e-book-backend-file.h"
+#define d(x)
+
#define CHANGES_DB_SUFFIX ".changes.db"
#define E_BOOK_BACKEND_FILE_VERSION_NAME "PAS-DB-VERSION"
@@ -306,7 +308,7 @@ e_book_backend_file_get_contact_list (EBookBackendSync *backend,
const char *search = query;
GList *contact_list = NULL;
- printf ("e_book_backend_file_get_contact_list (%s)\n", search);
+ d(printf ("e_book_backend_file_get_contact_list (%s)\n", search));
search_needed = TRUE;
@@ -357,10 +359,38 @@ typedef struct {
} FileBackendSearchClosure;
static void
+closure_destroy (FileBackendSearchClosure *closure)
+{
+ d(printf ("destroying search closure\n"));
+ g_mutex_free (closure->mutex);
+ g_free (closure);
+}
+
+static FileBackendSearchClosure*
+init_closure (EDataBookView *book_view)
+{
+ FileBackendSearchClosure *closure = g_new (FileBackendSearchClosure, 1);
+
+ closure->mutex = g_mutex_new();
+ closure->stopped = FALSE;
+
+ g_object_set_data_full (G_OBJECT (book_view), "EBookBackendFile.BookView::closure",
+ closure, (GDestroyNotify)closure_destroy);
+
+ return closure;
+}
+
+static FileBackendSearchClosure*
+get_closure (EDataBookView *book_view)
+{
+ 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)
{
- FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1);
+ FileBackendSearchClosure *closure;
EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
const char *query;
DB *db;
@@ -368,19 +398,36 @@ e_book_backend_file_start_book_view (EBookBackend *backend,
int db_error;
gboolean stopped = FALSE;
- printf ("starting initial population of book view\n");
+ 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 */
- g_object_ref (book_view);
+ 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);
- closure->mutex = g_mutex_new();
- closure->stopped = FALSE;
- g_object_set_data (G_OBJECT (book_view), "EBookBackendFile.BookView::closure", closure);
-
if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
e_data_book_view_notify_status_message (book_view, _("Loading..."));
else
@@ -398,11 +445,8 @@ e_book_backend_file_start_book_view (EBookBackend *backend,
stopped = closure->stopped;
g_mutex_unlock (closure->mutex);
- if (stopped) {
- g_mutex_free (closure->mutex);
- g_free (closure);
+ if (stopped)
break;
- }
string_to_dbt (id, &id_dbt);
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
@@ -460,31 +504,35 @@ e_book_backend_file_start_book_view (EBookBackend *backend,
if (!stopped)
e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success);
- g_mutex_free (closure->mutex);
- g_free (closure);
-
- g_object_set_data (G_OBJECT (book_view), "EBookBackendFile.BookView::closure", NULL);
-
/* unref the */
- g_object_unref (book_view);
+ bonobo_object_unref (book_view);
- printf ("finished initial population of book view\n");
+ d(printf ("finished initial population of book view\n"));
}
static void
e_book_backend_file_stop_book_view (EBookBackend *backend,
EDataBookView *book_view)
{
- FileBackendSearchClosure *closure = g_object_get_data (G_OBJECT (book_view), "EBookBackendFile.BookView::closure");
- if (!closure) {
- printf ("book view is already done populating\n");
- return;
+ FileBackendSearchClosure *closure;
+
+ g_mutex_lock (e_data_book_view_get_mutex (book_view));
+
+ closure = get_closure (book_view);
+
+ 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;
}
- printf ("stopping book view!\n");
- g_mutex_lock (closure->mutex);
- closure->stopped = TRUE;
- g_mutex_unlock (closure->mutex);
+ g_mutex_unlock (e_data_book_view_get_mutex (book_view));
}
typedef struct {
diff --git a/addressbook/libedata-book/e-data-book-view.c b/addressbook/libedata-book/e-data-book-view.c
index 584110a96..a7fff0da1 100644
--- a/addressbook/libedata-book/e-data-book-view.c
+++ b/addressbook/libedata-book/e-data-book-view.c
@@ -16,6 +16,8 @@
#include "e-book-backend-sexp.h"
#include "e-data-book-view.h"
+#define d(x)
+
static BonoboObjectClass *e_data_book_view_parent_class;
struct _EDataBookViewPrivate {
@@ -24,6 +26,8 @@ struct _EDataBookViewPrivate {
#define INITIAL_THRESHOLD 20
#define THRESHOLD_MAX 3000
+ GMutex *mutex;
+
GMutex *pending_mutex;
CORBA_sequence_GNOME_Evolution_Addressbook_VCard adds;
@@ -373,6 +377,7 @@ impl_GNOME_Evolution_Addressbook_BookView_dispose (PortableServer_Servant servan
{
EDataBookView *view = E_DATA_BOOK_VIEW (bonobo_object (servant));
+ d(printf("in impl_GNOME_Evolution_Addressbook_BookView_dispose\n"));
ORBit_small_unlisten_for_broken (e_data_book_view_get_listener (view), G_CALLBACK (view_listener_died_cb));
bonobo_object_unref (view);
@@ -408,6 +413,14 @@ e_data_book_view_get_backend (EDataBookView *book_view)
return book_view->priv->backend;
}
+GMutex*
+e_data_book_view_get_mutex (EDataBookView *book_view)
+{
+ g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (book_view), NULL);
+
+ return book_view->priv->mutex;
+}
+
GNOME_Evolution_Addressbook_BookViewListener
e_data_book_view_get_listener (EDataBookView *book_view)
{
@@ -441,6 +454,7 @@ e_data_book_view_dispose (GObject *object)
{
EDataBookView *book_view = E_DATA_BOOK_VIEW (object);
+ d(printf ("disposing of EDataBookView\n"));
if (book_view->priv) {
bonobo_object_release_unref (book_view->priv->listener, NULL);
@@ -457,6 +471,9 @@ e_data_book_view_dispose (GObject *object)
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_free (book_view->priv);
book_view->priv = NULL;
}
@@ -489,6 +506,7 @@ e_data_book_view_init (EDataBookView *book_view)
book_view->priv = g_new0 (EDataBookViewPrivate, 1);
book_view->priv->pending_mutex = g_mutex_new();
+ book_view->priv->mutex = g_mutex_new();
book_view->priv->next_threshold = INITIAL_THRESHOLD;
book_view->priv->threshold_max = THRESHOLD_MAX;
diff --git a/addressbook/libedata-book/e-data-book-view.h b/addressbook/libedata-book/e-data-book-view.h
index 6eb4411a9..4b13061a7 100644
--- a/addressbook/libedata-book/e-data-book-view.h
+++ b/addressbook/libedata-book/e-data-book-view.h
@@ -40,24 +40,25 @@ struct _EDataBookViewClass {
};
-EDataBookView *e_data_book_view_new (EBookBackend *backend,
- GNOME_Evolution_Addressbook_BookViewListener listener,
- const char *card_query,
- EBookBackendSExp *card_sexp);
+EDataBookView *e_data_book_view_new (EBookBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ EBookBackendSExp *card_sexp);
-const char* e_data_book_view_get_card_query (EDataBookView *book_view);
-EBookBackendSExp* e_data_book_view_get_card_sexp (EDataBookView *book_view);
-EBookBackend* e_data_book_view_get_backend (EDataBookView *book_view);
+const char* e_data_book_view_get_card_query (EDataBookView *book_view);
+EBookBackendSExp* e_data_book_view_get_card_sexp (EDataBookView *book_view);
+EBookBackend* e_data_book_view_get_backend (EDataBookView *book_view);
GNOME_Evolution_Addressbook_BookViewListener e_data_book_view_get_listener (EDataBookView *book_view);
+GMutex* e_data_book_view_get_mutex (EDataBookView *book_view);
void e_data_book_view_notify_update (EDataBookView *book_view,
- EContact *contact);
+ EContact *contact);
void e_data_book_view_notify_remove (EDataBookView *book_view,
- const char *id);
+ const char *id);
void e_data_book_view_notify_complete (EDataBookView *book_view,
- GNOME_Evolution_Addressbook_CallStatus);
+ GNOME_Evolution_Addressbook_CallStatus);
void e_data_book_view_notify_status_message (EDataBookView *book_view,
- const char *message);
+ const char *message);
GType e_data_book_view_get_type (void);