Changeset 2536

Show
Ignore:
Timestamp:
07/31/07 10:21:03
Author:
pvanhoof
Message:

2007-07-31 Philip Van Hoof <pvanhoof@gnome.org>

        • Merging back devel/pvanhoof/sessionwork to trunk/
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r2534 r2536  
     12007-07-31  Philip Van Hoof  <pvanhoof@gnome.org> 
     2 
     3        * Merging back devel/pvanhoof/sessionwork to trunk/ 
     4 
     52007-07-31  Philip Van Hoof  <pvanhoof@gnome.org> 
     6 
     7        * Cleaning up, coding style fixes 
     8        * Review of TnyCamelFolder and TnyCamelStoreAccount 
     9 
     102007-07-30  Philip Van Hoof  <pvanhoof@gnome.org> 
     11 
     12        * Various fixes that make Modest actually work with this 
     13 
    1142007-07-30  Javier Fernandez Garcia-Boente  <jfernandez@igalia.com> 
    215 
     
    2336 
    2437        * Merging the Cond patch from devel/sessionwork 
     38 
     392007-07-29  Philip Van Hoof  <pvanhoof@gnome.org> 
     40 
     41        * The long awaited alert, get_pass and forget_pass now in the mainloop 
     42 
     43        * This was a major API and behaviour change 
     44 
     452007-07-29  Philip Van Hoof  <pvanhoof@gnome.org> 
     46 
     47        * Fixed a race condition when the account was or is connection or not 
     48        yet finished connecting while the connection-status-changed signal was 
     49        already being used. Introduced a new API for this 
     50        * Introduced the tny_account_is_ready API, which indicates when an 
     51        account is not only valid as instance, but also fully registered 
     52        within the system. 
     53        * Implemented some missing implementations in TnyCombinedAccount 
     54 
     55        * This was a major API change 
     56 
     572007-07-27  Philip Van Hoof  <pvanhoof@gnome.org> 
     58 
     59        * Dealing with remotely removed folders 
     60        * The poke status calls are now on the same queue as the other 
     61        operations 
     62        * Rewritten the TnySessionCamel infrastructure that connects accounts 
     63        and sets them up 
     64        * Added support for detecting folder changes to 
     65        TnyGtkFolderStoreTreeModel 
     66        * API change on tny_camel_account_set_online. The last argument is now 
     67        a callback rather than a GError. In the callback you can know about 
     68        when the account got connected and if not, why it failed 
     69 
     70        * Cond locks in the queues of the store accounts while the callbacks 
     71        are happening. This is a significant policy change in locking 
     72        behaviour that should be well tested.  
     73 
     74        * This was a major API change in TnyAccount 
     75 
     762007-07-27  Philip Van Hoof  <pvanhoof@gnome.org> 
     77 
     78        * Branchpoint "devel/sessionwork" 
    2579 
    26802007-07-26  Philip Van Hoof  <pvanhoof@gnome.org> 
  • trunk/bindings/python/tinymailmodule.c

    r643 r2536  
    22  
    33void pytinymail_register_classes (PyObject *d);  
    4 void pytinymail_add_constants(PyObject *module, const gchar *strip_prefix); 
     4/*void pytinymail_add_constants(PyObject *module, const gchar *strip_prefix);*/ 
    55extern PyMethodDef pytinymail_functions[]; 
    66 
     
    1616  
    1717    pytinymail_register_classes (d); 
    18     pytinymail_add_constants (m, "TNY_"); 
     18    /*pytinymail_add_constants (m, "TNY_");*/ 
    1919        
    2020    if (PyErr_Occurred ()) { 
  • trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c

    r2443 r2536  
    10071007{ 
    10081008        int len = strlen (type), i; 
    1009         char *resp
    1010          
     1009        char *resp = NULL
     1010 
    10111011        len = strlen (type); 
    10121012         
  • trunk/libtinymail-camel/tny-camel-account-priv.h

    r2412 r2536  
    6868        GList *chooks; 
    6969        TnyConnectionStatus status; 
    70         gboolean is_connecting
     70        gboolean is_connecting, is_ready
    7171}; 
    7272 
  • trunk/libtinymail-camel/tny-camel-account.c

    r2484 r2536  
    697697        priv->session = session; 
    698698 
    699         _tny_session_camel_add_account_1 (session, self); 
     699        _tny_session_camel_register_account (session, self); 
    700700 
    701701        TNY_CAMEL_ACCOUNT_GET_CLASS (self)->prepare_func (self, FALSE, FALSE); 
     
    887887 
    888888        if (priv->session) 
    889                 _tny_session_camel_add_account_2 (priv->session, TNY_CAMEL_ACCOUNT (self)); 
     889                _tny_session_camel_activate_account (priv->session, TNY_CAMEL_ACCOUNT (self)); 
    890890 
    891891        g_static_rec_mutex_unlock (priv->service_lock); 
     
    11221122        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
    11231123 
     1124        priv->is_ready = FALSE; 
    11241125        priv->is_connecting = FALSE; 
    11251126        priv->in_auth = FALSE; 
     
    11601161} 
    11611162 
    1162 /** 
    1163  * tny_camel_account_set_online: 
    1164  * @self: a #TnyCamelAccount object 
    1165  * @online: whether or not the account is online 
    1166  * @err: a #GError instance or NULL 
    1167  * 
    1168  * Set the connectivity status of an account. 
    1169  * Setting this to FALSE means that the account will not attempt to use the network,  
    1170  * and will use only the cache. 
    1171  * Setting this to TRUE means that the account may use the network to provide up-to-date  
    1172  * information. 
    1173  * 
    1174  **/ 
    1175 void  
    1176 tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err) 
    1177 
    1178         TNY_CAMEL_ACCOUNT_GET_CLASS (self)->set_online_func (self, online, err); 
    1179 
     1163/* The is the protected version that will actually set it online. This should 
     1164 * always happen in a thread. In fact, it will always happen in the operations 
     1165 * queue of @self (else it's a bug). */ 
    11801166 
    11811167void  
     
    13221308 
    13231309 
    1324 typedef struct { 
    1325         TnyCamelAccount *self; 
    1326         gboolean online; 
    1327         GError **err; 
    1328         GMainLoop *loop; 
    1329 } SetOnlineInfo; 
    1330  
    1331 static gpointer 
    1332 set_online_thread (gpointer data) 
    1333 
    1334         SetOnlineInfo *info = (SetOnlineInfo *) data; 
    1335  
    1336         _tny_camel_account_set_online (info->self, info->online, info->err); 
    1337  
    1338         if (g_main_loop_is_running (info->loop)) 
    1339                 g_main_loop_quit (info->loop); 
    1340  
    1341         g_thread_exit (NULL); 
    1342         return NULL; 
    1343 
    1344  
     1310 
     1311 
     1312 
     1313/** 
     1314 * tny_camel_account_set_online: 
     1315 * @self: a #TnyCamelAccount object 
     1316 * @online: whether or not the account is online 
     1317 * @callback: a callback when the account went online 
     1318 * 
     1319 * Set the connectivity status of an account. Setting this to FALSE means that  
     1320 * the account will not attempt to use the network, and will use only the cache. 
     1321 * Setting this to TRUE means that the account may use the network to  
     1322 * provide up-to-date information. 
     1323 * 
     1324 * The @callback will be invoke as soon as the account is actually online. It's 
     1325 * guaranteed that the @callback will happen in the mainloop, if available. 
     1326 * 
     1327 **/ 
    13451328void  
    1346 tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, GError **err) 
    1347 
    1348         if (g_main_depth () != 0) 
    1349         { 
    1350                 /* We are being called from the mainnloop */ 
    1351                 SetOnlineInfo *info = g_slice_new (SetOnlineInfo); 
    1352                 GThread *thread = NULL; 
    1353  
    1354                 info->self = TNY_CAMEL_ACCOUNT (g_object_ref (self)); 
    1355                 info->online = online; 
    1356                 info->err = err; 
    1357                 info->loop = g_main_loop_new (NULL, FALSE); 
    1358  
    1359                 thread = g_thread_create (set_online_thread, info, TRUE, NULL); 
    1360  
    1361                 g_main_loop_run (info->loop); 
    1362  
    1363                 g_main_loop_unref (info->loop); 
    1364                 g_object_unref (info->self); 
    1365                 g_slice_free (SetOnlineInfo, info); 
    1366  
    1367         } else 
    1368                 _tny_camel_account_set_online (self, online, err); 
    1369 
    1370  
     1329tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback) 
     1330
     1331        TNY_CAMEL_ACCOUNT_GET_CLASS (self)->set_online_func (self, online, callback); 
     1332
     1333 
     1334typedef struct 
     1335
     1336        TnyCamelAccount *account; 
     1337        GError *err; 
     1338        TnyCamelSetOnlineCallback callback; 
     1339 
     1340        GCond* condition; 
     1341        gboolean had_callback; 
     1342        GMutex *mutex; 
     1343 
     1344} OnSetOnlineInfo; 
     1345 
     1346gboolean  
     1347on_set_online_done_idle_func (gpointer data) 
     1348
     1349        OnSetOnlineInfo *info = (OnSetOnlineInfo *) data; 
     1350        if (info->callback) 
     1351                info->callback (info->account, info->err); 
     1352        return FALSE; 
     1353
     1354 
     1355static void  
     1356on_set_online_done_destroy_func (gpointer data) 
     1357
     1358        OnSetOnlineInfo *info = (OnSetOnlineInfo *) data; 
     1359 
     1360        /* We copied it, so we must also free it */ 
     1361        if (info->err) 
     1362                g_error_free (info->err); 
     1363 
     1364        /* Thread reference */ 
     1365        g_object_unref (info->account); 
     1366 
     1367        if (info->condition) { 
     1368                g_mutex_lock (info->mutex); 
     1369                g_cond_broadcast (info->condition); 
     1370                info->had_callback = TRUE; 
     1371                g_mutex_unlock (info->mutex); 
     1372        } 
     1373 
     1374        return; 
     1375
     1376 
     1377/** 
     1378 * When using a #GMainLoop this method will execute a callback using 
     1379 * g_idle_add_full.  Note that without a #GMainLoop, the callbacks 
     1380 * could happen in a worker thread (depends on who call it) at an 
     1381 * unknown moment in time (check your locking in this case). 
     1382 */ 
     1383static void 
     1384execute_callback (gint depth,  
     1385                  gint priority, 
     1386                  GSourceFunc idle_func, 
     1387                  gpointer data,  
     1388                  GDestroyNotify destroy_func) 
     1389
     1390        if (depth > 0){ 
     1391                g_idle_add_full (priority, idle_func, data, destroy_func); 
     1392        } else { 
     1393                idle_func (data); 
     1394                destroy_func (data); 
     1395        } 
     1396
     1397 
     1398static void  
     1399on_set_online_done (TnySessionCamel *self, TnyCamelAccount *account, GError *err, gpointer user_data) 
     1400
     1401        OnSetOnlineInfo *info = g_slice_new (OnSetOnlineInfo); 
     1402 
     1403        /* Thread reference */ 
     1404        info->account = TNY_CAMEL_ACCOUNT (g_object_ref (account)); 
     1405 
     1406        /* We must copy the err because this context will destroy it! */ 
     1407        if (err) 
     1408                info->err = g_error_copy (err);  
     1409        else 
     1410                info->err = NULL; 
     1411 
     1412        info->callback = (TnyCamelSetOnlineCallback) user_data; 
     1413 
     1414        info->mutex = g_mutex_new (); 
     1415        info->condition = g_cond_new (); 
     1416        info->had_callback = FALSE; 
     1417 
     1418        execute_callback (/* info->depth */ 10, G_PRIORITY_HIGH,  
     1419                on_set_online_done_idle_func,  
     1420                info, on_set_online_done_destroy_func); 
     1421 
     1422        /* Wait on the queue for the mainloop callback to be finished */ 
     1423        g_mutex_lock (info->mutex); 
     1424        if (!info->had_callback) 
     1425                g_cond_wait (info->condition, info->mutex); 
     1426        g_mutex_unlock (info->mutex); 
     1427 
     1428        g_mutex_free (info->mutex); 
     1429        g_cond_free (info->condition); 
     1430 
     1431        g_slice_free (OnSetOnlineInfo, info); 
     1432 
     1433        return; 
     1434
     1435 
     1436void  
     1437tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback) 
     1438
     1439 
     1440        /* In case we  are a store account, this means that we need to throw the  
     1441         * request to go online to the account's queue. */ 
     1442 
     1443        if (TNY_IS_CAMEL_STORE_ACCOUNT (self)) 
     1444        { 
     1445                TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     1446                TnySessionCamel *session = priv->session; 
     1447 
     1448                _tny_camel_store_account_queue_going_online ( 
     1449                        TNY_CAMEL_STORE_ACCOUNT (self), session, online,  
     1450                        on_set_online_done, (gpointer) callback); 
     1451        } 
     1452 
     1453 
     1454        /* Else, if it's a transport account, we don't have any transport  
     1455         * account implementations that actually need to go online at this  
     1456         * moment yet. At the moment of transferring the first message, the 
     1457         * current implementations will automatically connect themselves. */ 
     1458 
     1459        if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (self)) 
     1460        { 
     1461                g_signal_emit (self,  
     1462                        tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online); 
     1463                return; 
     1464        } 
     1465
     1466 
     1467static gboolean 
     1468tny_camel_account_is_ready (TnyAccount *self) 
     1469
     1470        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     1471        return priv->is_ready; 
     1472
    13711473 
    13721474static void 
     
    13881490 
    13891491        if (priv->session) { 
    1390                 _tny_session_camel_forget_account (priv->session, (TnyCamelAccount*) object);     
     1492                _tny_session_camel_unregister_account (priv->session, (TnyCamelAccount*) object);     
    13911493                camel_object_unref (priv->session); 
    13921494        } 
     
    14811583        klass->start_operation_func = tny_camel_account_start_operation; 
    14821584        klass->stop_operation_func =  tny_camel_account_stop_operation; 
     1585        klass->is_ready_func = tny_camel_account_is_ready; 
    14831586 
    14841587        return; 
     
    16691772                } 
    16701773                 
    1671                 iter = g_list_next (iter);      
     1774                iter = g_list_next (iter); 
    16721775        } 
    16731776        g_list_free (authtypes); 
     
    17411844{  
    17421845        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     1846        GetSupportedAuthInfo *info = NULL; 
     1847 
    17431848        g_return_if_fail (callback); 
    17441849        g_return_if_fail (priv->session); 
     
    17651870 
    17661871        /* Idle info for the status callback: */ 
    1767         GetSupportedAuthInfo *info = g_slice_new (GetSupportedAuthInfo); 
     1872        info = g_slice_new (GetSupportedAuthInfo); 
    17681873        info->session = priv->session; 
    17691874        info->err = NULL; 
  • trunk/libtinymail-camel/tny-camel-account.h

    r2352 r2536  
    4848extern guint tny_camel_account_signals [TNY_CAMEL_ACCOUNT_LAST_SIGNAL]; 
    4949 
     50typedef void (*TnyCamelSetOnlineCallback) (TnyCamelAccount *account, GError *err); 
     51 
    5052 
    5153struct _TnyCamelAccount 
     
    8991 
    9092        void (*add_option_func) (TnyCamelAccount *self, const gchar *option); 
    91         void (*set_online_func) (TnyCamelAccount *self, gboolean online, GError **err); 
     93        void (*set_online_func) (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback); 
    9294 
    9395        /* Abstract methods */ 
     
    103105void tny_camel_account_add_option (TnyCamelAccount *self, const gchar *option); 
    104106void tny_camel_account_set_session (TnyCamelAccount *self, TnySessionCamel *session); 
    105 void tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err); 
     107void tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback); 
    106108 
    107109 
  • trunk/libtinymail-camel/tny-camel-folder.c

    r2530 r2536  
    515515        gboolean haderr = FALSE; 
    516516 
    517         g_assert (TNY_IS_CAMEL_MSG (msg)); 
    518  
    519         if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err,  
    520                         TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_ADD_MSG)) 
     517        if (!TNY_IS_CAMEL_MSG (msg)) 
     518        { 
     519                g_critical ("You must not use a non-TnyCamelMsg implementation " 
     520                        "of TnyMsg with TnyCamelFolder types. This indicates a " 
     521                        "problem in the software (unsupported operation)\n"); 
     522                g_assert (TNY_IS_CAMEL_MSG (msg)); 
     523        } 
     524 
     525        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
     526                        priv->account, err, TNY_FOLDER_ERROR,  
     527                        TNY_FOLDER_ERROR_ADD_MSG)) 
    521528                return; 
    522529 
     
    539546                gint a = 0, len = 0, nlen = 0; 
    540547                CamelException ex2 = CAMEL_EXCEPTION_INITIALISER; 
     548 
    541549                len = priv->folder->summary->messages->len; 
    542550                dst_orig_uids = g_ptr_array_sized_new (len); 
    543                 for (a = 0; a < len; a++) { 
    544                         CamelMessageInfo *om = camel_folder_summary_index (priv->folder->summary, a); 
     551 
     552                for (a = 0; a < len; a++)  
     553                { 
     554                        CamelMessageInfo *om =  
     555                                camel_folder_summary_index (priv->folder->summary, a); 
    545556                        if (om && om->uid) 
    546557                                g_ptr_array_add (dst_orig_uids, g_strdup (om->uid)); 
     
    548559                                camel_message_info_free (om); 
    549560                } 
    550          
     561 
    551562                camel_folder_append_message (priv->folder, message, NULL, NULL, &ex); 
    552563                priv->unread_length = camel_folder_get_unread_message_count (priv->folder); 
     
    558569                for (a = 0; a < nlen; a++)  
    559570                { 
    560                         CamelMessageInfo *om = camel_folder_summary_index (priv->folder->summary, a); 
    561                         if (om && om->uid) { 
     571                        CamelMessageInfo *om =  
     572                                camel_folder_summary_index (priv->folder->summary, a); 
     573 
     574                        if (om && om->uid)  
     575                        { 
    562576                                gint b = 0; 
    563577                                gboolean found = FALSE; 
     
    649663        g_assert (TNY_IS_HEADER (header)); 
    650664 
    651         if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err,  
    652                         TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REMOVE_MSG)) 
     665        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
     666                        priv->account, err, TNY_FOLDER_ERROR,  
     667                        TNY_FOLDER_ERROR_REMOVE_MSG)) 
    653668                return; 
    654669 
     
    670685        tny_msg_remove_strategy_perform_remove (priv->remove_strat, self, header, err); 
    671686 
    672  
    673687        /* Notify about unread count */ 
    674688        _tny_camel_folder_check_unread_count (TNY_CAMEL_FOLDER (self)); 
     
    796810        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    797811        priv->cached_length = len; 
    798  
    799812        return; 
    800813} 
     
    806819        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    807820        priv->local_size = len; 
    808  
    809821        return; 
    810822} 
     
    820832{ 
    821833        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    822  
    823834        return priv->cached_length; 
    824835} 
     
    835846{ 
    836847        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    837  
    838848        return TNY_ACCOUNT (g_object_ref (priv->account)); 
    839849} 
     
    852862} 
    853863 
    854 /** 
    855  * When using a #GMainLoop this method will execute a callback using 
     864/* When using a #GMainLoop this method will execute a callback using 
    856865 * g_idle_add_full.  Note that without a #GMainLoop, the callbacks 
    857866 * could happen in a worker thread (depends on who call it) at an 
    858  * unknown moment in time (check your locking in this case). 
    859  */ 
     867 * unknown moment in time (check your locking in this case). */ 
     868 
    860869static void 
    861870execute_callback (gint depth,  
     
    888897        CamelException ex = CAMEL_EXCEPTION_INITIALISER; 
    889898 
    890         if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err,  
    891                         TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_SYNC)) 
     899        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
     900                        priv->account, err, TNY_FOLDER_ERROR,  
     901                        TNY_FOLDER_ERROR_SYNC)) 
    892902                return; 
    893903 
     
    949959        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    950960 
     961        /* thread reference */ 
    951962        _tny_camel_folder_unreason (priv); 
    952  
    953         /* thread reference */ 
    954963        g_object_unref (G_OBJECT (self)); 
     964 
    955965        if (info->err) 
    956966                g_error_free (info->err); 
     
    961971        info->stopper = NULL; 
    962972 
    963         g_mutex_lock (info->mutex); 
    964         g_cond_broadcast (info->condition); 
    965         info->had_callback = TRUE; 
    966         g_mutex_unlock (info->mutex); 
     973        if (info->condition) { 
     974                g_mutex_lock (info->mutex); 
     975                g_cond_broadcast (info->condition); 
     976                info->had_callback = TRUE; 
     977                g_mutex_unlock (info->mutex); 
     978        } 
    967979 
    968980        return; 
     
    976988        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    977989        TnyFolderChange *change = tny_folder_change_new (self); 
    978  
    979         if (info->callback) 
    980                 info->callback (info->self, info->cancelled, &info->err, info->user_data); 
    981  
    982         tny_idle_stopper_stop (info->stopper); 
    983990 
    984991        tny_folder_change_set_new_all_count (change, priv->cached_length); 
     
    987994        g_object_unref (change); 
    988995 
     996        if (info->callback) 
     997                info->callback (info->self, info->cancelled, &info->err, info->user_data); 
     998 
     999        tny_idle_stopper_stop (info->stopper); 
     1000 
    9891001        return FALSE; 
    9901002} 
     
    10241036        { 
    10251037                tny_camel_folder_sync_async_destroyer (info); 
     1038                g_slice_free (SyncFolderInfo, thr_user_data); 
    10261039                g_static_rec_mutex_unlock (priv->folder_lock); 
    10271040                return NULL; 
     
    10681081                          tny_camel_folder_sync_async_destroyer); 
    10691082 
     1083 
    10701084        /* Wait on the queue for the mainloop callback to be finished */ 
    10711085        g_mutex_lock (info->mutex); 
     
    10861100{ 
    10871101        SyncFolderInfo *info = thr_user_data; 
    1088  
    10891102        g_error_free (info->err); 
    10901103        g_object_unref (info->self); 
    10911104        g_slice_free (SyncFolderInfo, thr_user_data); 
     1105        return; 
    10921106} 
    10931107 
     
    10961110{ 
    10971111        SyncFolderInfo *info = thr_user_data; 
    1098  
    10991112        if (info->callback) 
    11001113                info->callback (info->self, TRUE, &info->err, info->user_data); 
    1101  
    11021114        return FALSE; 
    11031115} 
     1116 
    11041117void  
    11051118tny_camel_folder_sync_async_default (TnyFolder *self, gboolean expunge, TnySyncFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
     
    11191132        info->depth = g_main_depth (); 
    11201133        info->expunge = expunge; 
     1134        info->condition = NULL; 
    11211135 
    11221136        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,  
     
    11261140                        info->err = g_error_copy (err); 
    11271141                        g_object_ref (info->self); 
    1128  
    11291142                        execute_callback (info->depth, G_PRIORITY_DEFAULT, 
    11301143                                          tny_camel_folder_sync_async_cancelled_callback, info,  
     
    11381151 
    11391152        /* thread reference */ 
    1140         g_object_ref (G_OBJECT (self)); 
     1153        g_object_ref (info->self); 
    11411154        _tny_camel_folder_reason (priv); 
    11421155 
     
    11591172        gpointer user_data; 
    11601173        gboolean cancelled; 
    1161         /* This stops us from calling a status callback after the operation has  
    1162          * finished. */ 
    11631174        TnyIdleStopper* stopper; 
    11641175        guint depth; 
     
    11741185 
    11751186/** This is the GDestroyNotify callback provided to g_idle_add_full() 
    1176  * for tny_camel_folder_refresh_async_callback(). 
    1177  */ 
     1187 * for tny_camel_folder_refresh_async_callback().*/ 
     1188 
    11781189static void 
    11791190tny_camel_folder_refresh_async_destroyer (gpointer thr_user_data) 
     
    11831194        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    11841195 
     1196        /* thread reference */ 
    11851197        _tny_camel_folder_unreason (priv); 
    1186  
    1187         /* thread reference */ 
    11881198        g_object_unref (G_OBJECT (self)); 
     1199 
    11891200        if (info->err) 
    11901201                g_error_free (info->err); 
     
    11951206        info->stopper = NULL; 
    11961207 
    1197         g_mutex_lock (info->mutex); 
    1198         g_cond_broadcast (info->condition); 
    1199         info->had_callback = TRUE; 
    1200         g_mutex_unlock (info->mutex); 
     1208        if (info->condition) { 
     1209                g_mutex_lock (info->mutex); 
     1210                g_cond_broadcast (info->condition); 
     1211                info->had_callback = TRUE; 
     1212                g_mutex_unlock (info->mutex); 
     1213        } 
    12011214 
    12021215        return; 
     
    12101223        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    12111224        TnyFolderChange *change = tny_folder_change_new (self); 
    1212  
    1213         if (info->callback) 
    1214                 info->callback (info->self, info->cancelled, &info->err, info->user_data); 
    1215  
    1216         /* Prevent status callbacks from being called after this 
    1217          * (can happen because the 2 idle callbacks have different priorities) 
    1218          * by causing tny_idle_stopper_is_stopped() to return TRUE. */ 
    1219         tny_idle_stopper_stop (info->stopper); 
    12201225 
    12211226        tny_folder_change_set_new_all_count (change, priv->cached_length); 
     
    12241229        g_object_unref (change); 
    12251230 
     1231        if (info->callback) 
     1232                info->callback (info->self, info->cancelled, &info->err, info->user_data); 
     1233 
     1234        /* Prevent status callbacks from being called after this 
     1235         * (can happen because the 2 idle callbacks have different priorities) 
     1236         * by causing tny_idle_stopper_is_stopped() to return TRUE. */ 
     1237 
     1238        tny_idle_stopper_stop (info->stopper); 
     1239 
    12261240        return FALSE; 
    12271241} 
     
    12611275        { 
    12621276                tny_camel_folder_refresh_async_destroyer (info); 
     1277                g_slice_free (RefreshFolderInfo, info); 
    12631278                g_static_rec_mutex_unlock (priv->folder_lock); 
    12641279                return NULL; 
     
    13001315        info->had_callback = FALSE; 
    13011316 
    1302         if (info->callback) 
    1303         { 
    1304                 execute_callback (info->depth, G_PRIORITY_DEFAULT,  
    1305                                   tny_camel_folder_refresh_async_callback, info,  
    1306                                   tny_camel_folder_refresh_async_destroyer); 
    1307         } else { /* Thread reference */ 
    1308                 g_object_unref (G_OBJECT (self)); 
    1309                 _tny_camel_folder_unreason (priv); 
    1310         } 
     1317        execute_callback (info->depth, G_PRIORITY_DEFAULT,  
     1318                          tny_camel_folder_refresh_async_callback, info,  
     1319                          tny_camel_folder_refresh_async_destroyer); 
    13111320 
    13121321        /* Wait on the queue for the mainloop callback to be finished */ 
     
    13341343{ 
    13351344        RefreshFolderInfo *info = thr_user_data; 
    1336  
    13371345        g_error_free (info->err); 
    13381346        g_object_unref (info->self); 
    13391347        g_slice_free (RefreshFolderInfo, thr_user_data); 
     1348        return; 
    13401349} 
    13411350 
     
    13441353{ 
    13451354        RefreshFolderInfo *info = thr_user_data; 
    1346  
    13471355        if (info->callback) 
    13481356                info->callback (info->self, TRUE, &info->err, info->user_data); 
    1349  
    13501357        return FALSE; 
    13511358} 
     
    13651372 * become zero while doing stuff on the instance in the background, don't you? 
    13661373 **/ 
     1374 
    13671375static void 
    13681376tny_camel_folder_refresh_async_default (TnyFolder *self, TnyRefreshFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
     
    13811389        info->user_data = user_data; 
    13821390        info->depth = g_main_depth (); 
     1391        info->condition = NULL; 
    13831392 
    13841393        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,  
     
    13881397                        info->err = g_error_copy (err); 
    13891398                        g_object_ref (info->self); 
    1390  
    13911399                        execute_callback (info->depth, G_PRIORITY_DEFAULT, 
    13921400                                          tny_camel_folder_refresh_async_cancelled_callback, info,  
     
    14321440        TnyFolderChange *change = NULL; 
    14331441 
    1434         if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err,  
    1435                         TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH)) 
     1442        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
     1443                        priv->account, err, TNY_FOLDER_ERROR,  
     1444                        TNY_FOLDER_ERROR_REFRESH)) 
    14361445                return; 
    14371446 
     
    14451454        } 
    14461455 
    1447         /*_tny_camel_account_start_camel_operation (TNY_CAMEL_ACCOUNT (priv->account),  
    1448                 NULL, NULL, NULL); */ 
    1449  
    14501456        oldlen = priv->cached_length; 
    14511457        oldurlen = priv->unread_length; 
     
    14541460        camel_folder_refresh_info (priv->folder, &ex); 
    14551461        priv->want_changes = TRUE; 
    1456  
    1457         /* _tny_camel_account_stop_camel_operation (TNY_CAMEL_ACCOUNT (priv->account)); */ 
    14581462 
    14591463        priv->cached_length = camel_folder_get_message_count (priv->folder);     
     
    14611465                priv->unread_length = (guint) camel_folder_get_unread_message_count (priv->folder); 
    14621466        update_iter_counts (priv); 
    1463  
    14641467 
    14651468        if (camel_exception_is_set (&ex)) 
     
    15071510 
    15081511        header = _tny_camel_header_new (); 
    1509  
    1510         _tny_camel_header_set_folder (TNY_CAMEL_HEADER (header), TNY_CAMEL_FOLDER (self), priv); 
    1511         _tny_camel_header_set_camel_message_info (TNY_CAMEL_HEADER (header), mi, FALSE); 
    1512  
    1513         tny_list_prepend (headers, (GObject*)header); 
    1514  
    1515         g_object_unref (G_OBJECT (header)); 
     1512        _tny_camel_header_set_folder ((TnyCamelHeader *) header, (TnyCamelFolder *) self, priv); 
     1513        _tny_camel_header_set_camel_message_info ((TnyCamelHeader *) header, mi, FALSE); 
     1514        tny_list_prepend (headers, (GObject*) header); 
     1515        g_object_unref (header); 
    15161516 
    15171517        return; 
     
    15381538                return; 
    15391539 
    1540         /* we reason the folder to make sure it does not 
    1541          * lose all the references and uncache, causing an interlock */ 
    1542         _tny_camel_folder_reason (priv); 
    15431540        g_static_rec_mutex_lock (priv->folder_lock); 
    15441541 
     
    15501547        } 
    15511548 
    1552         g_object_ref (G_OBJECT (headers)); 
    1553  
     1549        /* We reason the folder to make sure it does not lose all the references 
     1550         * and uncache, causing an interlock */ 
     1551        _tny_camel_folder_reason (priv); 
     1552 
     1553        g_object_ref (headers); 
    15541554        ptr = g_slice_new (FldAndPriv); 
    15551555        ptr->self = self; 
     
    15771577        g_slice_free (FldAndPriv, ptr); 
    15781578 
    1579         g_object_unref (G_OBJECT (headers)); 
     1579        g_object_unref (headers); 
     1580 
    15801581        g_static_rec_mutex_unlock (priv->folder_lock); 
    15811582        _tny_camel_folder_unreason (priv); 
     
    16131614{ 
    16141615        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
     1616        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
     1617 
     1618        /* thread reference */ 
     1619        _tny_camel_folder_unreason (priv); 
     1620        g_object_unref (info->self); 
     1621 
     1622          if (info->err) 
     1623                g_error_free (info->err); 
     1624 
     1625        _tny_session_stop_operation (info->session); 
     1626 
     1627        tny_idle_stopper_destroy (info->stopper); 
     1628        info->stopper = NULL; 
     1629 
     1630        if (info->condition) { 
     1631                g_mutex_lock (info->mutex); 
     1632                g_cond_broadcast (info->condition); 
     1633                info->had_callback = TRUE; 
     1634                g_mutex_unlock (info->mutex); 
     1635        } 
     1636 
     1637        return; 
     1638} 
     1639 
     1640 
     1641static gboolean 
     1642tny_camel_folder_get_msg_async_callback (gpointer thr_user_data) 
     1643{ 
     1644        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
    16151645        TnyFolderChange *change; 
    16161646        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
     
    16251655        } 
    16261656 
    1627         /* thread reference */ 
    1628         _tny_camel_folder_unreason (priv); 
    1629         g_object_unref (info->self); 
    1630  
    1631           if (info->err) 
    1632                 g_error_free (info->err); 
    1633  
    1634         _tny_session_stop_operation (info->session); 
    1635  
    1636         tny_idle_stopper_destroy (info->stopper); 
    1637         info->stopper = NULL; 
    1638  
    1639         g_mutex_lock (info->mutex); 
    1640