balsa r8032 - in trunk: . libbalsa/imap



Author: pawels
Date: Tue Dec 30 17:23:33 2008
New Revision: 8032
URL: http://svn.gnome.org/viewvc/balsa?rev=8032&view=rev

Log:
* libbalsa/imap/imap_search.c: keep ImapHandle locked when searching.
* libbalsa/imap/imap-handle.c: .. and when switching to IDLE mode.
* libbalsa/imap/imap-commands.c: and when threading and sorting.


Modified:
   trunk/ChangeLog
   trunk/libbalsa/imap/imap-commands.c
   trunk/libbalsa/imap/imap-handle.c
   trunk/libbalsa/imap/imap_private.h
   trunk/libbalsa/imap/imap_search.c

Modified: trunk/libbalsa/imap/imap-commands.c
==============================================================================
--- trunk/libbalsa/imap/imap-commands.c	(original)
+++ trunk/libbalsa/imap/imap-commands.c	Tue Dec 30 17:23:33 2008
@@ -807,7 +807,8 @@
 }
   
 /* imap_assure_needed_flags issues several SEARCH queries in one shot
-   and hopes the output is not intermixed */
+   and hopes the output is not intermixed. This functionl must be
+   called with handle locked. */
 ImapResponse
 imap_assure_needed_flags(ImapMboxHandle *h, ImapMsgFlag needed_flags)
 {
@@ -896,16 +897,22 @@
 {
   ImapFlagCache *flags;
   ImapMsgFlag needed_flags;
+  gboolean retval;
 
   IMAP_REQUIRED_STATE1(h, IMHS_SELECTED, IMR_BAD);
+
+  HANDLE_LOCK(h);
   flags = &g_array_index(h->flag_cache, ImapFlagCache, msgno-1);
   
   needed_flags = ~flags->known_flags & (flag_set | flag_unset);
   
-  return 
+  retval =
     (!needed_flags||imap_assure_needed_flags(h, needed_flags) == IMR_OK) &&
     (flags->flag_values & flag_set) == flag_set &&
     (flags->flag_values & flag_unset) == 0;
+  HANDLE_UNLOCK(h);
+
+  return retval;
 }
 
 
@@ -1555,7 +1562,11 @@
 ImapResponse
 imap_mbox_thread(ImapMboxHandle *h, const char *how, ImapSearchKey *filter)
 {
+  ImapResponse rc = IMR_NO;
+
   IMAP_REQUIRED_STATE1(h, IMHS_SELECTED, IMR_BAD);
+
+  HANDLE_LOCK(h);
   if(imap_mbox_handle_can_do(h, IMCAP_THREAD_REFERENCES)) {
     int can_do_literals = imap_mbox_handle_can_do(h, IMCAP_LITERAL);
     unsigned cmdno;
@@ -1579,9 +1590,10 @@
       rc = imap_cmd_step(h, cmdno);
     while(rc == IMR_UNTAGGED);
     imap_handle_idle_enable(h, 30);
-    return rc;
-  } else
-    return IMR_NO;
+  }
+  HANDLE_UNLOCK(h);
+
+  return rc;
 }
 
 
@@ -1803,15 +1815,19 @@
 imap_mbox_sort_msgno(ImapMboxHandle *handle, ImapSortKey key,
                      int ascending, unsigned int *msgno, unsigned cnt)
 {
+  ImapResponse rc;
   IMAP_REQUIRED_STATE1(handle, IMHS_SELECTED, IMR_BAD);
+
+  HANDLE_LOCK(handle);
   if(imap_mbox_handle_can_do(handle, IMCAP_SORT)) 
-    return imap_mbox_sort_msgno_srv(handle, key, ascending, msgno, cnt);
+    rc = imap_mbox_sort_msgno_srv(handle, key, ascending, msgno, cnt);
   else {
-    return 
-      handle->enable_client_sort
+    rc = handle->enable_client_sort
       ? imap_mbox_sort_msgno_client(handle, key, ascending, msgno, cnt)
       : IMR_NO;
   }
+  HANDLE_UNLOCK(handle);
+  return rc;
 }
 
 static void
@@ -1838,12 +1854,14 @@
   unsigned i;
 
   IMAP_REQUIRED_STATE1(handle, IMHS_SELECTED, IMR_BAD);
+
+  HANDLE_LOCK(handle);
   if(key == IMSO_MSGNO) {
     if(filter) { /* CASE 1a */
       handle->mbox_view.entries = 0; /* FIXME: I do not like this! 
                                       * we should not be doing such 
                                       * low level manipulations here */
-      rc = imap_search_exec(handle, FALSE, filter, append_no, NULL);
+      rc = imap_search_exec_unlocked(handle, FALSE, filter, append_no, NULL);
     } else { /* CASE 1b */
       if(handle->thread_root)
         g_node_destroy(handle->thread_root);
@@ -1857,7 +1875,7 @@
           g_node_prepend_data(handle->thread_root,
                               GUINT_TO_POINTER(i));
       }
-      return IMR_OK;
+      rc = IMR_OK;
     }
   } else { 
     if(imap_mbox_handle_can_do(handle, IMCAP_SORT)) { /* CASE 2a */
@@ -1890,23 +1908,23 @@
       while(rc == IMR_UNTAGGED);
     } else {                                           /* CASE 2b */
       /* try client-side sorting... */
-      if(!handle->enable_client_sort)
-        return IMR_NO;
-      handle->mbox_view.entries = 0; /* FIXME: I do not like this! 
-                                      * we should not be doing such 
-                                      * low level manipulations here */
-      if(filter)
-        rc = imap_search_exec(handle, FALSE, filter, append_no, NULL);
-      else {
-        rc = IMR_OK;
-        for(i=0; i<handle->exists; i++)
-          mbox_view_append_no(&handle->mbox_view, i+1);
-      }
-      if(rc != IMR_OK)
-        return rc;
-      rc = imap_mbox_sort_msgno_client(handle, key, ascending,
-                                       handle->mbox_view.arr,
-                                       handle->mbox_view.entries);
+      if(handle->enable_client_sort) {
+	handle->mbox_view.entries = 0; /* FIXME: I do not like this! 
+					* we should not be doing such 
+					* low level manipulations here */
+	if(filter)
+	  rc = imap_search_exec_unlocked(handle, FALSE, filter,
+					 append_no, NULL);
+	else {
+	  rc = IMR_OK;
+	  for(i=0; i<handle->exists; i++)
+	    mbox_view_append_no(&handle->mbox_view, i+1);
+	}
+	if(rc == IMR_OK)
+	  rc = imap_mbox_sort_msgno_client(handle, key, ascending,
+					   handle->mbox_view.arr,
+					   handle->mbox_view.entries);
+      } else rc = IMR_NO;
     }
   }
   if(rc == IMR_OK) {
@@ -1918,6 +1936,9 @@
       g_node_append_data(handle->thread_root,
                          GUINT_TO_POINTER(handle->mbox_view.arr[i]));
   }
+
+  HANDLE_UNLOCK(handle);
+
   return rc;
 }
 
@@ -1936,8 +1957,8 @@
 {
   ImapResponse res;
   HANDLE_LOCK(handle);
-  res= imap_search_exec(handle, FALSE, filter,
-			(ImapSearchCb)make_msgno_table, msgnos);
+  res = imap_search_exec_unlocked(handle, FALSE, filter,
+				  (ImapSearchCb)make_msgno_table, msgnos);
   HANDLE_UNLOCK(handle);
   return res;
 }

Modified: trunk/libbalsa/imap/imap-handle.c
==============================================================================
--- trunk/libbalsa/imap/imap-handle.c	(original)
+++ trunk/libbalsa/imap/imap-handle.c	Tue Dec 30 17:23:33 2008
@@ -416,6 +416,8 @@
      channel to get disconnected before IDLE gets activated */
   IMAP_REQUIRED_STATE3(h, IMHS_CONNECTED, IMHS_AUTHENTICATED,
                        IMHS_SELECTED, FALSE);
+
+  HANDLE_LOCK(h);
   asyncno = imap_make_tag(tag); sio_write(h->sio, tag, strlen(tag));
   sio_write(h->sio, " IDLE\r\n", 7); sio_flush(h->sio);
   cmdi_add_handler(&h->cmd_info, asyncno, cmdi_empty, NULL);
@@ -425,6 +427,7 @@
   } while (rc == IMR_UNTAGGED);
   if(rc != IMR_RESPOND) {
     g_message("idle_start() expected IMR_RESPOND but got %d\n", rc);
+    HANDLE_UNLOCK(h);
     return FALSE;
   }
   while( (c=sio_getc(h->sio)) != -1 && c != '\n');
@@ -436,9 +439,12 @@
 				     async_process, h);
   h->idle_enable_id = 0;
   h->idle_issued = 1;
+
+  HANDLE_UNLOCK(h);
   return FALSE;
 }
 
+/** Called with handle locked. */
 ImapResponse
 imap_cmd_issue(ImapMboxHandle* h, const char* cmd)
 {
@@ -501,6 +507,7 @@
   return h->op_cancelled;
 }
 
+/** Called with handle locked. */
 void
 imap_handle_disconnect(ImapMboxHandle *h)
 {

Modified: trunk/libbalsa/imap/imap_private.h
==============================================================================
--- trunk/libbalsa/imap/imap_private.h	(original)
+++ trunk/libbalsa/imap/imap_private.h	Tue Dec 30 17:23:33 2008
@@ -175,6 +175,9 @@
 
 ImapResponse imap_write_key(ImapMboxHandle *handle, ImapSearchKey *s,
                             unsigned cmdno, int use_literal);
+ImapResponse imap_search_exec_unlocked(ImapMboxHandle *h, gboolean uid, 
+				       ImapSearchKey *s,
+				       ImapSearchCb cb, void *cb_arg);
 ImapResponse imap_assure_needed_flags(ImapMboxHandle *h,
                                       ImapMsgFlag needed_flags);
 

Modified: trunk/libbalsa/imap/imap_search.c
==============================================================================
--- trunk/libbalsa/imap/imap_search.c	(original)
+++ trunk/libbalsa/imap/imap_search.c	Tue Dec 30 17:23:33 2008
@@ -456,8 +456,8 @@
     (flags) and immutable terms (anything else).
  */
 ImapResponse
-imap_search_exec(ImapMboxHandle *h, gboolean uid, 
-		 ImapSearchKey *s, ImapSearchCb cb, void *cb_arg)
+imap_search_exec_unlocked(ImapMboxHandle *h, gboolean uid, 
+			  ImapSearchKey *s, ImapSearchCb cb, void *cb_arg)
 {
   static const unsigned BODY_TO_SEARCH_AT_ONCE   = 500000;
   static const unsigned HEADER_TO_SEARCH_AT_ONCE = 2000;
@@ -541,6 +541,19 @@
   return ir;
 }
 
+ImapResponse
+imap_search_exec(ImapMboxHandle *h, gboolean uid, 
+		 ImapSearchKey *s, ImapSearchCb cb, void *cb_arg)
+{
+  ImapResponse rc;
+
+  HANDLE_LOCK(h);
+  rc = imap_search_exec_unlocked(h, uid, s, cb, cb_arg);
+  HANDLE_UNLOCK(h);
+
+  return rc;
+}
+
 /* == optimized branch for flag-only searches..  Since we know most of
    the flags most of the time, there is no point in repeating some
    flag-only searches over and over. We just run a search optimized



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