Changeset 2983

Show
Ignore:
Timestamp:
11/20/07 22:23:11
Author:
pvanhoof
Message:

and made it possible to provide a ui-locker. Also, locking the ui
context at the right times.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r2981 r2983  
    88 
    99        * Bugfix makes ENABLE not happen if login failed 
     10        * Completed the implementation of TnyMergeFolder, shortened its locks 
     11        and made it possible to provide a ui-locker. Also, locking the ui 
     12        context at the right times. 
    1013 
    11142007-11-20  Steve Kowalik  <stevenk@ubuntu.com> 
  • trunk/libtinymail/tny-folder-monitor.c

    r2914 r2983  
    366366 
    367367        g_mutex_lock (priv->lock); 
    368         g_object_unref (G_OBJECT (priv->lists)); 
     368        g_object_unref (priv->lists); 
    369369        g_mutex_unlock (priv->lock); 
    370370 
  • trunk/libtinymail/tny-merge-folder.c

    r2884 r2983  
    2727#include <tny-simple-list.h> 
    2828#include <tny-folder-observer.h> 
     29#include <tny-noop-lockable.h> 
    2930 
    3031static GObjectClass *parent_class = NULL; 
     
    3536{ 
    3637        gchar *id, *name; 
    37         TnyList *mothers, *observers
     38        TnyList *mothers
    3839        GStaticRecMutex *lock; 
    3940        TnyFolderType folder_type; 
     41        GList *obs; 
     42        TnyLockable *ui_locker; 
    4043}; 
    4144 
     
    4952{ 
    5053        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    51         TnyList *copy = NULL; 
    5254        TnyIterator *iter; 
    53  
    54         g_static_rec_mutex_lock (priv->lock); 
    55         if (!priv->observers) { 
     55        GList *list; 
     56 
     57        g_static_rec_mutex_lock (priv->lock); 
     58        if (!priv->obs) { 
    5659                g_static_rec_mutex_unlock (priv->lock); 
    5760                return; 
    5861        } 
    59         copy = tny_list_copy (priv->observers); 
    60         g_static_rec_mutex_unlock (priv->lock); 
    61  
    62         iter = tny_list_create_iterator (copy); 
    63         while (!tny_iterator_is_done (iter)
    64         { 
    65                 TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (tny_iterator_get_current (iter)); 
    66                 /* TNY TODO: tny_lockable_lock (ui_lock); */ 
     62        list = g_list_copy (priv->obs); 
     63        g_static_rec_mutex_unlock (priv->lock); 
     64 
     65 
     66        while (list
     67        { 
     68                TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (list->data); 
     69                tny_lockable_lock (priv->ui_locker); 
    6770                tny_folder_observer_update (observer, change); 
    68                 /* TNY TODO: tny_lockable_unlock (ui_lock); */ 
    69                 g_object_unref (G_OBJECT (observer)); 
    70                tny_iterator_next (iter); 
    71         } 
    72  
    73         g_object_unref (iter); 
    74         g_object_unref (copy)
     71                tny_lockable_unlock (priv->ui_locker); 
     72                list = g_list_next (list); 
     73        } 
     74 
     75        g_list_free (list); 
     76 
     77        return
    7578} 
    7679 
     
    122125        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    123126        TnyIterator *iter; 
    124  
    125         g_static_rec_mutex_lock (priv->lock); 
    126  
    127         iter = tny_list_create_iterator (priv->mothers); 
     127        TnyList *copy; 
     128 
     129        g_static_rec_mutex_lock (priv->lock); 
     130        copy = tny_list_copy (priv->mothers); 
     131        g_static_rec_mutex_unlock (priv->lock); 
     132 
     133        iter = tny_list_create_iterator (copy); 
    128134        while (!tny_iterator_is_done (iter)) 
    129135        { 
     
    143149        } 
    144150        g_object_unref (iter); 
    145  
    146         g_static_rec_mutex_unlock (priv->lock); 
     151        g_object_unref (copy); 
     152 
    147153 
    148154        return; 
     
    172178 
    173179        /* thread reference */ 
    174         g_object_unref (G_OBJECT (self)); 
     180        g_object_unref (self); 
    175181        if (info->err) 
    176182                g_error_free (info->err); 
     
    185191{ 
    186192        SyncFolderInfo *info = thr_user_data; 
     193        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (info->self); 
    187194 
    188195        if (info->callback) { 
    189                 /* TNY TODO: tny_lockable_lock (ui_lock); */ 
     196                tny_lockable_lock (priv->ui_locker); 
    190197                info->callback (info->self, info->cancelled, info->err, info->user_data); 
    191                 /* TNY TODO: tny_lockable_unlock (ui_lock); */ 
     198                tny_lockable_unlock (priv->ui_locker); 
    192199        } 
    193200 
     
    204211        TnyIterator *iter; 
    205212        GError *err = NULL; 
    206  
    207         g_static_rec_mutex_lock (priv->lock); 
     213        TnyList *copy; 
     214 
     215        g_static_rec_mutex_lock (priv->lock); 
     216        copy = tny_list_copy (priv->mothers); 
     217        g_static_rec_mutex_unlock (priv->lock); 
    208218 
    209219        info->cancelled = FALSE; 
    210220 
    211         iter = tny_list_create_iterator (priv->mothers); 
     221        iter = tny_list_create_iterator (copy); 
    212222        while (!tny_iterator_is_done (iter)) 
    213223        { 
     
    226236                tny_iterator_next (iter); 
    227237        } 
     238 
    228239        g_object_unref (iter); 
     240        g_object_unref (copy); 
    229241 
    230242        info->err = NULL; 
    231  
    232         g_static_rec_mutex_unlock (priv->lock); 
    233243 
    234244        if (info->callback) 
     
    244254                } 
    245255        } else /* Thread reference */ 
    246                 g_object_unref (G_OBJECT (self)); 
     256                g_object_unref (self); 
    247257 
    248258        g_thread_exit (NULL); 
     
    268278 
    269279        /* thread reference */ 
    270         g_object_ref (G_OBJECT (self)); 
     280        g_object_ref (self); 
    271281 
    272282        thread = g_thread_create (sync_async_thread, info, FALSE, NULL); 
     
    321331        TnyFolder *fol = tny_header_get_folder (header); 
    322332        TnyMsg *retval = tny_folder_get_msg (fol, header, err); 
     333 
    323334        g_object_unref (fol); 
    324335 
     
    333344        TnyIterator *iter; 
    334345        TnyMsg *retval = NULL; 
    335  
    336         g_static_rec_mutex_lock (priv->lock); 
    337  
    338         iter = tny_list_create_iterator (priv->mothers); 
     346        TnyList *copy; 
     347 
     348        g_static_rec_mutex_lock (priv->lock); 
     349        copy = tny_list_copy (priv->mothers); 
     350        g_static_rec_mutex_unlock (priv->lock); 
     351 
     352        iter = tny_list_create_iterator (copy); 
    339353        while (!tny_iterator_is_done (iter) && !retval) 
    340354        { 
     
    346360 
    347361        g_object_unref (iter); 
    348  
    349         g_static_rec_mutex_unlock (priv->lock); 
     362        g_object_unref (copy); 
     363 
    350364 
    351365        if (!retval) 
     
    376390 
    377391        /* thread reference */ 
    378         g_object_unref (G_OBJECT (info->self)); 
     392        g_object_unref (info->self); 
     393 
    379394        if (info->msg) 
    380                 g_object_unref (G_OBJECT (info->msg)); 
     395                g_object_unref (info->msg); 
    381396 
    382397        if (info->err) 
     
    390405{ 
    391406        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
     407        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (info->self); 
    392408 
    393409        if (info->callback) {  
    394410                /* TNY TODO: the cancelled field */ 
    395  
    396                 /* TNY TODO: tny_lockable_lock (ui_lock); */ 
     411                tny_lockable_lock (priv->ui_locker); 
    397412                info->callback (info->self, FALSE, info->msg, info->err, info->user_data); 
    398                 /* TNY TODO: tny_lockable_unlock (ui_lock); */ 
     413                tny_lockable_unlock (priv->ui_locker); 
    399414        } 
    400415 
     
    413428        { 
    414429                if (info->msg && G_IS_OBJECT (info->msg)) 
    415                         g_object_unref (G_OBJECT (info->msg)); 
     430                        g_object_unref (info->msg); 
    416431                info->msg = NULL; 
    417432        } 
    418433 
    419         g_object_unref (G_OBJECT (info->header)); 
     434        g_object_unref (info->header); 
    420435 
    421436        if (info->callback) 
     
    431446                } 
    432447        } else /* thread reference */ 
    433                 g_object_unref (G_OBJECT (info->self)); 
     448                g_object_unref (info->self); 
    434449 
    435450        g_thread_exit (NULL); 
     
    499514{ 
    500515        GetHeadersFolderInfo *info = thr_user_data; 
     516        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (info->self); 
    501517 
    502518        if (info->callback) { 
    503                 /* TNY TODO: tny_lockable_lock (ui_lock); */ 
     519                tny_lockable_lock (priv->ui_locker); 
    504520                info->callback (info->self, info->cancelled, info->headers, info->err, info->user_data); 
    505                 /* TNY TODO: tny_lockable_unlock (ui_lock); */ 
     521                tny_lockable_unlock (priv->ui_locker); 
    506522        } 
    507523 
     
    518534        TnyIterator *iter; 
    519535        GError *err = NULL; 
    520  
    521         g_static_rec_mutex_lock (priv->lock); 
     536        TnyList *copy; 
     537 
     538        g_static_rec_mutex_lock (priv->lock); 
     539        copy = tny_list_copy (priv->mothers); 
     540        g_static_rec_mutex_unlock (priv->lock); 
    522541 
    523542        info->cancelled = FALSE; 
    524543 
    525         iter = tny_list_create_iterator (priv->mothers); 
     544        iter = tny_list_create_iterator (copy); 
    526545        while (!tny_iterator_is_done (iter)) 
    527546        { 
     
    540559                tny_iterator_next (iter); 
    541560        } 
     561 
    542562        g_object_unref (iter); 
     563        g_object_unref (copy); 
    543564 
    544565        info->err = NULL; 
    545  
    546         g_static_rec_mutex_unlock (priv->lock); 
    547566 
    548567        if (info->callback) 
     
    598617        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    599618        TnyIterator *iter; 
    600  
    601         g_static_rec_mutex_lock (priv->lock); 
    602  
    603         iter = tny_list_create_iterator (priv->mothers); 
     619        TnyList *copy; 
     620 
     621        g_static_rec_mutex_lock (priv->lock); 
     622        copy = tny_list_copy (priv->mothers); 
     623        g_static_rec_mutex_unlock (priv->lock); 
     624 
     625        iter = tny_list_create_iterator (copy); 
    604626 
    605627        while (!tny_iterator_is_done (iter)) 
     
    620642 
    621643        g_object_unref (iter); 
    622  
    623         g_static_rec_mutex_unlock (priv->lock); 
     644        g_object_unref (copy); 
    624645 
    625646} 
     
    643664                GString *ids = g_string_new (""); 
    644665                gboolean first = TRUE; 
     666                TnyList *copy; 
    645667 
    646668                g_static_rec_mutex_lock (priv->lock); 
    647  
    648                 iter = tny_list_create_iterator (priv->mothers); 
     669                copy = tny_list_copy (priv->mothers); 
     670                g_static_rec_mutex_unlock (priv->lock); 
     671 
     672                iter = tny_list_create_iterator (copy); 
    649673 
    650674                while (!tny_iterator_is_done (iter)) 
     
    666690                priv->id = ids->str; 
    667691                g_string_free (ids, FALSE); 
     692 
    668693                g_object_unref (iter); 
    669  
    670                 g_static_rec_mutex_unlock (priv->lock); 
     694                g_object_unref (copy); 
    671695 
    672696        } 
     
    674698        /* The get_id_func() DBC contract does not allow this to be NULL or "": */ 
    675699        if ( (priv->id == NULL) || (strlen (priv->id) == 0)) { 
    676                 priv->id = g_strdup ("unknown_mergefolder");    
    677         } 
    678          
     700                priv->id = g_strdup ("unknown_mergefolder"); 
     701        } 
     702 
    679703        return priv->id; 
    680704} 
     
    723747        TnyIterator *iter; 
    724748        guint total = 0; 
    725  
    726         g_static_rec_mutex_lock (priv->lock); 
    727  
    728         iter = tny_list_create_iterator (priv->mothers); 
     749        TnyList *copy; 
     750 
     751        g_static_rec_mutex_lock (priv->lock); 
     752        copy = tny_list_copy (priv->mothers); 
     753        g_static_rec_mutex_unlock (priv->lock); 
     754 
     755        iter = tny_list_create_iterator (copy); 
    729756 
    730757        while (!tny_iterator_is_done (iter)) 
     
    737764 
    738765        g_object_unref (iter); 
    739  
    740         g_static_rec_mutex_unlock (priv->lock); 
     766        g_object_unref (copy); 
     767 
    741768 
    742769        return total; 
     
    749776        TnyIterator *iter; 
    750777        guint total = 0; 
    751  
    752         g_static_rec_mutex_lock (priv->lock); 
    753  
    754         iter = tny_list_create_iterator (priv->mothers); 
     778        TnyList *copy; 
     779 
     780        g_static_rec_mutex_lock (priv->lock); 
     781        copy = tny_list_copy (priv->mothers); 
     782        g_static_rec_mutex_unlock (priv->lock); 
     783 
     784        iter = tny_list_create_iterator (copy); 
    755785 
    756786        while (!tny_iterator_is_done (iter)) 
     
    763793 
    764794        g_object_unref (iter); 
    765  
    766         g_static_rec_mutex_unlock (priv->lock); 
     795        g_object_unref (copy); 
    767796 
    768797        return total; 
     
    776805        TnyIterator *iter; 
    777806        guint total = 0; 
    778  
    779         g_static_rec_mutex_lock (priv->lock); 
    780  
    781         iter = tny_list_create_iterator (priv->mothers); 
     807        TnyList *copy; 
     808 
     809        g_static_rec_mutex_lock (priv->lock); 
     810        copy = tny_list_copy (priv->mothers); 
     811        g_static_rec_mutex_unlock (priv->lock); 
     812 
     813        iter = tny_list_create_iterator (copy); 
    782814 
    783815        while (!tny_iterator_is_done (iter)) 
     
    790822 
    791823        g_object_unref (iter); 
    792  
    793         g_static_rec_mutex_unlock (priv->lock); 
     824        g_object_unref (copy); 
    794825 
    795826        return total; 
     
    808839        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    809840        TnyIterator *iter; 
    810  
    811         g_static_rec_mutex_lock (priv->lock); 
    812  
    813         iter = tny_list_create_iterator (priv->mothers); 
     841        TnyList *copy; 
     842 
     843        g_static_rec_mutex_lock (priv->lock); 
     844        copy = tny_list_copy (priv->mothers); 
     845        g_static_rec_mutex_unlock (priv->lock); 
     846 
     847        iter = tny_list_create_iterator (copy); 
    814848        while (!tny_iterator_is_done (iter)) 
    815849        { 
     
    829863 
    830864        g_object_unref (iter); 
    831  
    832         g_static_rec_mutex_unlock (priv->lock); 
     865        g_object_unref (copy); 
    833866 
    834867        return; 
     
    855888 
    856889        /* thread reference */ 
    857         g_object_unref (G_OBJECT (self)); 
     890        g_object_unref (self); 
    858891        if (info->err) 
    859892                g_error_free (info->err); 
     
    868901{ 
    869902        RefreshFolderInfo *info = thr_user_data; 
     903        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (info->self); 
    870904 
    871905        if (info->callback) { 
    872                 /* TNY TODO: tny_lockable_lock (ui_lock); */ 
     906                tny_lockable_lock (priv->ui_locker); 
    873907                info->callback (info->self, info->cancelled, info->err, info->user_data); 
    874                 /* TNY TODO: tny_lockable_unlock (ui_lock); */ 
     908                tny_lockable_unlock (priv->ui_locker); 
    875909        } 
    876910 
     
    900934        TnyIterator *iter; 
    901935        GError *err = NULL; 
    902  
    903         g_static_rec_mutex_lock (priv->lock); 
     936        TnyList *copy; 
     937 
     938        g_static_rec_mutex_lock (priv->lock); 
     939        copy = tny_list_copy (priv->mothers); 
     940        g_static_rec_mutex_unlock (priv->lock); 
    904941 
    905942        info->cancelled = FALSE; 
    906943 
    907         iter = tny_list_create_iterator (priv->mothers); 
     944        iter = tny_list_create_iterator (copy); 
    908945        while (!tny_iterator_is_done (iter)) 
    909946        { 
     
    922959                tny_iterator_next (iter); 
    923960        } 
     961 
    924962        g_object_unref (iter); 
     963        g_object_unref (copy); 
    925964 
    926965        info->err = NULL; 
    927966 
    928         g_static_rec_mutex_unlock (priv->lock); 
    929967 
    930968        if (info->callback) 
     
    940978                } 
    941979        } else /* Thread reference */ 
    942                 g_object_unref (G_OBJECT (self)); 
     980                g_object_unref (self); 
    943981 
    944982        g_thread_exit (NULL); 
     
    9631001 
    9641002        /* thread reference */ 
    965         g_object_ref (G_OBJECT (self)); 
     1003        g_object_ref (self); 
    9661004 
    9671005        thread = g_thread_create (refresh_async_thread, info, FALSE, NULL); 
     
    9761014        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    9771015        TnyIterator *iter; 
    978  
    979         g_static_rec_mutex_lock (priv->lock); 
    9801016 
    9811017        iter = tny_list_create_iterator (header_list); 
     
    10051041 
    10061042        g_object_unref (iter); 
    1007  
    1008         g_static_rec_mutex_unlock (priv->lock); 
    10091043 
    10101044        return; 
     
    10301064 
    10311065        /* thread reference */ 
    1032         g_object_unref (G_OBJECT (info->self)); 
    1033         g_object_unref (G_OBJECT (info->folder_dst)); 
    1034         g_object_unref (G_OBJECT (info->header_list)); 
     1066        g_object_unref (info->self); 
     1067        g_object_unref (info->folder_dst); 
     1068        g_object_unref (info->header_list); 
    10351069 
    10361070        if (info->err) 
     
    10461080{ 
    10471081        TransferMsgsInfo *info = thr_user_data; 
     1082        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (info->self); 
    10481083 
    10491084        if (info->callback) { 
    10501085                /* TNY TODO: the cancelled field */ 
    1051  
    1052                 /* TNY TODO: tny_lockable_lock (ui_lock); */ 
     1086                tny_lockable_lock (priv->ui_locker); 
    10531087                info->callback (info->self, FALSE, info->err, info->user_data); 
    1054                 /* TNY TODO: tny_lockable_unlock (ui_lock); */ 
     1088                tny_lockable_unlock (priv->ui_locker); 
    10551089        } 
    10561090 
     
    10661100        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    10671101 
    1068         g_static_rec_mutex_lock (priv->lock); 
    10691102        tny_merge_folder_transfer_msgs (info->self, info->header_list, info->folder_dst, info->delete_originals, &info->err); 
    1070         g_static_rec_mutex_unlock (priv->lock); 
    10711103 
    10721104        if (info->callback) 
     
    10821114                } 
    10831115        } else  { /* Thread reference */ 
    1084                 g_object_unref (G_OBJECT (info->self)); 
    1085                 g_object_unref (G_OBJECT (info->folder_dst)); 
    1086                 g_object_unref (G_OBJECT (info->header_list)); 
     1116                g_object_unref (info->self); 
     1117                g_object_unref (info->folder_dst); 
     1118                g_object_unref (info->header_list); 
    10871119        } 
    10881120 
     
    11101142 
    11111143        /* thread reference */ 
    1112         g_object_ref (G_OBJECT (self)); 
    1113         g_object_ref (G_OBJECT (folder_dst)); 
    1114         g_object_ref (G_OBJECT (header_list)); 
     1144        g_object_ref (self); 
     1145        g_object_ref (folder_dst); 
     1146        g_object_ref (header_list); 
    11151147 
    11161148        thread = g_thread_create (transfer_msgs_async_thread, info, FALSE, NULL); 
     
    11271159        TnyIterator *iter; 
    11281160        TnyFolder *nfol = NULL; 
    1129  
    1130         g_static_rec_mutex_lock (priv->lock); 
    1131  
    1132         iter = tny_list_create_iterator (priv->mothers); 
     1161        TnyList *copy; 
     1162 
     1163        g_static_rec_mutex_lock (priv->lock); 
     1164        copy = tny_list_copy (priv->mothers); 
     1165        g_static_rec_mutex_unlock (priv->lock); 
     1166 
     1167        iter = tny_list_create_iterator (copy); 
    11331168        while (!tny_iterator_is_done (iter)) 
    11341169        { 
     
    11711206 
    11721207        g_object_unref (iter); 
    1173  
    1174         g_static_rec_mutex_unlock (priv->lock); 
     1208        g_object_unref (copy); 
    11751209 
    11761210        return nfol; 
     
    11821216        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    11831217        TnyIterator *iter; 
    1184  
    1185         g_static_rec_mutex_lock (priv->lock); 
    1186  
    1187         iter = tny_list_create_iterator (priv->mothers); 
     1218        TnyList *copy; 
     1219 
     1220        g_static_rec_mutex_lock (priv->lock); 
     1221        copy = tny_list_copy (priv->mothers); 
     1222        g_static_rec_mutex_unlock (priv->lock); 
     1223 
     1224        iter = tny_list_create_iterator (copy); 
    11881225        while (!tny_iterator_is_done (iter)) 
    11891226        { 
     
    11951232 
    11961233        g_object_unref (iter); 
    1197  
    1198         g_static_rec_mutex_unlock (priv->lock); 
    1199  
    1200         return; 
     1234        g_object_unref (copy); 
     1235 
     1236        return; 
     1237
     1238 
     1239 
     1240static void  
     1241notify_observer_del (gpointer user_data, GObject *observer) 
     1242
     1243        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (user_data); 
     1244        g_static_rec_mutex_lock (priv->lock); 
     1245        priv->obs = g_list_remove (priv->obs, observer); 
     1246        g_static_rec_mutex_unlock (priv->lock); 
    12011247} 
    12021248 
     
    12071253 
    12081254        g_static_rec_mutex_lock (priv->lock); 
    1209  
    1210         if (!priv->observers) 
    1211                 priv->observers = tny_simple_list_new (); 
    1212  
    1213         tny_list_prepend (priv->observers, G_OBJECT (observer)); 
    1214  
     1255        priv->obs = g_list_prepend (priv->obs, observer); 
     1256        g_object_weak_ref (G_OBJECT (observer), notify_observer_del, self); 
    12151257        g_static_rec_mutex_unlock (priv->lock); 
    12161258 
     
    12221264{ 
    12231265        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    1224  
    1225         g_static_rec_mutex_lock (priv->lock); 
    1226  
    1227         if (priv->observers) 
    1228                 tny_list_remove (priv->observers, G_OBJECT (observer)); 
     1266        GList *found = NULL; 
     1267 
     1268        g_assert (TNY_IS_FOLDER_OBSERVER (observer)); 
     1269 
     1270        g_static_rec_mutex_lock (priv->lock); 
     1271 
     1272        if (!priv->obs) { 
     1273                g_static_rec_mutex_unlock (priv->lock); 
     1274                return; 
     1275        } 
     1276 
     1277        found = g_list_find (priv->obs, observer); 
     1278        if (found) { 
     1279                priv->obs = g_list_remove_link (priv->obs, found); 
     1280                g_object_weak_unref (found->data, notify_observer_del, self); 
     1281                g_list_free (found); 
     1282        } 
    12291283 
    12301284        g_static_rec_mutex_unlock (priv->lock); 
     
    12491303        TnyIterator *iter; 
    12501304        gint total_size = 0; 
    1251  
    1252         g_static_rec_mutex_lock (priv->lock); 
    1253  
    1254         iter = tny_list_create_iterator (priv->mothers); 
     1305        TnyList *copy; 
     1306 
     1307        g_static_rec_mutex_lock (priv->lock); 
     1308        copy = tny_list_copy (priv->mothers); 
     1309        g_static_rec_mutex_unlock (priv->lock); 
     1310 
     1311        iter = tny_list_create_iterator (copy); 
    12551312        while (!tny_iterator_is_done (iter)) 
    12561313        { 
     
    12641321 
    12651322        g_object_unref (iter); 
    1266  
    1267         g_static_rec_mutex_unlock (priv->lock); 
     1323        g_object_unref (copy); 
    12681324 
    12691325        /* TNY TODO: update unread, all_count and local_size here ! */ 
     
    13051361        TnyList *list; 
    13061362        TnyIterator *iter; 
    1307  
    13081363        gint total = 0, unread = 0; 
    1309  
    1310         g_static_rec_mutex_lock (priv->lock); 
    1311  
    1312         iter = tny_list_create_iterator (priv->mothers); 
     1364        TnyList *copy; 
     1365 
     1366        g_static_rec_mutex_lock (priv->lock); 
     1367        copy = tny_list_copy (priv->mothers); 
     1368        g_static_rec_mutex_unlock (priv->lock); 
     1369 
     1370        iter = tny_list_create_iterator (copy); 
    13131371        while (!tny_iterator_is_done (iter)) 
    13141372        { 
     
    13191377                tny_iterator_next (iter); 
    13201378        } 
     1379 
    13211380        g_object_unref (iter); 
    1322         g_static_rec_mutex_unlock (priv->lock); 
     1381        g_object_unref (copy); 
    13231382 
    13241383        tny_folder_change_set_new_all_count (new_change, total); 
     
    13821441        /* TODO: register @self as observer of @folder and proxy the 
    13831442         * events through to observers of @self. */ 
    1384          
     1443 
    13851444        g_static_rec_mutex_lock (priv->lock); 
    13861445 
    13871446        tny_list_prepend (priv->mothers, G_OBJECT (folder)); 
    1388  
    13891447        tny_folder_add_observer (folder, TNY_FOLDER_OBSERVER (self)); 
    13901448 
     
    14111469 
    14121470        priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    1413          
     1471 
    14141472        g_static_rec_mutex_lock (priv->lock); 
    14151473 
    14161474        tny_folder_remove_observer (folder, TNY_FOLDER_OBSERVER (self)); 
    1417  
    14181475        tny_list_remove (priv->mothers, G_OBJECT (folder)); 
    14191476 
     
    14351492        TnyMergeFolderPriv *priv; 
    14361493        TnyIterator *iter; 
     1494        TnyList *copy; 
    14371495 
    14381496        g_return_if_fail (TNY_IS_MERGE_FOLDER (self)); 
     
    14401498 
    14411499        priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    1442          
    1443         g_static_rec_mutex_lock (priv->lock); 
    1444  
    1445         iter = tny_list_create_iterator (priv->mothers); 
     1500 
     1501        g_static_rec_mutex_lock (priv->lock); 
     1502        copy = tny_list_copy (priv->mothers); 
     1503        g_static_rec_mutex_unlock (priv->lock); 
     1504 
     1505        iter = tny_list_create_iterator (copy); 
    14461506        while (!tny_iterator_is_done (iter)) { 
    14471507                GObject *folder; 
     
    14531513                tny_iterator_next (iter); 
    14541514        } 
     1515 
    14551516        g_object_unref (iter); 
    1456  
    1457         g_static_rec_mutex_unlock (priv->lock); 
     1517        g_object_unref (copy); 
     1518 
    14581519} 
    14591520 
     
    14651526 * instances together (partly read only, though). 
    14661527 * 
     1528 * Important consideration: if you use this type within a Gtk+ application, 
     1529 * you probably want to use tny_merge_folder_new_with_ui_locker in stead. If 
     1530 * your UI toolkid isn't thread safe (most aren't), but so-called thread aware 
     1531 * because it has a UI context lock (like Gtk+ has), then you must create this 
     1532 * type with a TnyLockable that aquires and releases this lock correctly. 
     1533 * For Gtk+ there's a default implementation called TnyGtkLockable available 
     1534 * in libtinymailui-gtk. Please do use this, else you can have threading related 
     1535 * problems in your user interface software. 
     1536 * 
    14671537 * Return value: a new #TnyMergeFolder instance 
    14681538 **/ 
     
    14791549 
    14801550 
     1551/** 
     1552 * tny_merge_folder_new_with_ui_locker: 
     1553 * @folder_name: the name of the merged folder 
     1554 * @ui_locker: a #TnyLockable for locking your ui 
     1555 * 
     1556 * Creates a a new TnyMergeFolder instance that can merge multiple #TnyFolder  
     1557 * instances together (partly read only, though). Upon construction it  
     1558 * instantly sets the ui locker. For Gtk+ you should use TnyGtkLockable here. 
     1559 * 
     1560 * Return value: a new #TnyMergeFolder instance 
     1561 **/ 
     1562TnyFolder* 
     1563tny_merge_folder_new_with_ui_locker (const gchar *folder_name, TnyLockable *ui_locker) 
     1564{ 
     1565        TnyMergeFolder *self = TNY_MERGE_FOLDER (tny_merge_folder_new (folder_name)); 
     1566        tny_merge_folder_set_ui_locker (self, ui_locker); 
     1567        return TNY_FOLDER (self); 
     1568} 
     1569 
     1570/** 
     1571 * tny_merge_folder_set_ui_locker: 
     1572 * @self: a #TnyMergeFolder instance 
     1573 * @ui_locker: a #TnyLockable locker for locking your ui 
     1574 * 
     1575 * Sets the ui locker. For Gtk+ you should use TnyGtkLockable here. 
     1576 * 
     1577 **/ 
     1578void  
     1579tny_merge_folder_set_ui_locker (TnyMergeFolder *self, TnyLockable *ui_locker) 
     1580{ 
     1581        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
     1582        if (priv->ui_locker) 
     1583                g_object_unref (priv->ui_locker); 
     1584        priv->ui_locker = TNY_LOCKABLE (g_object_ref (ui_locker)); 
     1585        return; 
     1586} 
     1587 
     1588 
    14811589static void 
    14821590tny_merge_folder_instance_init (GTypeInstance *instance, gpointer g_class) 
     
    14891597        priv->lock = g_new0 (GStaticRecMutex, 1); 
    14901598        g_static_rec_mutex_init (priv->lock); 
    1491         priv->observers = NULL; 
     1599        priv->obs = NULL; 
    14921600        priv->folder_type = TNY_FOLDER_TYPE_MERGE; 
     1601        priv->ui_locker = tny_noop_lockable_new (); 
    14931602 
    14941603        return; 
     
    15011610        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    15021611        TnyIterator *iter; 
    1503  
    1504         g_static_rec_mutex_lock (priv->lock); 
    1505  
    1506         iter = tny_list_create_iterator (priv->mothers); 
     1612        TnyList *copy; 
     1613 
     1614        g_static_rec_mutex_lock (priv->lock); 
     1615        copy = tny_list_copy (priv->mothers); 
     1616        g_static_rec_mutex_unlock (priv->lock); 
     1617 
     1618        iter = tny_list_create_iterator (copy); 
    15071619        while (!tny_iterator_is_done (iter)) 
    15081620        { 
     
    15121624                tny_iterator_next (iter); 
    15131625        } 
     1626 
    15141627        g_object_unref (iter); 
    1515  
    1516         if (priv->observers)  
    1517                 g_object_unref (priv->observers); 
     1628        g_object_unref (copy); 
     1629 
     1630 
     1631        if (priv->obs) { 
     1632                GList *copy = priv->obs; 
     1633                while (copy) { 
     1634                        g_object_weak_unref ((GObject *) copy->data, notify_observer_del, self); 
     1635                        copy = g_list_next (copy); 
     1636                } 
     1637                g_list_free (priv->obs); 
     1638                priv->obs = NULL; 
     1639        } 
    15181640 
    15191641        g_object_unref (priv->mothers); 
     1642        g_object_unref (priv->ui_locker); 
    15201643 
    15211644        if (priv->id) 
     
    15241647        if (priv->name) 
    15251648                g_free (priv->name); 
    1526  
    1527         g_static_rec_mutex_unlock (priv->lock); 
    15281649 
    15291650        /* g_static_rec_mutex_free (priv->lock); */ 
  • trunk/libtinymail/tny-merge-folder.h

    r2825 r2983  
    3232#include <tny-folder-store.h> 
    3333#include <tny-folder-stats.h> 
     34#include <tny-lockable.h> 
    3435 
    3536G_BEGIN_DECLS 
     
    5859 
    5960TnyFolder* tny_merge_folder_new (const gchar *folder_name); 
     61TnyFolder* tny_merge_folder_new_with_ui_locker (const gchar *folder_name, TnyLockable *ui_locker); 
     62void tny_merge_folder_set_ui_locker (TnyMergeFolder *self, TnyLockable *ui_locker); 
    6063void tny_merge_folder_add_folder (TnyMergeFolder *self, TnyFolder *folder); 
    6164void tny_merge_folder_remove_folder (TnyMergeFolder *self, TnyFolder *folder); 
  • trunk/tests/c-demo/tny-demoui-summary-view.c

    r2896 r2983  
    177177                { 
    178178                        tny_folder_monitor_stop (priv->monitor); 
    179                         g_object_unref (G_OBJECT (priv->monitor)); 
     179                        g_object_unref (priv->monitor); 
    180180                } 
    181181                priv->monitor = NULL; 
     
    919919                                if (priv->monitor) { 
    920920                                        tny_folder_monitor_stop (priv->monitor); 
    921                                         g_object_unref (G_OBJECT (priv->monitor)); 
     921                                        g_object_unref (priv->monitor); 
    922922                                } 
    923923                                priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder)); 
     
    988988                        if (priv->monitor) { 
    989989                                tny_folder_monitor_stop (priv->monitor); 
    990                                 g_object_unref (G_OBJECT (priv->monitor)); 
     990                                g_object_unref (priv->monitor); 
    991991                        } 
    992992                        priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (merge)); 
     
    20472047        { 
    20482048                tny_folder_monitor_stop (priv->monitor); 
    2049                 g_object_unref (G_OBJECT (priv->monitor)); 
     2049                g_object_unref (priv->monitor); 
     2050                priv->monitor = NULL; 
    20502051        } 
    20512052        g_mutex_unlock (priv->monitor_lock);