diff options
author | Chris Toshok <toshok@ximian.com> | 2003-10-23 04:50:36 +0800 |
---|---|---|
committer | Chris Toshok <toshok@src.gnome.org> | 2003-10-23 04:50:36 +0800 |
commit | cbfab681c1576d4de27d48fbd6b4b7780670494a (patch) | |
tree | 70e99033907a1f5dada728e785835a07ca6ab98c /addressbook/backend/pas/pas-backend-vcf.c | |
parent | f7cbb839adf3fd47aa07ca2080063acd6fff6978 (diff) | |
download | gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.gz gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.bz2 gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.lz gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.xz gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.zst gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.zip |
use the synchronous api for this. simplifies it a bunch.
2003-10-21 Chris Toshok <toshok@ximian.com>
* tools/evolution-addressbook-abuse.c: use the synchronous api for
this. simplifies it a bunch.
2003-10-21 Chris Toshok <toshok@ximian.com>
* backend/pas/pas-book.c
(impl_GNOME_Evolution_Addressbook_Book_remove): we can ill afford
bad debug spew.
(view_listener_died_cb): implement.
(impl_GNOME_Evolution_Addressbook_Book_getBookView): hook up an
ORBit_small connection listener on the view's listener.
(pas_book_respond_create): use e_contact_get_const instead of
e_contact_get here. fixes a leak.
* backend/pas/pas-book-view.c
(impl_GNOME_Evolution_Addressbook_BookView_stop): implement, call
pas_backend_stop_book_view.
(pas_book_view_get_listener): return the book view's listener.
(pas_book_view_class_init): fill in epv->stop.
(pas_book_view_init): use a #define for THRESHOLD_MAX instead of
the constant.
* backend/pas/pas-book-view.h: add prototype for
pas_book_view_get_listener.
* backend/pas/pas-backend.c (pas_backend_stop_book_view):
implement.
(pas_backend_remove_book_view): implement.
* backend/pas/pas-backend.h: add prototype for stop_book_view and
remove_book_view.
* backend/pas/pas-backend-vcf.c (load_file): pass in the fd and
use fdopen here.
(foreach_build_list): don't creat EContacts here, because we'll
just be converting them back to vcards anyway.
(save_file): use char*'s instead of EContacts, and split entries
with 2 blank lines. Also, hold the lock over the entire function.
(do_create): hold the lock around uid generation and touching the
hash table.
(pas_backend_vcf_process_remove_contacts): same.
(pas_backend_vcf_process_modify_contact): same.
(pas_backend_vcf_stop_book_view): new function, but leave
unimplemented for now.
(pas_backend_vcf_load_uri): the uri contains the directory name,
not the filename.
(pas_backend_vcf_dispose): grab the lock here just for sanity's
sake. Also reorder things a bit, and free the hashtable and
mutex.
(pas_backend_vcf_init): init the mutex.
* backend/pas/pas-backend-summary.c
(pas_backend_summary_add_contact): don't unref the contact here.
* backend/pas/pas-backend-ldap.c
(pas_backend_ldap_process_stop_book_view): new function, but leave
unimplemented for now.
* backend/pas/pas-backend-file.c (build_summary): use an EContact
for this call.
(do_summary_query): nuke, the contents of this has been moved to
start_book_view.
(pas_backend_file_search_timeout): same.
(pas_backend_file_search): same.
(pas_backend_file_start_book_view): glom everything into here
involving searching. This function could (and should) be renamed
and reused from both this function and _get_contact_list.
(pas_backend_file_stop_book_view): new function.
(pas_backend_file_class_init): fill in backend->stop_book_view.
* backend/pas/Makefile.am (LDAP_BACKEND): libpasldap.a ->
libpasldap.la
(noinst_LTLIBRARIES): *.a -> *.la.
(libpas_la_SOURCES): same.
(libpasfile_la_SOURCES): same.
(libpasvcf_la_SOURCES): same.
(libpasldap_la_SOURCES): same.
* backend/idl/addressbook.idl: add BookView::stop.
* backend/ebook/e-vcard.c (read_attribute_value): fix GString
related leaks.
(read_attribute_params): same.
(parse): don't leak the EVCardAttributes corresponding to
BEGIN/END:vCard.
(free_gstring): new function
(e_vcard_attribute_remove_values): free the decoded_values list,
using free_gstring.
* backend/ebook/e-book.c (e_book_response_get_book_view): ref the
listener here.
* backend/ebook/e-book-view.h: add prototype for e_book_view_stop.
* backend/ebook/e-book-view.c (e_book_view_stop): new function.
* backend/ebook/e-book-async.c (_get_book_view_response_dtor):
unref the book view.
svn path=/trunk/; revision=23000
Diffstat (limited to 'addressbook/backend/pas/pas-backend-vcf.c')
-rw-r--r-- | addressbook/backend/pas/pas-backend-vcf.c | 95 |
1 files changed, 69 insertions, 26 deletions
diff --git a/addressbook/backend/pas/pas-backend-vcf.c b/addressbook/backend/pas/pas-backend-vcf.c index 3765fd978e..e82fe04f56 100644 --- a/addressbook/backend/pas/pas-backend-vcf.c +++ b/addressbook/backend/pas/pas-backend-vcf.c @@ -36,6 +36,7 @@ typedef struct _PASBackendVCFSearchContext PASBackendVCFSearchContext; struct _PASBackendVCFPrivate { char *uri; char *filename; + GMutex *mutex; GHashTable *contacts; gboolean dirty; int flush_timeout_tag; @@ -122,13 +123,13 @@ insert_contact (PASBackendVCF *vcf, char *vcard) } static void -load_file (PASBackendVCF *vcf) +load_file (PASBackendVCF *vcf, int fd) { FILE *fp; GString *str; char buf[1024]; - fp = fopen (vcf->priv->filename, "r"); + fp = fdopen (fd, "r"); if (!fp) { g_warning ("failed to open `%s' for reading", vcf->priv->filename); return; @@ -160,30 +161,32 @@ load_file (PASBackendVCF *vcf) static void foreach_build_list (char *id, char *vcard_string, GList **list) { - *list = g_list_append (*list, e_contact_new_from_vcard (vcard_string)); + *list = g_list_append (*list, vcard_string); } static gboolean save_file (PASBackendVCF *vcf) { - GList *contacts = NULL; + GList *vcards = NULL; GList *l; char *new_path; int fd, rv; - g_hash_table_foreach (vcf->priv->contacts, (GHFunc)foreach_build_list, &contacts); + g_warning ("PASBackendVCF flushing file to disk"); + + g_mutex_lock (vcf->priv->mutex); + g_hash_table_foreach (vcf->priv->contacts, (GHFunc)foreach_build_list, &vcards); new_path = g_strdup_printf ("%s.new", vcf->priv->filename); fd = open (new_path, O_CREAT | O_TRUNC | O_WRONLY, 0666); - for (l = contacts; l; l = l->next) { - EContact *contact = l->data; - char *vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); + for (l = vcards; l; l = l->next) { + char *vcard_str = l->data; int len = strlen (vcard_str); rv = write (fd, vcard_str, len); - g_free (vcard_str); + if (rv < len) { /* XXX */ g_warning ("write failed. we need to handle short writes\n"); @@ -192,8 +195,8 @@ save_file (PASBackendVCF *vcf) return FALSE; } - rv = write (fd, "\r\n", 2); - if (rv < 2) { + rv = write (fd, "\r\n\r\n", 4); + if (rv < 4) { /* XXX */ g_warning ("write failed. we need to handle short writes\n"); close (fd); @@ -208,12 +211,13 @@ save_file (PASBackendVCF *vcf) return FALSE; } - g_list_foreach (contacts, (GFunc)g_object_unref, NULL); - g_list_free (contacts); + g_list_free (vcards); g_free (new_path); vcf->priv->dirty = FALSE; + g_mutex_unlock (vcf->priv->mutex); + return TRUE; } @@ -245,6 +249,10 @@ do_create(PASBackendVCF *bvcf, EContact *contact; char *vcard; + /* at the very least we need the unique_id generation to be + protected by the lock, even if the actual vcard parsing + isn't. */ + g_mutex_lock (bvcf->priv->mutex); id = pas_backend_vcf_create_unique_id (); contact = e_contact_new_from_vcard (vcard_req); @@ -261,6 +269,8 @@ do_create(PASBackendVCF *bvcf, vcf_flush_file, bvcf); } + g_mutex_unlock (bvcf->priv->mutex); + return contact; } @@ -292,8 +302,13 @@ pas_backend_vcf_process_remove_contacts (PASBackendSync *backend, /* FIXME: make this handle bulk deletes like the file backend does */ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); char *id = id_list->data; + gboolean success; + + g_mutex_lock (bvcf->priv->mutex); + success = g_hash_table_remove (bvcf->priv->contacts, id); - if (!g_hash_table_remove (bvcf->priv->contacts, id)) { + if (!success) { + g_mutex_unlock (bvcf->priv->mutex); return GNOME_Evolution_Addressbook_ContactNotFound; } else { @@ -301,6 +316,7 @@ pas_backend_vcf_process_remove_contacts (PASBackendSync *backend, if (!bvcf->priv->flush_timeout_tag) bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT, vcf_flush_file, bvcf); + g_mutex_unlock (bvcf->priv->mutex); *ids = g_list_append (*ids, id); @@ -317,16 +333,26 @@ pas_backend_vcf_process_modify_contact (PASBackendSync *backend, PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); char *old_id, *old_vcard_string; const char *id; + gboolean success; /* create a new ecard from the request data */ *contact = e_contact_new_from_vcard (vcard); id = e_contact_get_const (*contact, E_CONTACT_UID); - if (!g_hash_table_lookup_extended (bvcf->priv->contacts, id, (gpointer)&old_id, (gpointer)&old_vcard_string)) { + g_mutex_lock (bvcf->priv->mutex); + success = g_hash_table_lookup_extended (bvcf->priv->contacts, id, (gpointer)&old_id, (gpointer)&old_vcard_string); + + if (!success) { + g_mutex_unlock (bvcf->priv->mutex); return GNOME_Evolution_Addressbook_ContactNotFound; } else { g_hash_table_insert (bvcf->priv->contacts, old_id, g_strdup (vcard)); + bvcf->priv->dirty = TRUE; + if (!bvcf->priv->flush_timeout_tag) + bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT, + vcf_flush_file, bvcf); + g_mutex_unlock (bvcf->priv->mutex); g_free (old_vcard_string); @@ -400,6 +426,13 @@ pas_backend_vcf_start_book_view (PASBackend *backend, pas_backend_vcf_search (PAS_BACKEND_VCF (backend), book_view); } +static void +pas_backend_vcf_stop_book_view (PASBackend *backend, + PASBookView *book_view) +{ + /* XXX nothing here yet, and there should be. */ +} + static char * pas_backend_vcf_extract_path_from_uri (const char *uri) { @@ -443,16 +476,17 @@ pas_backend_vcf_load_uri (PASBackend *backend, gboolean only_if_exists) { PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); - char *filename; + char *dirname; gboolean writable = FALSE; int fd; g_free(bvcf->priv->uri); bvcf->priv->uri = g_strdup (uri); - bvcf->priv->filename = filename = pas_backend_vcf_extract_path_from_uri (uri); + dirname = pas_backend_vcf_extract_path_from_uri (uri); + bvcf->priv->filename = g_build_filename (dirname, "addressbook.vcf", NULL); - fd = open (filename, O_RDWR); + fd = open (bvcf->priv->filename, O_RDWR); bvcf->priv->contacts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -460,10 +494,10 @@ pas_backend_vcf_load_uri (PASBackend *backend, if (fd != -1) { writable = TRUE; } else { - fd = open (filename, O_RDONLY); + fd = open (bvcf->priv->filename, O_RDONLY); if (fd == -1) { - fd = open (filename, O_CREAT, 0666); + fd = open (bvcf->priv->filename, O_CREAT, 0666); if (fd != -1 && !only_if_exists) { EContact *contact; @@ -485,8 +519,7 @@ pas_backend_vcf_load_uri (PASBackend *backend, return GNOME_Evolution_Addressbook_OtherError; } - close (fd); /* XXX ugh */ - load_file (bvcf); + load_file (bvcf, fd); pas_backend_set_is_loaded (backend, TRUE); pas_backend_set_is_writable (backend, writable); @@ -546,17 +579,25 @@ pas_backend_vcf_dispose (GObject *object) if (bvcf->priv) { - if (bvcf->priv->dirty) - save_file (bvcf); + g_mutex_lock (bvcf->priv->mutex); if (bvcf->priv->flush_timeout_tag) { g_source_remove (bvcf->priv->flush_timeout_tag); bvcf->priv->flush_timeout_tag = 0; } + if (bvcf->priv->dirty) + save_file (bvcf); + + g_hash_table_destroy (bvcf->priv->contacts); + g_free (bvcf->priv->uri); g_free (bvcf->priv->filename); + g_mutex_unlock (bvcf->priv->mutex); + + g_mutex_free (bvcf->priv->mutex); + g_free (bvcf->priv); bvcf->priv = NULL; } @@ -580,6 +621,7 @@ pas_backend_vcf_class_init (PASBackendVCFClass *klass) backend_class->load_uri = pas_backend_vcf_load_uri; backend_class->get_static_capabilities = pas_backend_vcf_get_static_capabilities; backend_class->start_book_view = pas_backend_vcf_start_book_view; + backend_class->stop_book_view = pas_backend_vcf_stop_book_view; backend_class->cancel_operation = pas_backend_vcf_cancel_operation; sync_class->create_contact_sync = pas_backend_vcf_process_create_contact; @@ -598,8 +640,9 @@ pas_backend_vcf_init (PASBackendVCF *backend) { PASBackendVCFPrivate *priv; - priv = g_new0 (PASBackendVCFPrivate, 1); - priv->uri = NULL; + priv = g_new0 (PASBackendVCFPrivate, 1); + priv->uri = NULL; + priv->mutex = g_mutex_new(); backend->priv = priv; } |