[evolution-mapi/push-notify: 6/6] Integrated event listeners. And cleanups.



commit 0bab7218d55d5dbfaca74fe4e03be10f1664cdb8
Author: Johnny Jacob <jjohnny novell com>
Date:   Mon Nov 23 11:03:12 2009 +0530

    Integrated event listeners. And cleanups.

 src/camel/camel-mapi-folder.c                  |   16 ++--
 src/camel/camel-mapi-notifications.c           |  107 ++++++++++++++++++++----
 src/camel/camel-mapi-store.c                   |   33 ++++++--
 src/camel/camel-mapi-store.h                   |    1 +
 src/libexchangemapi/exchange-mapi-connection.c |   19 +++--
 src/libexchangemapi/exchange-mapi-connection.h |    7 ++-
 6 files changed, 145 insertions(+), 38 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 9030bfa..96e8af9 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -374,7 +374,8 @@ fetch_items_summary_cb (FetchItemsCallbackData *item_data, gpointer data)
 	*slist = g_slist_prepend (*slist, item);
 
 	/*Write summary to db in batches of SUMMARY_FETCH_BATCH_COUNT items.*/ 
-	if ( (item_data->index % SUMMARY_FETCH_BATCH_COUNT == 0) || item_data->index == item_data->total-1) {
+	if ((item_data->index % SUMMARY_FETCH_BATCH_COUNT == 0) ||
+	     item_data->index == item_data->total-1) {
 		mapi_update_cache (fi_data->folder, *slist, &fi_data->changes, NULL, false);
 		g_slist_foreach (*slist, (GFunc)mapi_item_free, NULL);
 		g_slist_free (*slist);
@@ -781,7 +782,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
 
 	camel_operation_end (NULL);
 
-	camel_object_trigger_event (m->folder, "folder_changed", changes);
+	/* camel_object_trigger_event (m->folder, "folder_changed", changes); */
 	camel_folder_change_info_free (changes);
 
 	/* Discard server uid list */
@@ -965,7 +966,7 @@ camel_mapi_folder_fetch_summary (CamelStore *store, const mapi_id_t fid, struct
 				 struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options)
 {
 	gboolean status;
-	const gchar *folder_name;
+	CamelMapiStore *mapi_store = (CamelMapiStore *) store;
 
 	const guint32 summary_prop_list[] = {
 		PR_INTERNET_CPID,
@@ -992,13 +993,14 @@ camel_mapi_folder_fetch_summary (CamelStore *store, const mapi_id_t fid, struct
 
 	camel_operation_start (NULL, _("Fetching summary information for new messages in")); /* %s"), folder->name); */
 
+	CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
+
 	status = exchange_mapi_connection_fetch_items  (fid, res, sort, summary_prop_list,
 							G_N_ELEMENTS (summary_prop_list), 
 							NULL, NULL, fetch_items_summary_cb,
 							fetch_data, options);
 
-	if (!status)
-		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_INVALID, _("Fetching items failed"));
+	CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 
 	camel_operation_end (NULL);
 
@@ -1100,7 +1102,7 @@ mapi_refresh_folder(CamelFolder *folder, CamelException *ex)
 		if (((CamelMapiFolder *)folder)->type & CAMEL_MAPI_FOLDER_PUBLIC)
 			options |= MAPI_OPTIONS_USE_PFSTORE;
 
-		status = camel_mapi_folder_fetch_summary (mapi_store, temp_folder_id, res, sort,
+		status = camel_mapi_folder_fetch_summary ((CamelMapiStore *)mapi_store, temp_folder_id, res, sort,
 							  fetch_data, options);
 
 		if (!status) {
@@ -2215,5 +2217,3 @@ camel_mapi_folder_new (CamelStore *store, const char *folder_name, const char *f
 	}
 	return folder;
 }
-
-
diff --git a/src/camel/camel-mapi-notifications.c b/src/camel/camel-mapi-notifications.c
index 2868d7c..c6d9498 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -51,8 +51,10 @@
 
 static void mapi_push_notification_listener (CamelSession *session, CamelSessionThreadMsg *msg);
 static void mapi_push_notification_listener_close (CamelSession *session, CamelSessionThreadMsg *msg);
-static void mapi_new_mail_handler (struct NewMailNotification *event, gpointer *data);
 
+extern gint camel_application_is_exiting;
+
+/* TODO Doc : What is this message for?*/
 struct mapi_push_notification_msg {
 	CamelSessionThreadMsg msg;
 
@@ -62,15 +64,35 @@ struct mapi_push_notification_msg {
 	gpointer event_data;
 };
 
+/*Used for spawning threads for event actions
+  like new_mail, folder_created*/
+struct mapi_push_event_action_msg {
+	CamelSessionThreadMsg msg;
+
+	gpointer event;
+	gpointer data;
+};
+
 static void
-mapi_new_mail_handler (struct NewMailNotification *event, gpointer *data)
+mapi_new_mail_free (CamelSession *session, CamelSessionThreadMsg *msg)
 {
+	/*TODO*/
+}
+static void
+mapi_new_mail_fetch (CamelSession *session, CamelSessionThreadMsg *msg)
+{
+	struct mapi_push_event_action_msg *m = (struct mapi_push_event_action_msg *) msg;
+	struct NewMailNotification *event = m->event;
+
 	struct mapi_SRestriction *res = NULL;
-	struct SPropValue sprop;
 	guint32 options = 0;
-	CamelMapiStore *store = (CamelMapiStore *)data;
+
+	CamelMapiStore *store = (CamelMapiStore *)m->data;
 	fetch_items_data *fetch_data = g_new0 (fetch_items_data, 1);
 	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_name = NULL;
 	
@@ -87,19 +109,32 @@ mapi_new_mail_handler (struct NewMailNotification *event, gpointer *data)
 	res->res.resProperty.lpProp.ulPropTag = PR_MID;
 	res->res.resProperty.lpProp.value.dbl = event->MID;
 
-	/* set_SPropValue_proptag (&sprop, PR_MID, &event->MID); */
-	/* cast_mapi_SPropValue (&(res->res.resProperty.lpProp), &sprop); */
-
 	/* Get the folder object */
-	folder_name = camel_mapi_store_folder_lookup (store,folder_id);
-	folder = camel_store_get_folder (store, folder_name, 0, NULL);
-	if (!folder) g_print("%s %s : WARNING - FOLDER OBJECTI S INVLAUDes \n", G_STRLOC, G_STRFUNC);
-	/* FIXME : Abort on failure*/
+
+	/*Note : using store info to retrive full_name*/
+	info_count = camel_store_summary_count ((CamelStoreSummary *)store->summary) - 1;
+	while (info_count >= 0) {
+		info = camel_store_summary_index (store->summary, info_count);
+		mapi_info = (CamelMapiStoreInfo *)info;
+		if (!g_strcmp0 (mapi_info->folder_id, folder_id)){
+			folder_name = mapi_info->full_name;
+		}
+		info_count--;
+	}
+
+	folder = camel_store_get_folder ((CamelStore *)store, folder_name, 0, NULL);
+
+	/* Abort on failure*/
+	if (!folder)
+		return;
+
 	fetch_data->changes = camel_folder_change_info_new ();
 	fetch_data->folder = folder;
 
+	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
 	camel_mapi_folder_fetch_summary (store, event->FID, res, NULL, fetch_data, options);
-
+	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+	
 	camel_folder_summary_touch (folder->summary);
 	/* mapi_sync_summary */
 	camel_folder_summary_save_to_db (folder->summary, NULL);
@@ -107,14 +142,27 @@ mapi_new_mail_handler (struct NewMailNotification *event, gpointer *data)
 	camel_store_summary_save ((CamelStoreSummary *)((CamelMapiStore *)folder->parent_store)->summary);
 
 	camel_object_trigger_event (folder, "folder_changed", fetch_data->changes);
+
 	camel_folder_change_info_free (fetch_data->changes);
 	g_free (res);
 	g_free (folder_id);
+
 }
 
+static CamelSessionThreadOps mapi_new_mail_ops = {
+	mapi_new_mail_fetch,
+	mapi_new_mail_free,
+};
+
+
 static gint
-mapi_notifications_filter (guint16 type, void *event, void *private_data)
+mapi_notifications_filter (guint16 type, void *event, void *data)
 {
+	CamelMapiStore *store = (CamelMapiStore *)data;
+	CamelSession *session = ((CamelService *)store)->session;
+	struct mapi_push_event_action_msg *new_mail_ops_msg ;
+	gint status = 0;
+
 	switch(type) {
 	/* -- Folder Events -- */
 	case fnevObjectCreated:
@@ -137,7 +185,21 @@ mapi_notifications_filter (guint16 type, void *event, void *private_data)
 	case fnevNewMail:
 	case fnevNewMail|fnevMbit:
 		d_notifications(printf ("Event : New mail\n"));
-		mapi_new_mail_handler (event, private_data);
+		d_notifications(mapidump_newmail (event, "\t"));
+		/*Note : Use Thread Pool ?*/
+		new_mail_ops_msg = camel_session_thread_msg_new (session, &mapi_new_mail_ops,
+								 sizeof (*new_mail_ops_msg));
+
+		new_mail_ops_msg->event = event;
+		new_mail_ops_msg->data = data;
+		
+		/* status = camel_session_thread_queue (session, &new_mail_ops_msg->msg, 0); */
+		mapi_new_mail_fetch (session, new_mail_ops_msg);
+		/* camel_session_thread_wait (session, status); */
+
+		g_print("%s %s : >>>>>>>>>>> Queued a thread. - %d\n", G_STRLOC,
+			G_STRFUNC, status);
+		return -1;
 		break;
 	case fnevMbit|fnevObjectCreated:
 		d_notifications(printf ("Event : Message created\n"));
@@ -168,19 +230,32 @@ static CamelSessionThreadOps mapi_push_notification_ops = {
 	mapi_push_notification_listener_close,
 };
 
+static gint
+mapi_notifications_continue_check (void)
+{
+	if (camel_operation_cancel_check(NULL) || (camel_application_is_exiting == TRUE))
+		return 1;
+
+	return 0;
+}
+
 static void
 mapi_push_notification_listener (CamelSession *session, CamelSessionThreadMsg *msg)
 {
 	struct mapi_push_notification_msg *m = (struct mapi_push_notification_msg *)msg;
+	CamelMapiStore *mapi_store = (CamelMapiStore *) m->event_data;
 
+	CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
 	if (exchange_mapi_events_init ()) {
 		exchange_mapi_events_subscribe (0, m->event_options, m->event_mask,
 						&m->connection,	mapi_notifications_filter,
 						m->event_data);
 
+		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 		/* Need a better API for canceling this operation*/
-		exchange_mapi_events_monitor (NULL);
-	}
+		exchange_mapi_events_monitor (mapi_notifications_continue_check);
+	} else 
+		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 
 }
 
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index a668f11..e00b0a5 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -114,7 +114,7 @@ static void mapi_folders_sync (CamelMapiStore *store, const char *top, guint32 f
 static gboolean mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const char *fid);
 
 static void mapi_update_folder_hash_tables (CamelMapiStore *store, const gchar *name, const gchar *fid, const gchar *parent_id);
-static const gchar* mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache);
+/* static const gchar* mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache); */
 static const gchar* mapi_folders_hash_table_pfid_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache);
 #if 0
 static const gchar* mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name, gboolean use_cache);
@@ -352,6 +352,7 @@ mapi_connect(CamelService *service, CamelException *ex)
 {
 	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
 	CamelMapiStorePrivate *priv = store->priv;
+	guint16 event_mask = 0;
 
 	if (service->status == CAMEL_SERVICE_DISCONNECTED) {
 		return FALSE;
@@ -378,6 +379,12 @@ mapi_connect(CamelService *service, CamelException *ex)
 	service->status = CAMEL_SERVICE_CONNECTED;
 	((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_AVAIL;
 
+	/* Start event monitor */
+	event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted |
+		fnevObjectModified | fnevObjectMoved | fnevObjectCopied;
+
+	camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+
 	camel_store_summary_save ((CamelStoreSummary *) store->summary);
 
 	CAMEL_SERVICE_REC_UNLOCK (service, connect_lock);
@@ -390,9 +397,12 @@ mapi_disconnect(CamelService *service, gboolean clean, CamelException *ex)
 {
 	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
 
+	/* Disconnect from event monitor */
+	exchange_mapi_events_monitor_close ();
+
 	/* Close the mapi subsystem */
 	exchange_mapi_connection_close ();
-
+	
 	((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL;
 	service->status = CAMEL_SERVICE_DISCONNECTED;
 
@@ -436,9 +446,17 @@ mapi_get_folder(CamelStore *store, const char *folder_name, guint32 flags, Camel
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
 	CamelMapiStorePrivate *priv = mapi_store->priv;
 	CamelFolder *folder;
-	char *storage_path = NULL;
+	gchar *folder_dir, *storage_path = NULL;
 
 	storage_path = g_strdup_printf("%s/folders", priv->storage_path);
+	folder_dir = g_strdup_printf("%s/folders/%s", storage_path, folder_name);
+
+	if (!folder_dir || g_access (folder_dir, F_OK) != 0) {
+		g_free (folder_dir);
+		/* camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, */
+		/* 		_("No such folder %s"), folder_name); */
+		/* return NULL; */
+	}
 
 	folder = camel_mapi_folder_new (store, folder_name, storage_path, flags, ex);
 	g_free (storage_path);
@@ -1157,7 +1175,8 @@ mapi_folders_update_hash_tables_from_cache (CamelMapiStore *store)
 	}
 }
 
-static const gchar*
+/* static const gchar* */
+const gchar*
 mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid,
 				     gboolean use_cache)
 {
@@ -1356,10 +1375,10 @@ mapi_folders_sync (CamelMapiStore *store, const char *top, guint32 flags, CamelE
 
 	/* FIXME : This place is not right! */
 	/* Start Push Notification listener */
-	event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted |
-		fnevObjectModified | fnevObjectMoved | fnevObjectCopied;
+	/* event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted | */
+	/* 	fnevObjectModified | fnevObjectMoved | fnevObjectCopied; */
 
-	camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+	/* camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE); */
 }
 
 
diff --git a/src/camel/camel-mapi-store.h b/src/camel/camel-mapi-store.h
index f2540fa..329e560 100644
--- a/src/camel/camel-mapi-store.h
+++ b/src/camel/camel-mapi-store.h
@@ -96,6 +96,7 @@ const gchar* camel_mapi_store_folder_lookup (CamelMapiStore *mapi_store, const c
 const gchar* camel_mapi_store_get_profile_name (CamelMapiStore *mapi_store);
 const gchar *camel_mapi_store_system_folder_fid (CamelMapiStore *mapi_store, guint folder_type);
 const gchar *camel_mapi_store_folder_id_lookup_offline (CamelMapiStore *mapi_store, const char *folder_name);
+const gchar* mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache);
 
 __END_DECLS
 
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index 99a31db..b21fc27 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -3047,7 +3047,8 @@ exchange_mapi_events_subscribe (mapi_id_t *obj_id, guint32 options,
 	return (retval == MAPI_E_SUCCESS);
 }
 
-gboolean exchange_mapi_events_unsubscribe (mapi_object_t *obj, guint32 connection)
+gboolean
+exchange_mapi_events_unsubscribe (mapi_object_t *obj, guint32 connection)
 {
 	enum MAPISTATUS	retval;
 
@@ -3057,14 +3058,20 @@ gboolean exchange_mapi_events_unsubscribe (mapi_object_t *obj, guint32 connectio
 }
 
 /* Note : Blocking infinite loop. */
-gboolean exchange_mapi_events_monitor (gpointer data)
+gboolean
+exchange_mapi_events_monitor (mapi_notify_continue_callback_t check)
 {
 	enum MAPISTATUS	retval;
+	retval = MonitorNotification (global_mapi_session, NULL, check);
+	return retval;
+}
 
-	/*Fixme : If we do multiple sessions. Fix this */
-	retval = MonitorNotification(global_mapi_session, (void *)data);
-
-	return (retval == MAPI_E_SUCCESS);
+void
+exchange_mapi_events_monitor_close ()
+{
+	struct mapi_notify_ctx	*notify_ctx;
+	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
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index 3363472..b31892c 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -214,9 +214,13 @@ gboolean exchange_mapi_delete_profile (const char *profile);
 
 
 /* Push notifications APIs */
+typedef gboolean (*exchange_check_continue) (void);
+
 gboolean exchange_mapi_events_init ();
 
-gboolean exchange_mapi_events_monitor (gpointer data);
+gboolean exchange_mapi_events_monitor (exchange_check_continue check);
+
+void exchange_mapi_events_monitor_close ();
 
 gboolean exchange_mapi_events_subscribe (mapi_id_t *obj_id, guint32 options,
 					 guint16 event_mask, guint32 *connection,
@@ -229,4 +233,5 @@ exchange_mapi_events_subscribe_and_monitor (mapi_id_t *obj_id, guint32 options,
 					    guint16 event_mask, guint32 *connection,
 					    gboolean use_store, mapi_notify_callback_t callback,
 					    gpointer data);
+
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]