Changeset 2553

Show
Ignore:
Timestamp:
08/06/07 10:14:38
Author:
pvanhoof
Message:

2007-08-06 Philip Van Hoof <pvanhoof@gnome.org>

        • GDK lock awareness
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r2548 r2553  
     12007-08-06  Philip Van Hoof  <pvanhoof@gnome.org> 
     2 
     3        * GDK lock awareness 
     4 
    152007-08-02  Philip Van Hoof  <pvanhoof@gnome.org> 
    26 
  • trunk/libtinymail-camel/camel-lite/camel/camel-folder-summary.c

    r2547 r2553  
    32073207        g_return_if_fail(mi != NULL); 
    32083208 
    3209         if (mi->summary) { 
     3209        if (mi->summary)  
     3210        { 
    32103211                CAMEL_SUMMARY_LOCK(mi->summary, ref_lock); 
    32113212 
  • trunk/libtinymail-camel/tny-camel-account.c

    r2548 r2553  
    7070        TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
    7171 
     72        tny_lockable_lock (apriv->session->priv->ui_lock); 
    7273        g_signal_emit (G_OBJECT (self),  
    7374                tny_account_signals [TNY_ACCOUNT_CHANGED], 0); 
     75        tny_lockable_unlock (apriv->session->priv->ui_lock); 
    7476 
    7577        return FALSE; 
     
    625627        RefreshStatusInfo *oinfo = user_data; 
    626628        TnyProgressInfo *info = NULL; 
     629        TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (oinfo->self); 
    627630 
    628631        info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,  
    629632                oinfo->domain, oinfo->code, what, sofar,  
    630                 oftotal, oinfo->stopper, oinfo->user_data); 
     633                oftotal, oinfo->stopper, apriv->session->priv->ui_lock, oinfo->user_data); 
    631634 
    632635        if (oinfo->depth > 0) 
     
    12211224 * queue of @self (else it's a bug). */ 
    12221225 
     1226typedef struct { 
     1227        TnySessionCamel *session; 
     1228        TnyAccount *account; 
     1229        gboolean online; 
     1230} SetOnlInfo; 
     1231 
     1232 
     1233static gboolean 
     1234set_online_happened_idle (gpointer user_data) 
     1235{ 
     1236        SetOnlInfo *info = (SetOnlInfo *) user_data; 
     1237        tny_lockable_lock (info->session->priv->ui_lock); 
     1238        g_signal_emit (info->account,  
     1239                tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED],  
     1240                0, info->online); 
     1241        tny_lockable_unlock (info->session->priv->ui_lock); 
     1242        return FALSE; 
     1243} 
     1244 
     1245static void 
     1246set_online_happened_destroy (gpointer user_data) 
     1247{ 
     1248        SetOnlInfo *info = (SetOnlInfo *) user_data; 
     1249        camel_object_unref (info->session); 
     1250        g_object_unref (info->account); 
     1251        g_slice_free (SetOnlInfo, info); 
     1252        return; 
     1253} 
     1254 
     1255static void 
     1256set_online_happened (TnySessionCamel *session, TnyCamelAccount *account, gboolean online) 
     1257{ 
     1258        SetOnlInfo *info = g_slice_new (SetOnlInfo); 
     1259 
     1260        info->session = session; 
     1261        camel_object_ref (info->session); 
     1262        info->account = TNY_ACCOUNT (g_object_ref (account)); 
     1263        info->online = online; 
     1264 
     1265        g_idle_add_full (G_PRIORITY_DEFAULT, set_online_happened_idle,  
     1266                info, set_online_happened_destroy); 
     1267 
     1268        return; 
     1269} 
     1270 
     1271 
    12231272void  
    12241273_tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err) 
     
    12691318 
    12701319                        if (!camel_exception_is_set (&ex)) 
    1271                                 g_signal_emit (self,  
    1272                                         tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, TRUE); 
     1320                                set_online_happened (priv->session, self, TRUE); 
    12731321 
    12741322                        goto done; 
     
    13091357 
    13101358                        if (!camel_exception_is_set (&ex)) 
    1311                                 g_signal_emit (self,  
    1312                                         tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, TRUE); 
     1359                                set_online_happened (priv->session, self, TRUE); 
    13131360 
    13141361                        goto done; 
     
    13461393 
    13471394                if (!camel_exception_is_set (&ex)) 
    1348                         g_signal_emit (self,  
    1349                                 tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, FALSE); 
     1395                        set_online_happened (priv->session, self, FALSE); 
    13501396 
    13511397        } 
     
    14041450{ 
    14051451        OnSetOnlineInfo *info = (OnSetOnlineInfo *) data; 
    1406         if (info->callback) 
     1452        TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (info->account); 
     1453        TnySessionCamel *session = apriv->session; 
     1454 
     1455        if (info->callback) { 
     1456                tny_lockable_lock (session->priv->ui_lock); 
    14071457                info->callback (info->account, info->err); 
     1458                tny_lockable_unlock (session->priv->ui_lock); 
     1459        } 
    14081460        return FALSE; 
    14091461} 
     
    14931545tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback) 
    14941546{ 
     1547        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     1548        TnySessionCamel *session = priv->session; 
    14951549 
    14961550        /* In case we  are a store account, this means that we need to throw the  
     
    14981552 
    14991553        if (TNY_IS_CAMEL_STORE_ACCOUNT (self)) 
    1500         { 
    1501                 TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
    1502                 TnySessionCamel *session = priv->session; 
    1503  
    15041554                _tny_camel_store_account_queue_going_online ( 
    15051555                        TNY_CAMEL_STORE_ACCOUNT (self), session, online,  
    15061556                        on_set_online_done, (gpointer) callback); 
    1507         } 
    15081557 
    15091558 
     
    15141563 
    15151564        if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (self)) 
    1516         { 
    1517                 g_signal_emit (self,  
    1518                         tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online); 
    1519                 return; 
    1520         } 
     1565                set_online_happened (session, self, online); 
    15211566} 
    15221567 
     
    17751820        gboolean cancelled; 
    17761821        TnyList *result; 
    1777         /* This stops us from calling a status callback after the operation has  
    1778          * finished. */ 
    17791822        TnyIdleStopper* stopper; 
    17801823        GError *err; 
    17811824        TnySessionCamel *session; 
     1825 
     1826        GCond* condition; 
     1827        gboolean had_callback; 
     1828        GMutex *mutex; 
     1829 
    17821830} GetSupportedAuthInfo; 
     1831 
     1832 
     1833static gboolean  
     1834on_supauth_idle_func (gpointer user_data) 
     1835{ 
     1836        GetSupportedAuthInfo *info = (GetSupportedAuthInfo *) user_data; 
     1837 
     1838        if (info->callback) { 
     1839                tny_lockable_lock (info->session->priv->ui_lock); 
     1840                info->callback (info->self, info->cancelled, info->result, &info->err, info->user_data); 
     1841                tny_lockable_unlock (info->session->priv->ui_lock); 
     1842        } 
     1843 
     1844        tny_idle_stopper_stop (info->stopper); 
     1845} 
     1846 
     1847static void  
     1848on_supauth_destroy_func (gpointer user_data) 
     1849{ 
     1850        GetSupportedAuthInfo *info = (GetSupportedAuthInfo *) user_data; 
     1851 
     1852        /* Thread reference */ 
     1853        g_object_unref (info->self); 
     1854        camel_object_ref (info->session); 
     1855 
     1856        /* Result reference */ 
     1857        if (info->result) 
     1858                g_object_unref (info->result); 
     1859 
     1860        tny_idle_stopper_destroy (info->stopper); 
     1861        info->stopper = NULL; 
     1862 
     1863        if (info->condition) { 
     1864                g_mutex_lock (info->mutex); 
     1865                g_cond_broadcast (info->condition); 
     1866                info->had_callback = TRUE; 
     1867                g_mutex_unlock (info->mutex); 
     1868        } 
     1869} 
    17831870 
    17841871/* Starts the operation in the thread: */ 
     
    17931880        GError *err = NULL; 
    17941881        TnyStatus* status; 
     1882        GList *authtypes = NULL; 
     1883        TnyList *result = NULL; 
     1884        GList *iter = NULL; 
    17951885 
    17961886        g_static_rec_mutex_lock (priv->service_lock); 
     
    18001890                "Get secure authentication methods"); 
    18011891 
    1802         info->status_callback(G_OBJECT(self),  
    1803                 status, info->user_data); 
    1804    
    1805         /* Do the actual work: 
    1806          * This is happening in a thread,  
    1807          * and the status callback is being called regularly while this is  
    1808          * happening. */         
    1809         GList *authtypes = camel_service_query_auth_types (priv->service, &ex); 
    1810  
    1811         tny_status_set_fraction(status, 1); 
    1812         info->status_callback(G_OBJECT(self),  
    1813                 status, info->user_data); 
    1814  
    1815         /* The result will be a TnyList of TnyPairs: */ 
    1816         TnyList *result = tny_simple_list_new (); 
    1817         GList *iter = authtypes; 
    1818         while (iter) { 
     1892        authtypes = camel_service_query_auth_types (priv->service, &ex); 
     1893        /* Result reference */ 
     1894        result = tny_simple_list_new (); 
     1895        iter = authtypes; 
     1896 
     1897        while (iter)  
     1898        { 
    18191899                CamelServiceAuthType *item = (CamelServiceAuthType *)iter->data; 
    18201900                if (item) { 
    1821                         /* Get the name of the auth method: 
    1822                          * Note that, at least for IMAP, authproto=NULL when  
    1823                          * name=Password. */ 
    1824  
    1825                         /* We don't use the value part of the TnyPair. */ 
    18261901                        TnyPair *pair = tny_pair_new (item->name, NULL); 
    18271902                        tny_list_append (result, G_OBJECT (pair)); 
    18281903                        g_object_unref (pair); 
    18291904                } 
    1830                  
    18311905                iter = g_list_next (iter); 
    18321906        } 
     1907 
    18331908        g_list_free (authtypes); 
    18341909        authtypes = NULL; 
    1835          
    1836          
    1837         /* The work has finished, so clean up and provide the result via the  
    1838          * main callback: */ 
    18391910        info->result = result; 
    18401911 
    1841         /* Create the GError if necessary, 
    1842          * from the CamelException: */ 
    18431912        info->err = NULL; 
    18441913        if (camel_exception_is_set (&ex)) 
     
    18531922        g_static_rec_mutex_unlock (priv->service_lock); 
    18541923 
    1855         /* Call the callback, with the result, in an idle thread, 
    1856          * and stop this thread: */ 
    1857         if (info->callback) { 
    1858                 info->callback (info->self, info->cancelled, info->result, &info->err, info->user_data); 
    1859         } else { 
    1860                 /* Thread reference */ 
    1861                 g_object_unref (G_OBJECT (self)); 
    1862         } 
     1924        info->mutex = g_mutex_new (); 
     1925        info->condition = g_cond_new (); 
     1926        info->had_callback = FALSE; 
     1927 
     1928        execute_callback (10, G_PRIORITY_HIGH,  
     1929                on_supauth_idle_func,  
     1930                info, on_supauth_destroy_func); 
     1931 
     1932        /* Wait on the queue for the mainloop callback to be finished */ 
     1933        g_mutex_lock (info->mutex); 
     1934        if (!info->had_callback) 
     1935                g_cond_wait (info->condition, info->mutex); 
     1936        g_mutex_unlock (info->mutex); 
     1937 
     1938        g_mutex_free (info->mutex); 
     1939        g_cond_free (info->condition); 
     1940 
     1941        g_slice_free (GetSupportedAuthInfo, info); 
     1942 
    18631943        tny_status_free(status); 
    1864         g_thread_exit (NULL); 
    18651944 
    18661945        return NULL; 
     
    18681947 
    18691948 
    1870 /*TODO: This should be a vfunc so that it is generally available  
    1871  * (and implementable) for other imlpementations. But this should not need a  
    1872  * TnyAccount instance, so we need to find some other object to put the vfunc.  
    1873  */ 
    1874   
    18751949/**  
    18761950 * TnyCamelGetSupportedSecureAuthCallback: 
     
    19021976        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
    19031977        GetSupportedAuthInfo *info = NULL; 
    1904  
    1905         g_return_if_fail (callback); 
    1906         g_return_if_fail (priv->session); 
    1907  
    1908         /* Store all the interesting info in a struct  
    1909          * launch a thread and keep that struct-instance around. 
    1910          * - While the thread is running, we regularly call the status callback in  
    1911          * an idle handler. 
    1912          * - When the thread is finished, the main callback will  
    1913          * then be called in an idle handler. 
    1914          */ 
    1915  
    1916         /* Check that the session is ready, and stop with a GError if it is not: */ 
    19171978        GError *err = NULL; 
     1979 
    19181980        if (!_tny_session_check_operation (priv->session, TNY_ACCOUNT (self), &err,  
    19191981                        TNY_ACCOUNT_ERROR, TNY_ACCOUNT_ERROR_GET_SUPPORTED_AUTH)) 
     
    19251987        } 
    19261988 
    1927  
    1928         /* Idle info for the status callback: */ 
    19291989        info = g_slice_new (GetSupportedAuthInfo); 
    19301990        info->session = priv->session; 
     
    19361996        info->user_data = user_data; 
    19371997         
    1938         /* Use a ref count because we do not know which of the 2 idle callbacks  
    1939          * will be the last, and we can only unref self in the last callback: 
    1940          * This is destroyed in the idle GDestroyNotify callback. 
    1941          * A shared copy is taken and released by the _tny_progress* callback, 
    1942          * so that it can prevent the stats callback from being called after  
    1943          * the main callback. */ 
    19441998        info->stopper = tny_idle_stopper_new(); 
    19451999 
    19462000        /* thread reference */ 
    1947         g_object_ref (G_OBJECT (self)); 
    1948  
    1949         /* This will cause the idle status callback to be called, 
    1950          * via _tny_camel_account_start_camel_operation, 
    1951          * and also calls the idle main callback: */ 
    1952  
    1953         g_thread_create (tny_camel_account_get_supported_secure_authentication_async_thread, 
    1954                 info, FALSE, NULL); 
    1955 
    1956  
     2001        g_object_ref (self); 
     2002        camel_object_ref (info->session); 
     2003 
     2004 
     2005        if (TNY_IS_CAMEL_STORE_ACCOUNT (self))  
     2006        { 
     2007                TnyCamelStoreAccountPriv *aspriv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self); 
     2008                _tny_camel_queue_launch (aspriv->queue,  
     2009                        tny_camel_account_get_supported_secure_authentication_async_thread, info, 
     2010                        __FUNCTION__); 
     2011        } else { 
     2012                g_thread_create (tny_camel_account_get_supported_secure_authentication_async_thread, 
     2013                        info, FALSE, NULL); 
     2014        } 
     2015
     2016 
  • trunk/libtinymail-camel/tny-camel-folder.c

    r2551 r2553  
    7878static GObjectClass *parent_class = NULL; 
    7979 
     80 
     81typedef struct {  
     82        GObject *self; 
     83        GObject *change;  
     84} NotFolObInIdleInfo; 
     85 
     86static void  
     87do_notify_in_idle_destroy (gpointer user_data) 
     88{ 
     89        NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data; 
     90        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
     91 
     92        g_object_unref (info->change); 
     93        _tny_camel_folder_unreason (priv); 
     94        g_object_unref (info->self); 
     95        g_slice_free (NotFolObInIdleInfo, info); 
     96} 
     97 
    8098static void 
    8199notify_folder_store_observers_about (TnyFolderStore *self, TnyFolderStoreChange *change) 
    82100{ 
    83101        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     102        TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->account); 
    84103        TnyIterator *iter; 
    85104        TnyList *list; 
    86105 
    87106        g_static_rec_mutex_lock (priv->obs_lock); 
    88  
    89107        if (!priv->sobservers) { 
    90108                g_static_rec_mutex_unlock (priv->obs_lock); 
    91109                return; 
    92110        } 
    93  
    94111        list = tny_list_copy (priv->sobservers); 
    95112        g_static_rec_mutex_unlock (priv->obs_lock); 
    96113 
    97114        iter = tny_list_create_iterator (list); 
    98  
    99115        while (!tny_iterator_is_done (iter)) 
    100116        { 
    101117                TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter)); 
    102  
     118                tny_lockable_lock (apriv->session->priv->ui_lock); 
    103119                tny_folder_store_observer_update (observer, change); 
    104                 g_object_unref (G_OBJECT (observer)); 
     120                tny_lockable_unlock (apriv->session->priv->ui_lock); 
     121                g_object_unref (observer); 
    105122                tny_iterator_next (iter); 
    106123        } 
    107         g_object_unref (G_OBJECT (iter)); 
    108  
     124        g_object_unref (iter); 
    109125        g_object_unref (list); 
    110126 
    111 
     127        return; 
     128
     129 
     130static gboolean  
     131notify_folder_store_observers_about_idle (gpointer user_data) 
     132
     133        NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data; 
     134        notify_folder_store_observers_about (TNY_FOLDER_STORE (info->self),  
     135                TNY_FOLDER_STORE_CHANGE (info->change)); 
     136        return FALSE; 
     137
     138 
     139static void 
     140notify_folder_store_observers_about_in_idle (TnyFolderStore *self, TnyFolderStoreChange *change) 
     141
     142        NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo); 
     143        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     144 
     145        _tny_camel_folder_reason (priv); 
     146        info->self = g_object_ref (self); 
     147        info->change = g_object_ref (change); 
     148        g_idle_add_full (G_PRIORITY_HIGH, notify_folder_store_observers_about_idle, 
     149                info, do_notify_in_idle_destroy); 
     150
     151 
    112152 
    113153static void 
     
    115155{ 
    116156        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     157        TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->account); 
    117158        TnyIterator *iter; 
    118159        TnyList *list; 
    119160 
    120161        g_static_rec_mutex_lock (priv->obs_lock); 
    121  
    122162        if (!priv->observers) { 
    123163                g_static_rec_mutex_unlock (priv->obs_lock); 
    124164                return; 
    125165        } 
    126  
    127166        list = tny_list_copy (priv->observers); 
    128167        g_static_rec_mutex_unlock (priv->obs_lock); 
    129168 
    130169        iter = tny_list_create_iterator (list); 
    131  
    132170        while (!tny_iterator_is_done (iter)) 
    133171        { 
    134172                TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (tny_iterator_get_current (iter)); 
     173                tny_lockable_lock (apriv->session->priv->ui_lock); 
    135174                tny_folder_observer_update (observer, change); 
    136                 g_object_unref (G_OBJECT (observer)); 
     175                tny_lockable_unlock (apriv->session->priv->ui_lock); 
     176                g_object_unref (observer); 
    137177                tny_iterator_next (iter); 
    138178        } 
    139         g_object_unref (G_OBJECT (iter)); 
    140  
     179        g_object_unref (iter); 
    141180        g_object_unref (list); 
    142181 
    143 
     182        return; 
     183
     184 
     185 
     186static gboolean  
     187notify_folder_observers_about_idle (gpointer user_data) 
     188
     189        NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data; 
     190        notify_folder_observers_about (TNY_FOLDER (info->self),  
     191                TNY_FOLDER_CHANGE (info->change)); 
     192        return FALSE; 
     193
     194 
     195static void 
     196notify_folder_observers_about_in_idle (TnyFolder *self, TnyFolderChange *change) 
     197
     198        NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo); 
     199        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     200 
     201        _tny_camel_folder_reason (priv); 
     202        info->self = g_object_ref (self); 
     203        info->change = g_object_ref (change); 
     204        g_idle_add_full (G_PRIORITY_HIGH, notify_folder_observers_about_idle, 
     205                info, do_notify_in_idle_destroy); 
     206
     207 
     208 
     209static void 
     210notify_folder_store_observers_about_for_store_acc (TnyFolderStore *self, TnyFolderStoreChange *change) 
     211
     212        TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self); 
     213        TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     214        TnyIterator *iter; 
     215        TnyList *list = NULL; 
     216 
     217        g_static_rec_mutex_lock (priv->obs_lock); 
     218        if (!priv->sobservers) { 
     219                g_static_rec_mutex_unlock (priv->obs_lock); 
     220                return; 
     221        } 
     222        list = tny_list_copy (priv->sobservers); 
     223        g_static_rec_mutex_unlock (priv->obs_lock); 
     224 
     225        iter = tny_list_create_iterator (list); 
     226        while (!tny_iterator_is_done (iter)) 
     227        { 
     228                TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter)); 
     229                tny_lockable_lock (apriv->session->priv->ui_lock); 
     230                tny_folder_store_observer_update (observer, change); 
     231                tny_lockable_unlock (apriv->session->priv->ui_lock); 
     232                g_object_unref (observer); 
     233                tny_iterator_next (iter); 
     234        } 
     235        g_object_unref (iter); 
     236        g_object_unref (list); 
     237 
     238        return; 
     239
     240 
     241static gboolean  
     242notify_folder_store_observers_about_for_store_acc_idle (gpointer user_data) 
     243
     244        NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data; 
     245        notify_folder_store_observers_about_for_store_acc (TNY_FOLDER_STORE (info->self),  
     246                TNY_FOLDER_STORE_CHANGE (info->change)); 
     247        return FALSE; 
     248
     249 
     250static void 
     251notify_folder_store_observers_about_for_store_acc_in_idle (TnyFolderStore *self, TnyFolderStoreChange *change) 
     252
     253        NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo); 
     254        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     255 
     256        _tny_camel_folder_reason (priv); 
     257        info->self = g_object_ref (self); 
     258        info->change = g_object_ref (change); 
     259        g_idle_add_full (G_PRIORITY_HIGH, notify_folder_store_observers_about_for_store_acc_idle, 
     260                info, do_notify_in_idle_destroy); 
     261
     262 
    144263 
    145264static void  
     
    164283        tny_folder_change_set_new_unread_count (change, priv->unread_length); 
    165284        tny_folder_change_set_new_all_count (change, priv->cached_length); 
    166         notify_folder_observers_about (TNY_FOLDER (self), change); 
     285        notify_folder_observers_about_in_idle (TNY_FOLDER (self), change); 
    167286        g_object_unref (change); 
    168287} 
     
    617736                tny_folder_change_set_new_unread_count (change, priv->unread_length); 
    618737 
    619                 notify_folder_observers_about (self, change); 
    620  
    621                 g_object_unref (G_OBJECT (change)); 
     738                notify_folder_observers_about_in_idle (self, change); 
     739 
     740                g_object_unref (change); 
    622741 
    623742                if (dst_orig_uids) { 
     
    691810        change = tny_folder_change_new (self); 
    692811        tny_folder_change_add_expunged_header (change, header); 
    693         notify_folder_observers_about (self, change); 
     812        notify_folder_observers_about_in_idle (self, change); 
    694813        g_object_unref (change); 
    695814 
     
    9941113        g_object_unref (change); 
    9951114 
    996         if (info->callback) 
     1115        if (info->callback) { 
     1116                tny_lockable_lock (info->session->priv->ui_lock); 
    9971117                info->callback (info->self, info->cancelled, &info->err, info->user_data); 
     1118                tny_lockable_unlock (info->session->priv->ui_lock); 
     1119        } 
    9981120 
    9991121        tny_idle_stopper_stop (info->stopper); 
     
    10111133        info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,  
    10121134                TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_SYNC, what, sofar,  
    1013                 oftotal, oinfo->stopper, oinfo->user_data); 
     1135                oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data); 
    10141136 
    10151137        execute_callback (oinfo->depth, G_PRIORITY_HIGH, 
     
    11101232{ 
    11111233        SyncFolderInfo *info = thr_user_data; 
    1112         if (info->callback) 
     1234        if (info->callback) { 
     1235                tny_lockable_lock (info->session->priv->ui_lock); 
    11131236                info->callback (info->self, TRUE, &info->err, info->user_data); 
     1237                tny_lockable_unlock (info->session->priv->ui_lock); 
     1238        } 
    11141239        return FALSE; 
    11151240} 
     
    12301355        g_object_unref (change); 
    12311356 
    1232         if (info->callback) 
     1357        if (info->callback) { 
     1358                tny_lockable_lock (info->session->priv->ui_lock); 
    12331359                info->callback (info->self, info->cancelled, &info->err, info->user_data); 
     1360                tny_lockable_unlock (info->session->priv->ui_lock); 
     1361        } 
    12341362 
    12351363        /* Prevent status callbacks from being called after this 
     
    12511379        info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,  
    12521380                TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_REFRESH, what, sofar,  
    1253                 oftotal, oinfo->stopper, oinfo->user_data); 
     1381                oftotal, oinfo->stopper, oinfo->session->priv->ui_lock,  
     1382                oinfo->user_data); 
    12541383 
    12551384        execute_callback (oinfo->depth, G_PRIORITY_HIGH, 
     
    13541483{ 
    13551484        RefreshFolderInfo *info = thr_user_data; 
    1356         if (info->callback) 
     1485        if (info->callback) { 
     1486                tny_lockable_lock (info->session->priv->ui_lock); 
    13571487                info->callback (info->self, TRUE, &info->err, info->user_data); 
     1488                tny_lockable_unlock (info->session->priv->ui_lock); 
     1489        } 
    13581490        return FALSE; 
    13591491} 
     
    14831615        tny_folder_change_set_new_all_count (change, priv->cached_length); 
    14841616        tny_folder_change_set_new_unread_count (change, priv->unread_length); 
    1485         notify_folder_observers_about (self, change); 
     1617        notify_folder_observers_about_in_idle (self, change); 
    14861618        g_object_unref (change); 
    14871619 
     
    15691701{ 
    15701702        GetHeadersInfo *info = thr_user_data; 
    1571         if (info->callback) 
     1703        if (info->callback) { 
     1704                tny_lockable_lock (info->session->priv->ui_lock); 
    15721705                info->callback (info->self, FALSE, info->headers, &info->err, info->user_data); 
     1706                tny_lockable_unlock (info->session->priv->ui_lock); 
     1707        } 
    15731708        return FALSE; 
    15741709} 
     
    16261761{ 
    16271762        GetHeadersInfo *info = thr_user_data; 
    1628         if (info->callback) 
     1763        if (info->callback) { 
     1764                tny_lockable_lock (info->session->priv->ui_lock); 
    16291765                info->callback (info->self, TRUE, info->headers, &info->err, info->user_data); 
     1766                tny_lockable_unlock (info->session->priv->ui_lock); 
     1767        } 
    16301768        return FALSE; 
    16311769} 
     
    18241962        } 
    18251963 
    1826         if (info->callback) 
     1964        if (info->callback) { 
     1965                tny_lockable_lock (info->session->priv->ui_lock); 
    18271966                info->callback (info->self, info->cancelled, info->msg, &info->err, info->user_data); 
     1967                tny_lockable_unlock (info->session->priv->ui_lock); 
     1968        } 
    18281969 
    18291970        if (info->msg) 
     
    18481989        info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,  
    18491990                TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_GET_MSG, what, sofar,  
    1850                 oftotal, oinfo->stopper, oinfo->user_data); 
     1991                oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data); 
    18511992 
    18521993        execute_callback (oinfo->depth, G_PRIORITY_HIGH,  
     
    19472088 
    19482089        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
    1949         if (info->callback) 
     2090        if (info->callback) { 
     2091                tny_lockable_lock (info->session->priv->ui_lock); 
    19502092                info->callback (info->self, TRUE, NULL, &info->err, info->user_data); 
     2093                tny_lockable_unlock (info->session->priv->ui_lock); 
     2094        } 
    19512095        return FALSE; 
    19522096} 
     
    20892233                change = tny_folder_change_new (self); 
    20902234                tny_folder_change_set_received_msg (change, retval); 
    2091                 notify_folder_observers_about (self, change); 
    2092                 g_object_unref (G_OBJECT (change)); 
     2235                notify_folder_observers_about_in_idle (self, change); 
     2236                g_object_unref (change); 
    20932237        } 
    20942238 
     
    24422586 
    24432587 
    2444 static void 
    2445 notify_folder_store_observers_about_for_store_acc (TnyFolderStore *self, TnyFolderStoreChange *change) 
    2446 
    2447         TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self); 
    2448         TnyIterator *iter; 
    2449  
    2450         if (!priv->sobservers) 
    2451                 return; 
    2452  
    2453         iter = tny_list_create_iterator (priv->sobservers); 
    2454         while (!tny_iterator_is_done (iter)) 
    2455         { 
    2456                 TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter)); 
    2457                 tny_folder_store_observer_update (observer, change); 
    2458                 g_object_unref (observer); 
    2459                 tny_iterator_next (iter); 
    2460         } 
    2461         g_object_unref (iter); 
    2462 
    2463  
    2464 static void 
    2465 notify_folder_observers_about_copy (GList *adds, GList *rems, gboolean del) 
    2466 
     2588 
     2589typedef struct { 
     2590        TnyFolder *folder; 
     2591        gboolean rem; 
     2592} NotFolObsItem; 
     2593 
     2594static void 
     2595not_fol_obs_foreach (gpointer key, gpointer value, gpointer user_data) 
     2596
     2597        GList *items = (GList *) value; 
     2598        TnyFolderStore *str = (TnyFolderStore *) key; 
     2599        TnyFolderStoreChange *change = tny_folder_store_change_new (str); 
     2600        gboolean in_idle = (gboolean) user_data; 
     2601 
     2602        while (items) 
     2603        { 
     2604                NotFolObsItem *item = (NotFolObsItem *) items->data; 
     2605 
     2606                tny_debug ("tny_folder_copy: observers notify folder-%s %s\n",  
     2607                        item->rem ? "del" : "add", 
     2608                        tny_folder_get_name (item->folder)); 
     2609 
     2610                if (item->rem) 
     2611                        tny_folder_store_change_add_removed_folder (change, item->folder); 
     2612                else 
     2613                        tny_folder_store_change_add_created_folder (change, item->folder); 
     2614 
     2615                g_slice_free (NotFolObsItem, item); 
     2616                items = g_list_next (items); 
     2617        } 
     2618 
     2619        g_list_free (items); 
     2620 
     2621        if (TNY_IS_CAMEL_STORE_ACCOUNT (str)) { 
     2622                if (in_idle) 
     2623                        notify_folder_store_observers_about_for_store_acc_in_idle (str, change); 
     2624                else 
     2625                        notify_folder_store_observers_about_for_store_acc (str, change); 
     2626        } else { 
     2627                if (in_idle) 
     2628                        notify_folder_store_observers_about_in_idle (str, change); 
     2629                else 
     2630                        notify_folder_store_observers_about (str, change); 
     2631        } 
     2632        g_object_unref (change); 
     2633 
     2634        return; 
     2635
     2636 
     2637static void 
     2638notify_folder_observers_about_copy (GList *adds, GList *rems, gboolean del, gboolean in_idle) 
     2639
     2640 
     2641        GHashTable *table = g_hash_table_new_full (g_direct_hash, g_direct_equal,  
     2642                                        NULL, NULL); 
     2643 
    24672644        rems = g_list_first (rems); 
    2468  
    24692645        while (rems) 
    24702646        { 
    24712647                CpyEvent *evt = rems->data; 
    2472  
    2473  
    24742648                if (del) { 
    2475                         TnyFolderStoreChange *change = tny_folder_store_change_new (evt->str); 
    2476                         tny_folder_store_change_add_removed_folder (change, evt->fol); 
    2477  
    2478                         if (TNY_IS_CAMEL_STORE_ACCOUNT (evt->str)) 
    2479                                 notify_folder_store_observers_about_for_store_acc (evt->str, change); 
    2480                         else 
    2481                                 notify_folder_store_observers_about (evt->str, change); 
    2482  
    2483                         tny_debug ("tny_folder_copy: observers notify folder-del %s\n",  
    2484                                 tny_folder_get_name (evt->fol)); 
    2485  
    2486                         g_object_unref (change); 
     2649                        gboolean add = FALSE; 
     2650                        NotFolObsItem *item = g_slice_new (NotFolObsItem); 
     2651                        GList *items = g_hash_table_lookup (table, evt->str); 
     2652                        if (!items) 
     2653                                add = TRUE; 
     2654                        item->folder = TNY_FOLDER (g_object_ref (evt->fol)); 
     2655                        item->rem = TRUE; 
     2656                        items = g_list_append (items, item); 
     2657                        if (add) 
     2658                                g_hash_table_insert (table, evt->str, items); 
     2659 
    24872660                } 
    2488  
    24892661                cpy_event_free (evt); 
    24902662                rems = g_list_next (rems); 
    24912663        } 
    2492  
    24932664        g_list_free (rems); 
    24942665 
    24952666        while (adds) 
    24962667        { 
    2497                 TnyFolderStoreChange *change; 
    24982668                CpyEvent *evt = adds->data; 
    2499  
    2500                 change = tny_folder_store_change_new (evt->str); 
    2501                 tny_folder_store_change_add_created_folder (change, evt->fol); 
    2502  
    2503                 if (TNY_IS_CAMEL_STORE_ACCOUNT (evt->str)) 
    2504                         notify_folder_store_observers_about_for_store_acc (evt->str, change); 
    2505                 else 
    2506                         notify_folder_store_observers_about (evt->str, change); 
    2507  
    2508                 g_object_unref (change); 
    2509  
    2510                 tny_debug ("tny_folder_copy: observers notify folder-add %s\n", 
    2511                          tny_folder_get_name (evt->fol)); 
    2512  
     2669                gboolean add = FALSE; 
     2670                NotFolObsItem *item = g_slice_new (NotFolObsItem); 
     2671                GList *items = g_hash_table_lookup (table, evt->str); 
     2672                if (!items) 
     2673                        add = TRUE; 
     2674                item->folder = TNY_FOLDER (g_object_ref (evt->fol)); 
     2675                item->rem = FALSE; 
     2676                items = g_list_append (items, item); 
     2677                if (add) 
     2678                        g_hash_table_insert (table, evt->str, items); 
    25132679                cpy_event_free (evt); 
    25142680                adds = g_list_next (