[evolution-mapi] Bug #607744 - Crash on MAPI notification close
- From: Milan Crha <mcrha src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #607744 - Crash on MAPI notification close
- Date: Fri, 5 Feb 2010 12:35:59 +0000 (UTC)
commit 006728d1cd3c778a1fd87ddf497a8411d9b9cd70
Author: Milan Crha <mcrha redhat com>
Date: Fri Feb 5 13:35:28 2010 +0100
Bug #607744 - Crash on MAPI notification close
src/camel/camel-mapi-notifications.c | 78 ++++++++++++++----------
src/camel/camel-mapi-notifications.h | 6 +-
src/camel/camel-mapi-store.c | 12 +++-
src/libexchangemapi/exchange-mapi-connection.c | 19 ++----
src/libexchangemapi/exchange-mapi-connection.h | 6 +-
5 files changed, 66 insertions(+), 55 deletions(-)
---
diff --git a/src/camel/camel-mapi-notifications.c b/src/camel/camel-mapi-notifications.c
index 99a2150..3276a8e 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -62,44 +62,31 @@ struct mapi_push_notification_msg {
guint32 connection;
guint32 event_options;
gpointer event_data;
-};
-
-/*Used for spawning threads for event actions
- like new_mail, folder_created*/
-struct mapi_push_event_action_msg {
- CamelSessionThreadMsg msg;
- uint64_t fid;
- uint64_t mid;
- gpointer data;
+ gint op_id;
};
static void
-mapi_new_mail_fetch (struct NewMailNotification *event, gpointer data)
+process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *new_mail_notif)
{
struct mapi_SRestriction *res = NULL;
guint32 options = 0;
- CamelMapiStore *store = (CamelMapiStore *)data;
- fetch_items_data *fetch_data = g_new0 (fetch_items_data, 1);
+ fetch_items_data *fetch_data;
CamelFolder *folder = NULL;
gint info_count = -1;
CamelStoreInfo *info;
CamelMapiStoreInfo *mapi_info;
- const gchar *folder_id = exchange_mapi_util_mapi_id_to_string (event->FID);
+ const gchar *folder_id;
const gchar *folder_name = NULL;
-
+
+ g_return_if_fail (store != NULL);
+ g_return_if_fail (new_mail_notif != NULL);
+
/* FIXME : Continue only if we are handling a mail object.*/
if (0) return;
-
- /*Use restriction to fetch the message summary based on MID*/
- res = g_new0 (struct mapi_SRestriction, 1);
- res->rt = RES_PROPERTY;
- res->res.resProperty.relop = RES_PROPERTY;
- res->res.resProperty.ulPropTag = PR_MID;
- res->res.resProperty.lpProp.ulPropTag = PR_MID;
- res->res.resProperty.lpProp.value.dbl = event->MID;
+ folder_id = exchange_mapi_util_mapi_id_to_string (new_mail_notif->FID);
/* Get the folder object */
@@ -122,12 +109,21 @@ mapi_new_mail_fetch (struct NewMailNotification *event, gpointer data)
if (!folder)
return;
+ /*Use restriction to fetch the message summary based on MID*/
+ res = g_new0 (struct mapi_SRestriction, 1);
+
+ res->rt = RES_PROPERTY;
+ res->res.resProperty.relop = RES_PROPERTY;
+ res->res.resProperty.ulPropTag = PR_MID;
+ res->res.resProperty.lpProp.ulPropTag = PR_MID;
+ res->res.resProperty.lpProp.value.dbl = new_mail_notif->MID;
+
+ fetch_data = g_new0 (fetch_items_data, 1);
fetch_data->changes = camel_folder_change_info_new ();
fetch_data->folder = folder;
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
- camel_mapi_folder_fetch_summary ((CamelStore *)store, event->FID,
- res, NULL, fetch_data, options);
+ camel_mapi_folder_fetch_summary ((CamelStore *)store, new_mail_notif->FID, res, NULL, fetch_data, options);
CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
camel_folder_summary_touch (folder->summary);
@@ -143,7 +139,7 @@ mapi_new_mail_fetch (struct NewMailNotification *event, gpointer data)
}
static gint
-mapi_notifications_filter (guint16 type, void *event, void *data)
+mapi_notifications_filter (guint16 type, void *event, void *store)
{
switch(type) {
/* -- Folder Events -- */
@@ -168,7 +164,7 @@ mapi_notifications_filter (guint16 type, void *event, void *data)
case fnevNewMail|fnevMbit:
d_notifications(printf ("Event : New mail\n"));
d_notifications(mapidump_newmail (event, "\t"));
- mapi_new_mail_fetch (event, data);
+ process_mapi_new_mail_notif (store, event);
return -1;
break;
case fnevMbit|fnevObjectCreated:
@@ -233,12 +229,13 @@ mapi_push_notification_listener (CamelSession *session, CamelSessionThreadMsg *m
CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
if (exchange_mapi_events_init ()) {
- exchange_mapi_events_subscribe (0, m->event_options, m->event_mask,
+ exchange_mapi_events_subscribe (m->event_options, m->event_mask,
&m->connection, mapi_notifications_filter,
m->event_data);
CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
exchange_mapi_events_monitor (cb_data); /*Blocking call. Don't hold locks here*/
+ exchange_mapi_events_unsubscribe (m->connection);
} else
CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
@@ -248,12 +245,10 @@ mapi_push_notification_listener (CamelSession *session, CamelSessionThreadMsg *m
static void
mapi_push_notification_listener_close (CamelSession *session, CamelSessionThreadMsg *msg)
{
- /*TODO*/
}
-void
-camel_mapi_notfication_listener_start (CamelMapiStore *store, guint16 mask,
- guint32 options)
+gpointer
+camel_mapi_notification_listener_start (CamelMapiStore *store, guint16 mask, guint32 options)
{
CamelSession *session = ((CamelService *)store)->session;
struct mapi_push_notification_msg *mapi_push_notification_msg_op;
@@ -266,5 +261,24 @@ camel_mapi_notfication_listener_start (CamelMapiStore *store, guint16 mask,
mapi_push_notification_msg_op->event_mask = mask;
mapi_push_notification_msg_op->event_data = store;
- camel_session_thread_queue (session, &mapi_push_notification_msg_op->msg, 0);
+ mapi_push_notification_msg_op->op_id = camel_session_thread_queue (session, &mapi_push_notification_msg_op->msg, 0);
+
+ return mapi_push_notification_msg_op;
+}
+
+/* start_value is a pointer returned from the start function */
+void
+camel_mapi_notification_listener_stop (CamelMapiStore *store, gpointer start_value)
+{
+ struct mapi_push_notification_msg *msg_op;
+ gint op_id;
+
+ g_return_if_fail (store != NULL);
+ g_return_if_fail (start_value != NULL);
+
+ msg_op = start_value;
+ op_id = msg_op->op_id;
+ camel_operation_cancel (msg_op->msg.op);
+
+ camel_session_thread_wait (((CamelService *)store)->session, op_id);
}
diff --git a/src/camel/camel-mapi-notifications.h b/src/camel/camel-mapi-notifications.h
index 4c72aef..363a416 100644
--- a/src/camel/camel-mapi-notifications.h
+++ b/src/camel/camel-mapi-notifications.h
@@ -28,9 +28,9 @@
G_BEGIN_DECLS
-void
-camel_mapi_notfication_listener_start (CamelMapiStore *store, guint16 mask,
- guint32 options);
+gpointer camel_mapi_notification_listener_start (CamelMapiStore *store, guint16 mask, guint32 options);
+void camel_mapi_notification_listener_stop (CamelMapiStore *store, gpointer start_value);
+
G_END_DECLS
#endif
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 1a293ba..1c3c157 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -84,6 +84,7 @@ struct _CamelMapiStorePrivate {
GHashTable *default_folders; /*Default Type : Folder ID*/
gboolean folders_synced; /* whether were synced folder list already */
+ gpointer notification_data; /* pointer to a notification data; can be only one */
};
static CamelOfflineStoreClass *parent_class = NULL;
@@ -233,6 +234,7 @@ static void camel_mapi_store_init(CamelMapiStore *store, CamelMapiStoreClass *kl
priv->storage_path = NULL;
priv->base_url = NULL;
priv->folders_synced = FALSE;
+ priv->notification_data = NULL;
mapi_store->priv = priv;
@@ -420,7 +422,8 @@ mapi_connect(CamelService *service, CamelException *ex)
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
- camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+ if (!store->priv->notification_data)
+ store->priv->notification_data = camel_mapi_notification_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
@@ -437,11 +440,14 @@ mapi_disconnect(CamelService *service, gboolean clean, CamelException *ex)
CamelMapiStore *store = CAMEL_MAPI_STORE (service);
/* Disconnect from event monitor */
- exchange_mapi_events_monitor_close ();
+ if (store->priv->notification_data) {
+ camel_mapi_notification_listener_stop (store, store->priv->notification_data);
+ store->priv->notification_data = NULL;
+ }
/* Close the mapi subsystem */
exchange_mapi_connection_close ();
-
+
store->priv->folders_synced = FALSE;
((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL;
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index eae5f67..82fa76b 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -3109,7 +3109,7 @@ exchange_mapi_events_init ()
}
gboolean
-exchange_mapi_events_subscribe (mapi_id_t *obj_id, guint32 options,
+exchange_mapi_events_subscribe (guint32 options,
guint16 event_mask, guint32 *connection,
mapi_notify_callback_t callback, gpointer data)
{
@@ -3139,11 +3139,14 @@ exchange_mapi_events_subscribe (mapi_id_t *obj_id, guint32 options,
}
gboolean
-exchange_mapi_events_unsubscribe (mapi_object_t *obj, guint32 connection)
+exchange_mapi_events_unsubscribe (guint32 connection)
{
enum MAPISTATUS retval;
- retval = Unsubscribe(mapi_object_get_session(obj), connection);
+ if (!global_mapi_session)
+ return FALSE;
+
+ retval = Unsubscribe (global_mapi_session, connection);
return (retval == MAPI_E_SUCCESS);
}
@@ -3157,16 +3160,6 @@ exchange_mapi_events_monitor (struct mapi_notify_continue_callback_data *cb_data
return retval;
}
-void
-exchange_mapi_events_monitor_close ()
-{
- struct mapi_notify_ctx *notify_ctx;
- if (global_mapi_session) {
- notify_ctx = global_mapi_session->notify_ctx;
- close (notify_ctx->fd);
- }
-}
-
/* Shows error message on the console, and, if error_msg is not NULL, then
sets it to the similar error message as well. */
static void
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index 7ef029c..b3d27e7 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -223,13 +223,11 @@ gboolean exchange_mapi_events_init ();
gboolean exchange_mapi_events_monitor (struct mapi_notify_continue_callback_data *cb_data);
-void exchange_mapi_events_monitor_close ();
-
-gboolean exchange_mapi_events_subscribe (mapi_id_t *obj_id, guint32 options,
+gboolean exchange_mapi_events_subscribe (guint32 options,
guint16 event_mask, guint32 *connection,
mapi_notify_callback_t callback, gpointer data);
-gboolean exchange_mapi_events_unsubscribe (mapi_object_t *obj, guint32 connection);
+gboolean exchange_mapi_events_unsubscribe (guint32 connection);
gboolean
exchange_mapi_events_subscribe_and_monitor (mapi_id_t *obj_id, guint32 options,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]