~ubuntu-branches/ubuntu/utopic/evolution-data-server/utopic-proposed

« back to all changes in this revision

Viewing changes to camel/camel-folder-summary.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-06-13 12:02:14 UTC
  • mfrom: (1.1.116) (1.2.35 sid)
  • Revision ID: package-import@ubuntu.com-20140613120214-1zx93d8jxwt093aw
Tags: 3.12.2-1ubuntu1
* Merge with Debian, remaining changes:
  - debian/control: build depend on hardening-wrapper
  - Add build-depends and pass configure flag to enable Ubuntu Online
    Accounts support.
  - Filter out -Bsymbolic-functions from LDFLAGS (for future people
    wondering about this change, see e.g. BGO #594473 and duplicates).
  - Enable Ubuntu Online Accounts and split it and GOA into a separate
    package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
2
/*
3
 
 *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
4
 
 *
5
 
 *  Authors: Michael Zucchi <notzed@ximian.com>
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or
8
 
 * modify it under the terms of version 2 of the GNU Lesser General Public
9
 
 * License as published by the Free Software Foundation.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 * General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this program; if not, write to the
18
 
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
 
 * Boston, MA 02110-1301, USA.
 
3
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 
4
 *
 
5
 * Authors: Michael Zucchi <notzed@ximian.com>
 
6
 *
 
7
 * This library is free software you can redistribute it and/or modify it
 
8
 * under the terms of the GNU Lesser General Public License as published by
 
9
 * the Free Software Foundation.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
14
 * for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public License
 
17
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
20
18
 */
21
19
 
22
20
#ifdef HAVE_CONFIG_H
81
79
        struct _CamelIndex *index;
82
80
 
83
81
        GRecMutex summary_lock; /* for the summary hashtable/array */
84
 
        GRecMutex io_lock;      /* load/save lock, for access to saved_count, etc */
85
82
        GRecMutex filter_lock;  /* for accessing any of the filtering/indexing stuff, since we share them */
86
 
        GRecMutex alloc_lock;   /* for setting up and using allocators */
87
 
        GRecMutex ref_lock;     /* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
88
83
 
89
84
        gboolean need_preview;
90
85
        GHashTable *preview_updates;
107
102
        guint timeout_handle;
108
103
};
109
104
 
110
 
static GMutex info_lock;
111
 
 
112
 
/* this lock is ONLY for the standalone messageinfo stuff */
113
 
#define GLOBAL_INFO_LOCK(i) g_mutex_lock(&info_lock)
114
 
#define GLOBAL_INFO_UNLOCK(i) g_mutex_unlock(&info_lock)
115
 
 
116
105
/* this should probably be conditional on it existing */
117
106
#define USE_BSEARCH
118
107
 
142
131
static CamelMessageContentInfo * content_info_new_from_message (CamelFolderSummary *summary, CamelMimePart *mp);
143
132
static void                      content_info_free (CamelFolderSummary *, CamelMessageContentInfo *);
144
133
 
145
 
static gint save_message_infos_to_db (CamelFolderSummary *summary, gboolean fresh_mir, GError **error);
 
134
static gint save_message_infos_to_db (CamelFolderSummary *summary, GError **error);
146
135
static gint camel_read_mir_callback (gpointer  ref, gint ncol, gchar ** cols, gchar ** name);
147
136
 
148
137
static gchar *next_uid_string (CamelFolderSummary *summary);
165
154
        PROP_NEED_PREVIEW
166
155
};
167
156
 
168
 
G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, CAMEL_TYPE_OBJECT)
 
157
G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, G_TYPE_OBJECT)
169
158
 
170
159
static gboolean
171
160
remove_each_item (gpointer uid,
186
175
 
187
176
        g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
188
177
 
189
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
178
        camel_folder_summary_lock (summary);
190
179
 
191
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
192
180
        g_hash_table_foreach_remove (summary->priv->loaded_infos, remove_each_item, &to_remove_infos);
193
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
194
181
 
195
 
        g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_free, NULL);
 
182
        g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_unref, NULL);
196
183
        g_slist_free (to_remove_infos);
197
184
 
198
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
185
        camel_folder_summary_unlock (summary);
199
186
}
200
187
 
201
188
static void
221
208
                priv->timeout_handle = 0;
222
209
        }
223
210
 
224
 
        if (priv->filter_index != NULL) {
225
 
                g_object_unref (priv->filter_index);
226
 
                priv->filter_index = NULL;
227
 
        }
228
 
 
229
 
        if (priv->filter_64 != NULL) {
230
 
                g_object_unref (priv->filter_64);
231
 
                priv->filter_64 = NULL;
232
 
        }
233
 
 
234
 
        if (priv->filter_qp != NULL) {
235
 
                g_object_unref (priv->filter_qp);
236
 
                priv->filter_qp = NULL;
237
 
        }
238
 
 
239
 
        if (priv->filter_uu != NULL) {
240
 
                g_object_unref (priv->filter_uu);
241
 
                priv->filter_uu = NULL;
242
 
        }
243
 
 
244
 
        if (priv->filter_save != NULL) {
245
 
                g_object_unref (priv->filter_save);
246
 
                priv->filter_save = NULL;
247
 
        }
248
 
 
249
 
        if (priv->filter_html != NULL) {
250
 
                g_object_unref (priv->filter_html);
251
 
                priv->filter_html = NULL;
252
 
        }
253
 
 
254
 
        if (priv->filter_stream != NULL) {
255
 
                g_object_unref (priv->filter_stream);
256
 
                priv->filter_stream = NULL;
257
 
        }
258
 
 
259
 
        if (priv->index != NULL) {
260
 
                g_object_unref (priv->index);
261
 
                priv->index = NULL;
262
 
        }
 
211
        g_clear_object (&priv->filter_index);
 
212
        g_clear_object (&priv->filter_64);
 
213
        g_clear_object (&priv->filter_qp);
 
214
        g_clear_object (&priv->filter_uu);
 
215
        g_clear_object (&priv->filter_save);
 
216
        g_clear_object (&priv->filter_html);
 
217
        g_clear_object (&priv->filter_stream);
 
218
        g_clear_object (&priv->filter_index);
263
219
 
264
220
        if (priv->folder) {
265
221
                g_object_weak_unref (G_OBJECT (priv->folder), (GWeakNotify) g_nullify_pointer, &priv->folder);
286
242
        g_hash_table_destroy (priv->preview_updates);
287
243
 
288
244
        g_rec_mutex_clear (&priv->summary_lock);
289
 
        g_rec_mutex_clear (&priv->io_lock);
290
245
        g_rec_mutex_clear (&priv->filter_lock);
291
 
        g_rec_mutex_clear (&priv->alloc_lock);
292
 
        g_rec_mutex_clear (&priv->ref_lock);
293
246
 
294
247
        /* Chain up to parent's finalize() method. */
295
248
        G_OBJECT_CLASS (camel_folder_summary_parent_class)->finalize (object);
299
252
folder_summary_set_folder (CamelFolderSummary *summary,
300
253
                           CamelFolder *folder)
301
254
{
302
 
        g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
303
255
        g_return_if_fail (summary->priv->folder == NULL);
304
256
        /* folder can be NULL in certain cases, see maildir-store */
305
257
 
346
298
        switch (property_id) {
347
299
                case PROP_FOLDER:
348
300
                        g_value_set_object (
349
 
                                value, camel_folder_summary_get_folder (
 
301
                                value,
 
302
                                camel_folder_summary_get_folder (
350
303
                                CAMEL_FOLDER_SUMMARY (object)));
351
304
                        return;
352
305
 
353
306
                case PROP_SAVED_COUNT:
354
307
                        g_value_set_uint (
355
 
                                value, camel_folder_summary_get_saved_count (
 
308
                                value,
 
309
                                camel_folder_summary_get_saved_count (
356
310
                                CAMEL_FOLDER_SUMMARY (object)));
357
311
                        return;
358
312
 
359
313
                case PROP_UNREAD_COUNT:
360
314
                        g_value_set_uint (
361
 
                                value, camel_folder_summary_get_unread_count (
 
315
                                value,
 
316
                                camel_folder_summary_get_unread_count (
362
317
                                CAMEL_FOLDER_SUMMARY (object)));
363
318
                        return;
364
319
 
365
320
                case PROP_DELETED_COUNT:
366
321
                        g_value_set_uint (
367
 
                                value, camel_folder_summary_get_deleted_count (
 
322
                                value,
 
323
                                camel_folder_summary_get_deleted_count (
368
324
                                CAMEL_FOLDER_SUMMARY (object)));
369
325
                        return;
370
326
 
371
327
                case PROP_JUNK_COUNT:
372
328
                        g_value_set_uint (
373
 
                                value, camel_folder_summary_get_junk_count (
 
329
                                value,
 
330
                                camel_folder_summary_get_junk_count (
374
331
                                CAMEL_FOLDER_SUMMARY (object)));
375
332
                        return;
376
333
 
377
334
                case PROP_JUNK_NOT_DELETED_COUNT:
378
335
                        g_value_set_uint (
379
 
                                value, camel_folder_summary_get_junk_not_deleted_count (
 
336
                                value,
 
337
                                camel_folder_summary_get_junk_not_deleted_count (
380
338
                                CAMEL_FOLDER_SUMMARY (object)));
381
339
                        return;
382
340
 
383
341
                case PROP_VISIBLE_COUNT:
384
342
                        g_value_set_uint (
385
 
                                value, camel_folder_summary_get_visible_count (
 
343
                                value,
 
344
                                camel_folder_summary_get_visible_count (
386
345
                                CAMEL_FOLDER_SUMMARY (object)));
387
346
                        return;
388
347
 
389
348
                case PROP_BUILD_CONTENT:
390
349
                        g_value_set_boolean (
391
 
                                value, camel_folder_summary_get_build_content (
 
350
                                value,
 
351
                                camel_folder_summary_get_build_content (
392
352
                                CAMEL_FOLDER_SUMMARY (object)));
393
353
                        return;
394
354
 
395
355
                case PROP_NEED_PREVIEW:
396
356
                        g_value_set_boolean (
397
 
                                value, camel_folder_summary_get_need_preview (
 
357
                                value,
 
358
                                camel_folder_summary_get_need_preview (
398
359
                                CAMEL_FOLDER_SUMMARY (object)));
399
360
                        return;
400
361
        }
894
855
 
895
856
        summary_object = G_OBJECT (summary);
896
857
 
897
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
858
        camel_folder_summary_lock (summary);
898
859
        g_object_freeze_notify (summary_object);
899
860
 
900
861
        old_flags = GPOINTER_TO_UINT (g_hash_table_lookup (summary->priv->uids, camel_message_info_uid (info)));
902
863
 
903
864
        if ((old_flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED) == (new_flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED)) {
904
865
                g_object_thaw_notify (summary_object);
905
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
866
                camel_folder_summary_unlock (summary);
906
867
                return FALSE;
907
868
        }
908
869
 
946
907
                GUINT_TO_POINTER (new_flags));
947
908
 
948
909
        g_object_thaw_notify (summary_object);
949
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
910
        camel_folder_summary_unlock (summary);
950
911
 
951
912
        return changed;
952
913
}
1147
1108
        }
1148
1109
 
1149
1110
        if (mi->summary) {
1150
 
                camel_folder_summary_lock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1111
                camel_folder_summary_lock (mi->summary);
1151
1112
                g_object_freeze_notify (G_OBJECT (mi->summary));
1152
1113
                counts_changed = camel_folder_summary_replace_flags (mi->summary, info);
1153
1114
        }
1155
1116
        if (!counts_changed && ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK))) {
1156
1117
                if (mi->summary) {
1157
1118
                        g_object_thaw_notify (G_OBJECT (mi->summary));
1158
 
                        camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1119
                        camel_folder_summary_unlock (mi->summary);
1159
1120
                }
1160
1121
                return FALSE;
1161
1122
        }
1162
1123
 
1163
1124
        if (mi->summary) {
1164
1125
                g_object_thaw_notify (G_OBJECT (mi->summary));
1165
 
                camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1126
                camel_folder_summary_unlock (mi->summary);
1166
1127
        }
1167
1128
 
1168
1129
        if (mi->summary && mi->summary->priv->folder && mi->uid) {
1380
1341
        summary->priv->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
1381
1342
 
1382
1343
        g_rec_mutex_init (&summary->priv->summary_lock);
1383
 
        g_rec_mutex_init (&summary->priv->io_lock);
1384
1344
        g_rec_mutex_init (&summary->priv->filter_lock);
1385
 
        g_rec_mutex_init (&summary->priv->alloc_lock);
1386
 
        g_rec_mutex_init (&summary->priv->ref_lock);
1387
1345
 
1388
1346
        summary->priv->cache_load_time = 0;
1389
1347
        summary->priv->timeout_handle = 0;
1636
1594
{
1637
1595
        guint32 uid;
1638
1596
 
1639
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1597
        camel_folder_summary_lock (summary);
1640
1598
 
1641
1599
        uid = summary->priv->nextuid++;
1642
1600
        camel_folder_summary_touch (summary);
1643
1601
 
1644
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1602
        camel_folder_summary_unlock (summary);
1645
1603
 
1646
1604
        return uid;
1647
1605
}
1659
1617
camel_folder_summary_set_next_uid (CamelFolderSummary *summary,
1660
1618
                                   guint32 uid)
1661
1619
{
1662
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1620
        camel_folder_summary_lock (summary);
1663
1621
 
1664
1622
        summary->priv->nextuid = MAX (summary->priv->nextuid, uid);
1665
1623
        camel_folder_summary_touch (summary);
1666
1624
 
1667
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1625
        camel_folder_summary_unlock (summary);
1668
1626
}
1669
1627
 
1670
1628
/**
1684
1642
 
1685
1643
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), 0);
1686
1644
 
1687
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1645
        camel_folder_summary_lock (summary);
1688
1646
 
1689
1647
        res = summary->priv->nextuid;
1690
1648
 
1691
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1649
        camel_folder_summary_unlock (summary);
1692
1650
 
1693
1651
        return res;
1694
1652
}
1752
1710
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
1753
1711
        g_return_val_if_fail (uid != NULL, FALSE);
1754
1712
 
1755
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1713
        camel_folder_summary_lock (summary);
1756
1714
 
1757
1715
        ret = g_hash_table_lookup_extended (summary->priv->uids, uid, NULL, NULL);
1758
1716
 
1759
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1717
        camel_folder_summary_unlock (summary);
1760
1718
 
1761
1719
        return ret;
1762
1720
}
1789
1747
 
1790
1748
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
1791
1749
 
1792
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1750
        camel_folder_summary_lock (summary);
1793
1751
 
1794
1752
        res = g_ptr_array_sized_new (g_hash_table_size (summary->priv->uids));
1795
1753
        g_hash_table_foreach (summary->priv->uids, folder_summary_dupe_uids_to_array, res);
1796
1754
 
1797
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1755
        camel_folder_summary_unlock (summary);
1798
1756
 
1799
1757
        return res;
1800
1758
}
1847
1805
 
1848
1806
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
1849
1807
 
1850
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1808
        camel_folder_summary_lock (summary);
1851
1809
 
1852
1810
        /* using direct hash because of strings being from the string pool */
1853
1811
        uids = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) camel_pstring_free, NULL);
1854
1812
        g_hash_table_foreach (summary->priv->uids, cfs_copy_uids_cb, uids);
1855
1813
 
1856
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1814
        camel_folder_summary_unlock (summary);
1857
1815
 
1858
1816
        return uids;
1859
1817
}
1892
1850
        CamelMessageInfo *info;
1893
1851
        gint ret;
1894
1852
 
1895
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1853
        camel_folder_summary_lock (summary);
1896
1854
 
1897
1855
        info = g_hash_table_lookup (summary->priv->loaded_infos, uid);
1898
1856
 
1905
1863
                folder_name = camel_folder_get_full_name (summary->priv->folder);
1906
1864
 
1907
1865
                if (is_in_memory_summary (summary)) {
1908
 
                        camel_folder_summary_unlock (
1909
 
                                summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1866
                        camel_folder_summary_unlock (summary);
1910
1867
                        g_warning (
1911
1868
                                "%s: Tried to load uid '%s' "
1912
1869
                                "from DB on in-memory summary of '%s'",
1929
1886
                        g_hash_table_destroy (data.columns_hash);
1930
1887
 
1931
1888
                if (ret != 0) {
1932
 
                        camel_folder_summary_unlock (
1933
 
                                summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1889
                        camel_folder_summary_unlock (summary);
1934
1890
                        return NULL;
1935
1891
                }
1936
1892
 
1943
1899
        if (info)
1944
1900
                camel_message_info_ref (info);
1945
1901
 
1946
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
1902
        camel_folder_summary_unlock (summary);
1947
1903
 
1948
1904
        return info;
1949
1905
}
1960
1916
 *
1961
1917
 * Returns: the summary item, or %NULL if the uid @uid is not available
1962
1918
 *
 
1919
 * See camel_folder_summary_get_info_flags().
 
1920
 *
1963
1921
 * Since: 3.4
1964
1922
 **/
1965
1923
CamelMessageInfo *
1977
1935
        return class->message_info_from_uid (summary, uid);
1978
1936
}
1979
1937
 
 
1938
/**
 
1939
 * camel_folder_summary_get_info_flags:
 
1940
 * @summary: a #CamelFolderSummary object
 
1941
 * @uid: a uid
 
1942
 *
 
1943
 * Retrieve CamelMessageInfo::flags for a message info with UID @uid.
 
1944
 * This is much quicker than camel_folder_summary_get(), because it
 
1945
 * doesn't require reading the message info from a disk.
 
1946
 *
 
1947
 * Returns: the flags currently stored for message info with UID @uid,
 
1948
 *          or (~0) on error
 
1949
 *
 
1950
 * Since: 3.12
 
1951
 **/
 
1952
guint32
 
1953
camel_folder_summary_get_info_flags (CamelFolderSummary *summary,
 
1954
                                     const gchar *uid)
 
1955
{
 
1956
        gpointer ptr_uid = NULL, ptr_flags = NULL;
 
1957
 
 
1958
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), (~0));
 
1959
        g_return_val_if_fail (uid != NULL, (~0));
 
1960
 
 
1961
        camel_folder_summary_lock (summary);
 
1962
        if (!g_hash_table_lookup_extended (summary->priv->uids, uid, &ptr_uid, &ptr_flags)) {
 
1963
                camel_folder_summary_unlock (summary);
 
1964
                return (~0);
 
1965
        }
 
1966
 
 
1967
        camel_folder_summary_unlock (summary);
 
1968
 
 
1969
        return GPOINTER_TO_UINT (ptr_flags);
 
1970
}
 
1971
 
1980
1972
static CamelMessageContentInfo *
1981
1973
perform_content_info_load_from_db (CamelFolderSummary *summary,
1982
1974
                                   CamelMIRecord *mir)
2012
2004
 
2013
2005
static void
2014
2006
gather_dirty_uids (gpointer key,
2015
 
                   gpointer value,
2016
 
                   gpointer user_data)
 
2007
                   gpointer value,
 
2008
                   gpointer user_data)
2017
2009
{
2018
2010
        const gchar *uid = key;
2019
2011
        CamelMessageInfoBase *info = value;
2025
2017
 
2026
2018
static void
2027
2019
gather_changed_uids (gpointer key,
2028
 
                     gpointer value,
2029
 
                     gpointer user_data)
 
2020
                     gpointer value,
 
2021
                     gpointer user_data)
2030
2022
{
2031
2023
        const gchar *uid = key;
2032
2024
        guint32 flags = GPOINTER_TO_UINT (value);
2047
2039
        GPtrArray *res;
2048
2040
        GHashTable *hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) camel_pstring_free, NULL);
2049
2041
 
2050
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2042
        camel_folder_summary_lock (summary);
2051
2043
 
2052
2044
        g_hash_table_foreach (summary->priv->loaded_infos, gather_dirty_uids, hash);
2053
2045
        g_hash_table_foreach (summary->priv->uids, gather_changed_uids, hash);
2055
2047
        res = g_ptr_array_sized_new (g_hash_table_size (hash));
2056
2048
        g_hash_table_foreach (hash, folder_summary_dupe_uids_to_array, res);
2057
2049
 
2058
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2050
        camel_folder_summary_unlock (summary);
2059
2051
 
2060
2052
        g_hash_table_destroy (hash);
2061
2053
 
2076
2068
{
2077
2069
        gint count = 0;
2078
2070
 
2079
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2071
        camel_folder_summary_lock (summary);
2080
2072
        g_hash_table_foreach (summary->priv->loaded_infos, (GHFunc) count_changed_uids, &count);
2081
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2073
        camel_folder_summary_unlock (summary);
2082
2074
 
2083
2075
        return count;
2084
2076
}
2109
2101
        if (time (NULL) - summary->priv->cache_load_time < SUMMARY_CACHE_DROP)
2110
2102
                return;
2111
2103
 
2112
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2104
        camel_folder_summary_lock (summary);
2113
2105
 
2114
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
2115
2106
        g_hash_table_foreach_remove (summary->priv->loaded_infos, (GHRFunc) remove_item, &to_remove_infos);
2116
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
2117
2107
 
2118
 
        g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_free, NULL);
 
2108
        g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_unref, NULL);
2119
2109
        g_slist_free (to_remove_infos);
2120
2110
 
2121
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2111
        camel_folder_summary_unlock (summary);
2122
2112
 
2123
2113
        summary->priv->cache_load_time = time (NULL);
2124
2114
}
2179
2169
                                SUMMARY_CACHE_DROP,
2180
2170
                                (GSourceFunc) cfs_try_release_memory,
2181
2171
                                g_object_ref (summary));
 
2172
                        g_source_set_name_by_id (
 
2173
                                summary->priv->timeout_handle,
 
2174
                                "[camel] cfs_try_release_memory");
2182
2175
                }
2183
2176
        }
2184
2177
 
2219
2212
                                camel_db_write_preview_record (parent_store->cdb_w, full_name, info->uid, info->preview, NULL);
2220
2213
                }
2221
2214
        }
2222
 
        camel_message_info_free (info);
 
2215
        camel_message_info_unref (info);
2223
2216
}
2224
2217
 
2225
2218
static void
2284
2277
                g_hash_table_destroy (preview_data);
2285
2278
        }
2286
2279
 
2287
 
        camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2280
        camel_folder_summary_lock (folder->summary);
2288
2281
        g_hash_table_foreach (folder->summary->priv->loaded_infos, (GHFunc) pick_uids, uids_uncached);
2289
 
        camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2282
        camel_folder_summary_unlock (folder->summary);
2290
2283
 
2291
2284
        for (i = 0; i < uids_uncached->len; i++) {
2292
2285
                g_hash_table_remove (uids_hash, uids_uncached->pdata[i]);
2293
2286
        }
2294
2287
 
2295
 
        camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
 
2288
        camel_folder_lock (folder);
2296
2289
        if (!is_in_memory)
2297
2290
                camel_db_begin_transaction (parent_store->cdb_w, NULL);
2298
2291
        g_hash_table_foreach (uids_hash, (GHFunc) msg_update_preview, folder);
2299
2292
        if (!is_in_memory)
2300
2293
                camel_db_end_transaction (parent_store->cdb_w, NULL);
2301
 
        camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
 
2294
        camel_folder_unlock (folder);
2302
2295
        camel_folder_free_uids (folder, uids_uncached);
2303
2296
        g_hash_table_destroy (uids_hash);
2304
2297
}
2310
2303
                    GError **error)
2311
2304
{
2312
2305
        CamelDB *cdb;
2313
 
        CamelSession *session;
2314
2306
        CamelStore *parent_store;
2315
2307
        const gchar *folder_name;
2316
2308
        gint ret = 0;
2325
2317
 
2326
2318
        folder_name = camel_folder_get_full_name (summary->priv->folder);
2327
2319
        parent_store = camel_folder_get_parent_store (summary->priv->folder);
2328
 
        session = camel_service_ref_session (CAMEL_SERVICE (parent_store));
2329
2320
        cdb = parent_store->cdb_r;
2330
2321
 
2331
2322
        data.columns_hash = NULL;
2341
2332
 
2342
2333
        cfs_schedule_info_release_timer (summary);
2343
2334
 
2344
 
        if (summary->priv->need_preview)
2345
 
                camel_session_submit_job (
2346
 
                        session,
2347
 
                        (CamelSessionCallback) preview_update,
2348
 
                        g_object_ref (summary->priv->folder),
2349
 
                        (GDestroyNotify) g_object_unref);
 
2335
        /* FIXME Convert this to a GTask, submitted through
 
2336
         *       camel_service_queue_task().  Then it won't
 
2337
         *       have to call camel_folder_lock/unlock(). */
 
2338
        if (summary->priv->need_preview) {
 
2339
                CamelSession *session;
2350
2340
 
2351
 
        g_object_unref (session);
 
2341
                /* This may not be available in a case of this being called as part
 
2342
                   of CamelSession's dispose, because the CamelService uses GWeakRef
 
2343
                   object which is invalidates its content when it reaches the dispose. */
 
2344
                session = camel_service_ref_session (CAMEL_SERVICE (parent_store));
 
2345
                if (session) {
 
2346
                        camel_session_submit_job (
 
2347
                                session,
 
2348
                                (CamelSessionCallback) preview_update,
 
2349
                                g_object_ref (summary->priv->folder),
 
2350
                                (GDestroyNotify) g_object_unref);
 
2351
                        g_object_unref (session);
 
2352
                }
 
2353
        }
2352
2354
 
2353
2355
        return ret == 0 ? 0 : -1;
2354
2356
}
2362
2364
camel_folder_summary_add_preview (CamelFolderSummary *summary,
2363
2365
                                  CamelMessageInfo *info)
2364
2366
{
2365
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2367
        camel_folder_summary_lock (summary);
2366
2368
        g_hash_table_insert (summary->priv->preview_updates, (gchar *) info->uid, ((CamelMessageInfoBase *) info)->preview);
2367
2369
        camel_folder_summary_touch (summary);
2368
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2370
        camel_folder_summary_unlock (summary);
2369
2371
}
2370
2372
 
2371
2373
/**
2392
2394
        known = camel_folder_summary_count (summary);
2393
2395
 
2394
2396
        if (known - loaded > 50) {
2395
 
                camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2397
                camel_folder_summary_lock (summary);
2396
2398
                cfs_reload_from_db (summary, error);
2397
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2399
                camel_folder_summary_unlock (summary);
2398
2400
        }
2399
2401
 
2400
2402
        /* update also cache load time, even when not loaded anything */
2421
2423
        if (is_in_memory_summary (summary))
2422
2424
                return TRUE;
2423
2425
 
2424
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2426
        camel_folder_summary_lock (summary);
2425
2427
        camel_folder_summary_save_to_db (summary, NULL);
2426
2428
 
2427
2429
        /* struct _db_pass_data data; */
2430
2432
        full_name = camel_folder_get_full_name (summary->priv->folder);
2431
2433
        parent_store = camel_folder_get_parent_store (summary->priv->folder);
2432
2434
        if (!camel_folder_summary_header_load_from_db (summary, parent_store, full_name, error)) {
2433
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2435
                camel_folder_summary_unlock (summary);
2434
2436
                return FALSE;
2435
2437
        }
2436
2438
 
2449
2451
        } else if (local_error != NULL)
2450
2452
                g_propagate_error (error, local_error);
2451
2453
 
2452
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2454
        camel_folder_summary_unlock (summary);
2453
2455
 
2454
2456
        return ret == 0;
2455
2457
}
2567
2569
        mir = g_new0 (CamelMIRecord , 1);
2568
2570
        mir_from_cols (mir, summary, &data->columns_hash, ncol, cols, name);
2569
2571
 
2570
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2572
        camel_folder_summary_lock (summary);
2571
2573
        if (!mir->uid || g_hash_table_lookup (summary->priv->loaded_infos, mir->uid)) {
2572
2574
                /* Unlock and better return */
2573
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2575
                camel_folder_summary_unlock (summary);
2574
2576
                camel_db_camel_mir_free (mir);
2575
2577
                return ret;
2576
2578
        }
2577
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2579
        camel_folder_summary_unlock (summary);
2578
2580
 
2579
2581
        info = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_from_db (summary, mir);
2580
2582
 
2586
2588
                        /* FIXME: this should be done differently, how i don't know */
2587
2589
                        ((CamelMessageInfoBase *) info)->content = perform_content_info_load_from_db (summary, mir);
2588
2590
                        if (((CamelMessageInfoBase *) info)->content == NULL) {
2589
 
                                camel_message_info_free (info);
 
2591
                                camel_message_info_unref (info);
2590
2592
                                info = NULL;
2591
2593
                        }
2592
2594
                        mir->cinfo = tmp;
2640
2642
        return TRUE;
2641
2643
}
2642
2644
 
2643
 
typedef struct {
2644
 
        GError **error;
2645
 
        gboolean migration;
2646
 
        gint progress;
2647
 
} SaveToDBArgs;
2648
 
 
2649
2645
static void
2650
2646
save_to_db_cb (gpointer key,
2651
2647
               gpointer value,
2652
2648
               gpointer data)
2653
2649
{
2654
 
        SaveToDBArgs *args = (SaveToDBArgs *) data;
2655
 
        GError **error = args->error;
2656
2650
        CamelMessageInfoBase *mi = (CamelMessageInfoBase *) value;
2657
2651
        CamelFolderSummary *summary = (CamelFolderSummary *) mi->summary;
2658
2652
        CamelStore *parent_store;
2659
2653
        const gchar *full_name;
2660
2654
        CamelDB *cdb;
2661
2655
        CamelMIRecord *mir;
 
2656
        GError **error = data;
2662
2657
 
2663
2658
        full_name = camel_folder_get_full_name (summary->priv->folder);
2664
2659
        parent_store = camel_folder_get_parent_store (summary->priv->folder);
2665
2660
        cdb = parent_store->cdb_w;
2666
2661
 
2667
 
        if (!args->migration && !mi->dirty)
 
2662
        if (!mi->dirty)
2668
2663
                return;
2669
2664
 
2670
2665
        mir = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_to_db (summary, (CamelMessageInfo *) mi);
2680
2675
 
2681
2676
        g_return_if_fail (mir != NULL);
2682
2677
 
2683
 
        if (!args->migration) {
2684
 
                if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
2685
 
                        camel_db_camel_mir_free (mir);
2686
 
                        return;
2687
 
                }
2688
 
        } else {
2689
 
                if (camel_db_write_fresh_message_info_record (cdb, CAMEL_DB_IN_MEMORY_TABLE, mir, error) != 0) {
2690
 
                        camel_db_camel_mir_free (mir);
2691
 
                        return;
2692
 
                }
2693
 
 
2694
 
                if (args->progress > CAMEL_DB_IN_MEMORY_TABLE_LIMIT) {
2695
 
                    g_print ("BULK INsert limit reached \n");
2696
 
                        camel_db_flush_in_memory_transactions (cdb, full_name, error);
2697
 
                        camel_db_start_in_memory_transactions (cdb, error);
2698
 
                        args->progress = 0;
2699
 
                } else {
2700
 
                        args->progress++;
2701
 
                }
 
2678
        if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
 
2679
                camel_db_camel_mir_free (mir);
 
2680
                return;
2702
2681
        }
2703
2682
 
2704
2683
        /* Reset the dirty flag which decides if the changes are synced to the DB or not.
2711
2690
 
2712
2691
static gint
2713
2692
save_message_infos_to_db (CamelFolderSummary *summary,
2714
 
                          gboolean fresh_mirs,
2715
2693
                          GError **error)
2716
2694
{
2717
2695
        CamelStore *parent_store;
2718
2696
        CamelDB *cdb;
2719
2697
        const gchar *full_name;
2720
 
        SaveToDBArgs args;
2721
2698
 
2722
2699
        if (is_in_memory_summary (summary))
2723
2700
                return 0;
2724
2701
 
2725
 
        args.error = error;
2726
 
        args.migration = fresh_mirs;
2727
 
        args.progress = 0;
2728
 
 
2729
2702
        full_name = camel_folder_get_full_name (summary->priv->folder);
2730
2703
        parent_store = camel_folder_get_parent_store (summary->priv->folder);
2731
2704
        cdb = parent_store->cdb_w;
2733
2706
        if (camel_db_prepare_message_info_table (cdb, full_name, error) != 0)
2734
2707
                return -1;
2735
2708
 
2736
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2709
        camel_folder_summary_lock (summary);
2737
2710
 
2738
2711
        /* Push MessageInfo-es */
2739
2712
        camel_db_begin_transaction (cdb, NULL);
2740
 
        g_hash_table_foreach (summary->priv->loaded_infos, save_to_db_cb, &args);
 
2713
        g_hash_table_foreach (summary->priv->loaded_infos, save_to_db_cb, error);
2741
2714
        camel_db_end_transaction (cdb, NULL);
2742
2715
 
2743
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2716
        camel_folder_summary_unlock (summary);
2744
2717
        cfs_schedule_info_release_timer (summary);
2745
2718
 
2746
2719
        return 0;
2784
2757
        parent_store = camel_folder_get_parent_store (summary->priv->folder);
2785
2758
        cdb = parent_store->cdb_w;
2786
2759
 
2787
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2760
        camel_folder_summary_lock (summary);
2788
2761
 
2789
2762
        d (printf ("\ncamel_folder_summary_save_to_db called \n"));
2790
2763
        if (summary->priv->need_preview && g_hash_table_size (summary->priv->preview_updates)) {
2799
2772
        count = cfs_count_dirty (summary);
2800
2773
        if (!count) {
2801
2774
                gboolean res = camel_folder_summary_header_save_to_db (summary, error);
2802
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2775
                camel_folder_summary_unlock (summary);
2803
2776
                return res;
2804
2777
        }
2805
2778
 
2806
 
        ret = save_message_infos_to_db (summary, FALSE, error);
 
2779
        ret = save_message_infos_to_db (summary, error);
2807
2780
        if (ret != 0) {
2808
2781
                /* Failed, so lets reset the flag */
2809
2782
                summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
2810
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2783
                camel_folder_summary_unlock (summary);
2811
2784
                return FALSE;
2812
2785
        }
2813
2786
 
2825
2798
                camel_db_reset_folder_version (cdb, full_name, 0, NULL);
2826
2799
                camel_db_end_transaction (cdb, NULL);
2827
2800
 
2828
 
                ret = save_message_infos_to_db (summary, FALSE, error);
 
2801
                ret = save_message_infos_to_db (summary, error);
2829
2802
                if (ret != 0) {
2830
2803
                        summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
2831
 
                        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2804
                        camel_folder_summary_unlock (summary);
2832
2805
                        return FALSE;
2833
2806
                }
2834
2807
        }
2836
2809
        record = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_to_db (summary, error);
2837
2810
        if (!record) {
2838
2811
                summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
2839
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2812
                camel_folder_summary_unlock (summary);
2840
2813
                return FALSE;
2841
2814
        }
2842
2815
 
2849
2822
        if (ret != 0) {
2850
2823
                camel_db_abort_transaction (cdb, NULL);
2851
2824
                summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
2852
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2825
                camel_folder_summary_unlock (summary);
2853
2826
                return FALSE;
2854
2827
        }
2855
2828
 
2856
2829
        camel_db_end_transaction (cdb, NULL);
2857
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2830
        camel_folder_summary_unlock (summary);
2858
2831
 
2859
2832
        return ret == 0;
2860
2833
}
2878
2851
 
2879
2852
        parent_store = camel_folder_get_parent_store (summary->priv->folder);
2880
2853
        cdb = parent_store->cdb_w;
2881
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2854
        camel_folder_summary_lock (summary);
2882
2855
 
2883
2856
        d (printf ("\ncamel_folder_summary_header_save_to_db called \n"));
2884
2857
 
2885
2858
        record = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_to_db (summary, error);
2886
2859
        if (!record) {
2887
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2860
                camel_folder_summary_unlock (summary);
2888
2861
                return FALSE;
2889
2862
        }
2890
2863
 
2896
2869
 
2897
2870
        if (ret != 0) {
2898
2871
                camel_db_abort_transaction (cdb, NULL);
2899
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2872
                camel_folder_summary_unlock (summary);
2900
2873
                return FALSE;
2901
2874
        }
2902
2875
 
2903
2876
        camel_db_end_transaction (cdb, NULL);
2904
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2877
        camel_folder_summary_unlock (summary);
2905
2878
 
2906
2879
        return ret == 0;
2907
2880
}
2926
2899
        if (is_in_memory_summary (summary))
2927
2900
                return TRUE;
2928
2901
 
2929
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2902
        camel_folder_summary_lock (summary);
2930
2903
        camel_folder_summary_save_to_db (summary, NULL);
2931
2904
 
2932
2905
        cdb = store->cdb_r;
2936
2909
 
2937
2910
        ret = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_from_db (summary, record);
2938
2911
 
2939
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2912
        camel_folder_summary_unlock (summary);
2940
2913
 
2941
2914
        g_free (record->folder_name);
2942
2915
        g_free (record->bdata);
2959
2932
                uid = info->uid = (gchar *) camel_pstring_add (camel_folder_summary_next_uid_string (summary), TRUE);
2960
2933
        }
2961
2934
 
2962
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2935
        camel_folder_summary_lock (summary);
2963
2936
 
2964
2937
        while ((mi = g_hash_table_lookup (summary->priv->loaded_infos, uid))) {
2965
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2938
                camel_folder_summary_unlock (summary);
2966
2939
 
2967
2940
                if (mi == info)
2968
2941
                        return FALSE;
2973
2946
                uid = info->uid = camel_pstring_add (camel_folder_summary_next_uid_string (summary), TRUE);
2974
2947
                camel_message_info_set_flags (info, CAMEL_MESSAGE_FOLDER_FLAGGED, CAMEL_MESSAGE_FOLDER_FLAGGED);
2975
2948
 
2976
 
                camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2949
                camel_folder_summary_lock (summary);
2977
2950
        }
2978
2951
 
2979
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2952
        camel_folder_summary_unlock (summary);
2980
2953
 
2981
2954
        return TRUE;
2982
2955
}
3005
2978
        if (info == NULL)
3006
2979
                return;
3007
2980
 
3008
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2981
        camel_folder_summary_lock (summary);
3009
2982
        if (!summary_assign_uid (summary, info)) {
3010
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
2983
                camel_folder_summary_unlock (summary);
3011
2984
                return;
3012
2985
        }
3013
2986
 
3026
2999
 
3027
3000
        camel_folder_summary_touch (summary);
3028
3001
 
3029
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3002
        camel_folder_summary_unlock (summary);
3030
3003
}
3031
3004
 
3032
3005
/**
3044
3017
        if (info == NULL)
3045
3018
                return;
3046
3019
 
3047
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3020
        camel_folder_summary_lock (summary);
3048
3021
 
3049
3022
        if (!load) {
3050
3023
                CamelMessageInfoBase *base_info = (CamelMessageInfoBase *) info;
3064
3037
        /* Summary always holds a ref for the loaded infos */
3065
3038
        g_hash_table_insert (summary->priv->loaded_infos, (gchar *) camel_message_info_uid (info), info);
3066
3039
 
3067
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
3068
 
}
3069
 
 
3070
 
/**
3071
 
 * camel_folder_summary_add_from_header:
3072
 
 * @summary: a #CamelFolderSummary object
3073
 
 * @headers: rfc822 headers
3074
 
 *
3075
 
 * Build a new info record based on a set of headers, and add it to
3076
 
 * the summary.
3077
 
 *
3078
 
 * Note that this function should not be used if build_content_info
3079
 
 * has been specified for this summary.
3080
 
 *
3081
 
 * Returns: the newly added record
3082
 
 **/
3083
 
CamelMessageInfo *
3084
 
camel_folder_summary_add_from_header (CamelFolderSummary *summary,
3085
 
                                      struct _camel_header_raw *h)
3086
 
{
3087
 
        CamelMessageInfo *info;
3088
 
 
3089
 
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
3090
 
 
3091
 
        info = camel_folder_summary_info_new_from_header (summary, h);
3092
 
 
3093
 
        camel_folder_summary_add (summary, info);
3094
 
 
3095
 
        return info;
3096
 
}
3097
 
 
3098
 
/**
3099
 
 * camel_folder_summary_add_from_parser:
3100
 
 * @summary: a #CamelFolderSummary object
3101
 
 * @parser: a #CamelMimeParser object
3102
 
 *
3103
 
 * Build a new info record based on the current position of a #CamelMimeParser.
3104
 
 *
3105
 
 * The parser should be positioned before the start of the message to summarise.
3106
 
 * This function may be used if build_contnet_info or an index has been
3107
 
 * specified for the summary.
3108
 
 *
3109
 
 * Returns: the newly added record
3110
 
 **/
3111
 
CamelMessageInfo *
3112
 
camel_folder_summary_add_from_parser (CamelFolderSummary *summary,
3113
 
                                      CamelMimeParser *mp)
3114
 
{
3115
 
        CamelMessageInfo *info;
3116
 
 
3117
 
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
3118
 
        g_return_val_if_fail (CAMEL_IS_MIME_PARSER (mp), NULL);
3119
 
 
3120
 
        info = camel_folder_summary_info_new_from_parser (summary, mp);
3121
 
 
3122
 
        camel_folder_summary_add (summary, info);
3123
 
 
3124
 
        return info;
3125
 
}
3126
 
 
3127
 
/**
3128
 
 * camel_folder_summary_add_from_message:
3129
 
 * @summary: a #CamelFolderSummary object
3130
 
 * @message: a #CamelMimeMessage object
3131
 
 *
3132
 
 * Add a summary item from an existing message.
3133
 
 *
3134
 
 * Returns: the newly added record
3135
 
 **/
3136
 
CamelMessageInfo *
3137
 
camel_folder_summary_add_from_message (CamelFolderSummary *summary,
3138
 
                                       CamelMimeMessage *msg)
3139
 
{
3140
 
        CamelMessageInfo *info = camel_folder_summary_info_new_from_message (summary, msg, NULL);
3141
 
 
3142
 
        camel_folder_summary_add (summary, info);
3143
 
 
3144
 
        return info;
 
3040
        camel_folder_summary_unlock (summary);
3145
3041
}
3146
3042
 
3147
3043
/**
3151
3047
 *
3152
3048
 * Create a new info record from a header.
3153
3049
 *
3154
 
 * Returns: the newly allocated record which must be freed with
3155
 
 * camel_message_info_free()
 
3050
 * Returns: the newly allocated record which must be unreferenced with
 
3051
 *          camel_message_info_unref()
3156
3052
 **/
3157
3053
CamelMessageInfo *
3158
3054
camel_folder_summary_info_new_from_header (CamelFolderSummary *summary,
3186
3082
 * Once complete, the parser will be positioned at the end of
3187
3083
 * the message.
3188
3084
 *
3189
 
 * Returns: the newly allocated record which must be freed with
3190
 
 * camel_message_info_free()
 
3085
 * Returns: the newly allocated record which must be unreferenced with
 
3086
 *          camel_message_info_unref()
3191
3087
 **/
3192
3088
CamelMessageInfo *
3193
3089
camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary,
3213
3109
                if (p->index)
3214
3110
                        summary_assign_uid (summary, info);
3215
3111
 
3216
 
                camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_FILTER_LOCK);
 
3112
                g_rec_mutex_lock (&summary->priv->filter_lock);
3217
3113
 
3218
3114
                if (p->index) {
3219
3115
                        if (p->filter_index == NULL)
3233
3129
                                CAMEL_MIME_FILTER_INDEX (p->filter_index), NULL);
3234
3130
                }
3235
3131
 
3236
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_FILTER_LOCK);
 
3132
                g_rec_mutex_unlock (&summary->priv->filter_lock);
3237
3133
 
3238
3134
                ((CamelMessageInfoBase *) info)->size = camel_mime_parser_tell (mp) - start;
3239
3135
        }
3242
3138
 
3243
3139
/**
3244
3140
 * camel_folder_summary_info_new_from_message:
3245
 
 * @summary: a #CamelFodlerSummary object
 
3141
 * @summary: a #CamelFolderSummary object
3246
3142
 * @message: a #CamelMimeMessage object
3247
3143
 * @bodystructure: a bodystructure or NULL
3248
3144
 *
3249
3145
 * Create a summary item from a message.
3250
3146
 *
3251
 
 * Returns: the newly allocated record which must be freed using
3252
 
 * camel_message_info_free()
 
3147
 * Returns: the newly allocated record which must be unreferenced with
 
3148
 *          camel_message_info_unref()
3253
3149
 **/
3254
3150
CamelMessageInfo *
3255
3151
camel_folder_summary_info_new_from_message (CamelFolderSummary *summary,
3267
3163
        if (p->index)
3268
3164
                summary_assign_uid (summary, info);
3269
3165
 
3270
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_FILTER_LOCK);
 
3166
        g_rec_mutex_lock (&summary->priv->filter_lock);
3271
3167
 
3272
3168
        if (p->index) {
3273
3169
                if (p->filter_index == NULL)
3294
3190
                        CAMEL_MIME_FILTER_INDEX (p->filter_index), NULL);
3295
3191
        }
3296
3192
 
3297
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_FILTER_LOCK);
 
3193
        g_rec_mutex_unlock (&summary->priv->filter_lock);
3298
3194
 
3299
3195
        return info;
3300
3196
}
3331
3227
void
3332
3228
camel_folder_summary_touch (CamelFolderSummary *summary)
3333
3229
{
3334
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3230
        camel_folder_summary_lock (summary);
3335
3231
        summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
3336
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3232
        camel_folder_summary_unlock (summary);
3337
3233
}
3338
3234
 
3339
3235
/**
3354
3250
 
3355
3251
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
3356
3252
 
3357
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3253
        camel_folder_summary_lock (summary);
3358
3254
        if (camel_folder_summary_count (summary) == 0) {
3359
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3255
                camel_folder_summary_unlock (summary);
3360
3256
                return TRUE;
3361
3257
        }
3362
3258
 
3392
3288
        g_object_notify (summary_object, "visible-count");
3393
3289
        g_object_thaw_notify (summary_object);
3394
3290
 
3395
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3291
        camel_folder_summary_unlock (summary);
3396
3292
 
3397
3293
        return res;
3398
3294
}
3414
3310
        g_return_val_if_fail (info != NULL, FALSE);
3415
3311
 
3416
3312
        if (camel_folder_summary_remove_uid (summary, camel_message_info_uid (info))) {
3417
 
                camel_message_info_free (info);
 
3313
                camel_message_info_unref (info);
3418
3314
                return TRUE;
3419
3315
        }
3420
3316
 
3443
3339
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
3444
3340
        g_return_val_if_fail (uid != NULL, FALSE);
3445
3341
 
3446
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3342
        camel_folder_summary_lock (summary);
3447
3343
        if (!g_hash_table_lookup_extended (summary->priv->uids, uid, &ptr_uid, &ptr_flags)) {
3448
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3344
                camel_folder_summary_unlock (summary);
3449
3345
                return FALSE;
3450
3346
        }
3451
3347
 
3465
3361
        camel_pstring_free (uid_copy);
3466
3362
 
3467
3363
        camel_folder_summary_touch (summary);
3468
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3364
        camel_folder_summary_unlock (summary);
3469
3365
 
3470
3366
        return res;
3471
3367
}
3494
3390
        g_return_val_if_fail (uids != NULL, FALSE);
3495
3391
 
3496
3392
        g_object_freeze_notify (G_OBJECT (summary));
3497
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3393
        camel_folder_summary_lock (summary);
3498
3394
 
3499
3395
        for (l = g_list_first (uids); l; l = g_list_next (l)) {
3500
3396
                gpointer ptr_uid = NULL, ptr_flags = NULL;
3509
3405
                        g_hash_table_remove (summary->priv->loaded_infos, uid_copy);
3510
3406
 
3511
3407
                        if (mi)
3512
 
                                camel_message_info_free (mi);
 
3408
                                camel_message_info_unref (mi);
3513
3409
                        camel_pstring_free (uid_copy);
3514
3410
                }
3515
3411
        }
3522
3418
        }
3523
3419
 
3524
3420
        camel_folder_summary_touch (summary);
3525
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3421
        camel_folder_summary_unlock (summary);
3526
3422
        g_object_thaw_notify (G_OBJECT (summary));
3527
3423
 
3528
3424
        return res;
3689
3585
camel_folder_summary_content_info_new (CamelFolderSummary *summary)
3690
3586
{
3691
3587
        CamelFolderSummaryClass *class;
3692
 
        CamelMessageContentInfo *ci;
3693
3588
 
3694
3589
        class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
3695
 
 
3696
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_ALLOC_LOCK);
3697
 
        ci = g_slice_alloc0 (class->content_info_size);
3698
 
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_ALLOC_LOCK);
3699
 
 
3700
 
        return ci;
 
3590
        g_return_val_if_fail (class->content_info_size > 0, NULL);
 
3591
 
 
3592
        return g_slice_alloc0 (class->content_info_size);
3701
3593
}
3702
3594
 
3703
3595
static CamelMessageInfo *
3818
3710
 
3819
3711
        if (mi->uid) {
3820
3712
                if (summary) {
3821
 
                        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3713
                        camel_folder_summary_lock (summary);
3822
3714
                        if (g_hash_table_lookup (summary->priv->loaded_infos, mi->uid) == mi) {
3823
3715
                                g_hash_table_remove (summary->priv->loaded_infos, mi->uid);
3824
3716
                        }
3825
 
                        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
3717
                        camel_folder_summary_unlock (summary);
3826
3718
                }
3827
3719
                camel_pstring_free (mi->uid);
3828
3720
        }
4292
4184
                      CamelFlag **from)
4293
4185
{
4294
4186
        CamelFlag *flag, *tmp;
4295
 
        gint changed = FALSE;
 
4187
        gboolean changed = FALSE;
4296
4188
 
4297
4189
        if (*to == NULL && from == NULL)
4298
4190
                return FALSE;
4302
4194
        while (flag->next) {
4303
4195
                tmp = flag->next;
4304
4196
                if (!camel_flag_get (from, tmp->name)) {
 
4197
                        if (*tmp->name)
 
4198
                                changed = TRUE;
4305
4199
                        flag->next = tmp->next;
4306
4200
                        g_free (tmp);
4307
 
                        changed = TRUE;
4308
4201
                } else {
4309
4202
                        flag = tmp;
4310
4203
                }
4311
4204
        }
4312
4205
 
4313
 
        /* Add any new flags */
 
4206
        /* Add any new non-empty flags */
4314
4207
        flag = *from;
4315
4208
        while (flag) {
4316
 
                changed |= camel_flag_set (to, flag->name, TRUE);
 
4209
                if (*flag->name)
 
4210
                        changed |= camel_flag_set (to, flag->name, TRUE);
4317
4211
                flag = flag->next;
4318
4212
        }
4319
4213
 
4552
4446
{
4553
4447
        CamelFolderSummaryClass *class;
4554
4448
        CamelMessageInfo *info;
 
4449
        gsize message_info_size;
4555
4450
 
4556
 
        if (summary) {
4557
 
                camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_ALLOC_LOCK);
 
4451
        if (summary != NULL) {
4558
4452
                class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
4559
 
                info = g_slice_alloc0 (class->message_info_size);
4560
 
                camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_ALLOC_LOCK);
 
4453
                g_return_val_if_fail (class->message_info_size > 0, NULL);
 
4454
                message_info_size = class->message_info_size;
4561
4455
        } else {
4562
 
                info = g_slice_alloc0 (sizeof (CamelMessageInfoBase));
 
4456
                message_info_size = sizeof (CamelMessageInfoBase);
4563
4457
        }
4564
4458
 
 
4459
        info = g_slice_alloc0 (message_info_size);
4565
4460
        info->refcount = 1;
4566
4461
        info->summary = summary;
4567
4462
 
4582
4477
{
4583
4478
        CamelMessageInfo *mi = o;
4584
4479
 
4585
 
        if (mi->summary) {
4586
 
                camel_folder_summary_lock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
4587
 
                g_assert (mi->refcount >= 1);
4588
 
                mi->refcount++;
4589
 
                camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
4590
 
        } else {
4591
 
                GLOBAL_INFO_LOCK (info);
4592
 
                g_assert (mi->refcount >= 1);
4593
 
                mi->refcount++;
4594
 
                GLOBAL_INFO_UNLOCK (info);
4595
 
        }
 
4480
        g_return_val_if_fail (mi != NULL, NULL);
 
4481
        g_return_val_if_fail (mi->refcount > 0, NULL);
 
4482
 
 
4483
        g_atomic_int_inc (&mi->refcount);
4596
4484
 
4597
4485
        return o;
4598
4486
}
4619
4507
}
4620
4508
 
4621
4509
/**
4622
 
 * camel_message_info_free:
 
4510
 * camel_message_info_unref:
4623
4511
 * @info: a #CamelMessageInfo
4624
4512
 *
4625
4513
 * Unref's and potentially frees a #CamelMessageInfo and its contents.
4626
4514
 **/
4627
4515
void
4628
 
camel_message_info_free (gpointer o)
 
4516
camel_message_info_unref (gpointer o)
4629
4517
{
4630
4518
        CamelMessageInfo *mi = o;
4631
4519
 
4632
4520
        g_return_if_fail (mi != NULL);
4633
 
 
4634
 
        if (mi->summary) {
4635
 
                camel_folder_summary_lock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
4636
 
 
4637
 
                if (mi->refcount >= 1)
4638
 
                        mi->refcount--;
4639
 
                if (mi->refcount > 0) {
4640
 
                        camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
4641
 
                        return;
4642
 
                }
4643
 
 
4644
 
                camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
4645
 
 
4646
 
                /* FIXME: this is kinda busted, should really be handled by message info free */
4647
 
                if (mi->summary->priv->build_content
4648
 
                    && ((CamelMessageInfoBase *) mi)->content) {
4649
 
                        camel_folder_summary_content_info_free (mi->summary, ((CamelMessageInfoBase *) mi)->content);
4650
 
                        ((CamelMessageInfoBase *) mi)->content = NULL;
4651
 
                }
4652
 
 
4653
 
                CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->message_info_free (mi->summary, mi);
4654
 
        } else {
4655
 
                GLOBAL_INFO_LOCK (info);
4656
 
                mi->refcount--;
4657
 
                if (mi->refcount > 0) {
4658
 
                        GLOBAL_INFO_UNLOCK (info);
4659
 
                        return;
4660
 
                }
4661
 
                GLOBAL_INFO_UNLOCK (info);
4662
 
 
4663
 
                message_info_free (NULL, mi);
 
4521
        g_return_if_fail (mi->refcount > 0);
 
4522
 
 
4523
        if (g_atomic_int_dec_and_test (&mi->refcount)) {
 
4524
                if (mi->summary != NULL) {
 
4525
                        CamelFolderSummaryClass *class;
 
4526
 
 
4527
                        /* FIXME This is kinda busted, should really
 
4528
                         *       be handled by message_info_free(). */
 
4529
                        if (mi->summary->priv->build_content
 
4530
                            && ((CamelMessageInfoBase *) mi)->content) {
 
4531
                                camel_folder_summary_content_info_free (
 
4532
                                        mi->summary,
 
4533
                                        ((CamelMessageInfoBase *) mi)->content);
 
4534
                                ((CamelMessageInfoBase *) mi)->content = NULL;
 
4535
                        }
 
4536
 
 
4537
                        class = CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary);
 
4538
                        g_return_if_fail (class->message_info_free != NULL);
 
4539
 
 
4540
                        class->message_info_free (mi->summary, mi);
 
4541
                } else {
 
4542
                        message_info_free (NULL, mi);
 
4543
                }
4664
4544
        }
4665
4545
}
4666
4546
 
4685
4565
 
4686
4566
/**
4687
4567
 * camel_message_info_ptr:
4688
 
 * @mi: a #CamelMessageInfo
 
4568
 * @info: a #CamelMessageInfo
4689
4569
 * @id: info to get
4690
4570
 *
4691
4571
 * Generic accessor method for getting pointer data.
4693
4573
 * Returns: the pointer data
4694
4574
 **/
4695
4575
gconstpointer
4696
 
camel_message_info_ptr (const CamelMessageInfo *mi,
 
4576
camel_message_info_ptr (const CamelMessageInfo *info,
4697
4577
                        gint id)
4698
4578
{
4699
 
        if (mi->summary)
4700
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_ptr (mi, id);
 
4579
        if (info->summary)
 
4580
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_ptr (info, id);
4701
4581
        else
4702
 
                return info_ptr (mi, id);
 
4582
                return info_ptr (info, id);
4703
4583
}
4704
4584
 
4705
4585
/**
4706
4586
 * camel_message_info_uint32:
4707
 
 * @mi: a #CamelMessageInfo
 
4587
 * @info: a #CamelMessageInfo
4708
4588
 * @id: info to get
4709
4589
 *
4710
4590
 * Generic accessor method for getting 32bit gint data.
4712
4592
 * Returns: the gint data
4713
4593
 **/
4714
4594
guint32
4715
 
camel_message_info_uint32 (const CamelMessageInfo *mi,
 
4595
camel_message_info_uint32 (const CamelMessageInfo *info,
4716
4596
                           gint id)
4717
4597
{
4718
 
        if (mi->summary)
4719
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_uint32 (mi, id);
 
4598
        if (info->summary)
 
4599
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_uint32 (info, id);
4720
4600
        else
4721
 
                return info_uint32 (mi, id);
 
4601
                return info_uint32 (info, id);
4722
4602
}
4723
4603
 
4724
4604
/**
4725
4605
 * camel_message_info_time:
4726
 
 * @mi: a #CamelMessageInfo
 
4606
 * @info: a #CamelMessageInfo
4727
4607
 * @id: info to get
4728
4608
 *
4729
4609
 * Generic accessor method for getting time_t data.
4731
4611
 * Returns: the time_t data
4732
4612
 **/
4733
4613
time_t
4734
 
camel_message_info_time (const CamelMessageInfo *mi,
 
4614
camel_message_info_time (const CamelMessageInfo *info,
4735
4615
                         gint id)
4736
4616
{
4737
 
        if (mi->summary)
4738
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_time (mi, id);
 
4617
        if (info->summary)
 
4618
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_time (info, id);
4739
4619
        else
4740
 
                return info_time (mi, id);
 
4620
                return info_time (info, id);
4741
4621
}
4742
4622
 
4743
4623
/**
4744
4624
 * camel_message_info_user_flag:
4745
 
 * @mi: a #CamelMessageInfo
 
4625
 * @info: a #CamelMessageInfo
4746
4626
 * @id: user flag to get
4747
4627
 *
4748
4628
 * Get the state of a user flag named @id.
4750
4630
 * Returns: the state of the user flag
4751
4631
 **/
4752
4632
gboolean
4753
 
camel_message_info_user_flag (const CamelMessageInfo *mi,
 
4633
camel_message_info_user_flag (const CamelMessageInfo *info,
4754
4634
                              const gchar *id)
4755
4635
{
4756
 
        if (mi->summary)
4757
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_user_flag (mi, id);
 
4636
        if (info->summary)
 
4637
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_user_flag (info, id);
4758
4638
        else
4759
 
                return info_user_flag (mi, id);
 
4639
                return info_user_flag (info, id);
4760
4640
}
4761
4641
 
4762
4642
/**
4763
4643
 * camel_message_info_user_tag:
4764
 
 * @mi: a #CamelMessageInfo
 
4644
 * @info: a #CamelMessageInfo
4765
4645
 * @id: user tag to get
4766
4646
 *
4767
4647
 * Get the value of a user tag named @id.
4769
4649
 * Returns: the value of the user tag
4770
4650
 **/
4771
4651
const gchar *
4772
 
camel_message_info_user_tag (const CamelMessageInfo *mi,
 
4652
camel_message_info_user_tag (const CamelMessageInfo *info,
4773
4653
                             const gchar *id)
4774
4654
{
4775
 
        if (mi->summary)
4776
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_user_tag (mi, id);
 
4655
        if (info->summary)
 
4656
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_user_tag (info, id);
4777
4657
        else
4778
 
                return info_user_tag (mi, id);
 
4658
                return info_user_tag (info, id);
4779
4659
}
4780
4660
 
4781
4661
/**
4782
4662
 * camel_message_info_set_flags:
4783
 
 * @mi: a #CamelMessageInfo
 
4663
 * @info: a #CamelMessageInfo
4784
4664
 * @flags: mask of flags to change
4785
4665
 * @set: state the flags should be changed to
4786
4666
 *
4789
4669
 * Returns: %TRUE if any of the flags changed or %FALSE otherwise
4790
4670
 **/
4791
4671
gboolean
4792
 
camel_message_info_set_flags (CamelMessageInfo *mi,
 
4672
camel_message_info_set_flags (CamelMessageInfo *info,
4793
4673
                              CamelMessageFlags flags,
4794
4674
                              guint32 set)
4795
4675
{
4796
 
        if (mi->summary)
4797
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_set_flags (mi, flags, set);
 
4676
        if (info->summary)
 
4677
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_set_flags (info, flags, set);
4798
4678
        else
4799
 
                return info_set_flags (mi, flags, set);
 
4679
                return info_set_flags (info, flags, set);
4800
4680
}
4801
4681
 
4802
4682
/**
4803
4683
 * camel_message_info_set_user_flag:
4804
 
 * @mi: a #CamelMessageInfo
 
4684
 * @info: a #CamelMessageInfo
4805
4685
 * @id: name of the user flag to set
4806
4686
 * @state: state to set the flag to
4807
4687
 *
4810
4690
 * Returns: %TRUE if the state changed or %FALSE otherwise
4811
4691
 **/
4812
4692
gboolean
4813
 
camel_message_info_set_user_flag (CamelMessageInfo *mi,
 
4693
camel_message_info_set_user_flag (CamelMessageInfo *info,
4814
4694
                                  const gchar *id,
4815
4695
                                  gboolean state)
4816
4696
{
4817
 
        if (mi->summary)
4818
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_set_user_flag (mi, id, state);
 
4697
        if (info->summary)
 
4698
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_set_user_flag (info, id, state);
4819
4699
        else
4820
 
                return info_set_user_flag (mi, id, state);
 
4700
                return info_set_user_flag (info, id, state);
4821
4701
}
4822
4702
 
4823
4703
/**
4824
4704
 * camel_message_info_set_user_tag:
4825
 
 * @mi: a #CamelMessageInfo
 
4705
 * @info: a #CamelMessageInfo
4826
4706
 * @id: name of the user tag to set
4827
4707
 * @val: value to set
4828
4708
 *
4831
4711
 * Returns: %TRUE if the value changed or %FALSE otherwise
4832
4712
 **/
4833
4713
gboolean
4834
 
camel_message_info_set_user_tag (CamelMessageInfo *mi,
 
4714
camel_message_info_set_user_tag (CamelMessageInfo *info,
4835
4715
                                 const gchar *id,
4836
4716
                                 const gchar *val)
4837
4717
{
4838
 
        if (mi->summary)
4839
 
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->info_set_user_tag (mi, id, val);
 
4718
        if (info->summary)
 
4719
                return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_set_user_tag (info, id, val);
4840
4720
        else
4841
 
                return info_set_user_tag (mi, id, val);
 
4721
                return info_set_user_tag (info, id, val);
4842
4722
}
4843
4723
 
4844
4724
void
4878
4758
}
4879
4759
 
4880
4760
void
4881
 
camel_message_info_dump (CamelMessageInfo *mi)
 
4761
camel_message_info_dump (CamelMessageInfo *info)
4882
4762
{
4883
 
        if (mi == NULL) {
 
4763
        if (info == NULL) {
4884
4764
                printf ("No message?\n");
4885
4765
                return;
4886
4766
        }
4887
4767
 
4888
 
        printf ("Subject: %s\n", camel_message_info_subject (mi));
4889
 
        printf ("To: %s\n", camel_message_info_to (mi));
4890
 
        printf ("Cc: %s\n", camel_message_info_cc (mi));
4891
 
        printf ("mailing list: %s\n", camel_message_info_mlist (mi));
4892
 
        printf ("From: %s\n", camel_message_info_from (mi));
4893
 
        printf ("UID: %s\n", camel_message_info_uid (mi));
4894
 
        printf ("Flags: %04x\n", camel_message_info_flags (mi));
4895
 
        camel_content_info_dump (((CamelMessageInfoBase *) mi)->content, 0);
4896
 
}
4897
 
 
4898
 
static gboolean
4899
 
compare_strings (const gchar *str1,
4900
 
                 const gchar *str2)
4901
 
{
4902
 
        if (str1 && str2 && !g_ascii_strcasecmp (str1, str2))
4903
 
                return TRUE;
4904
 
        else if (!str1 && !str2)
4905
 
                return TRUE;
4906
 
        else
4907
 
                return FALSE;
4908
 
}
4909
 
 
4910
 
static gboolean
4911
 
match_content_type (CamelContentType *info_ctype,
4912
 
                    CamelContentType *ctype)
4913
 
{
4914
 
        const gchar *name1, *name2;
4915
 
 
4916
 
        if (!compare_strings (info_ctype->type, ctype->type))
4917
 
                return FALSE;
4918
 
        if (!compare_strings (info_ctype->subtype, ctype->subtype))
4919
 
                return FALSE;
4920
 
 
4921
 
        name1 = camel_content_type_param (info_ctype, "name");
4922
 
        name2 = camel_content_type_param (ctype, "name");
4923
 
        if (!compare_strings (name1, name2))
4924
 
                return FALSE;
4925
 
 
4926
 
        return TRUE;
4927
 
}
4928
 
 
4929
 
/**
4930
 
 * camel_folder_summary_guess_content_info:
4931
 
 * @mi: a #CamelMessageInfo
4932
 
 * @ctype: a #CamelContentType
4933
 
 *
4934
 
 * FIXME Document me!
4935
 
 *
4936
 
 * Since: 2.30
4937
 
 **/
4938
 
const CamelMessageContentInfo *
4939
 
camel_folder_summary_guess_content_info (CamelMessageInfo *mi,
4940
 
                                         CamelContentType *ctype)
4941
 
{
4942
 
        const CamelMessageContentInfo *ci = camel_message_info_content (mi);
4943
 
 
4944
 
        while (ci) {
4945
 
                const CamelMessageContentInfo *child = ci;
4946
 
 
4947
 
                do {
4948
 
                        if (child->type && match_content_type (child->type, ctype))
4949
 
                                return child;
4950
 
 
4951
 
                        child = child->next;
4952
 
                } while (child != NULL);
4953
 
 
4954
 
                ci = ci->childs;
4955
 
        }
4956
 
 
4957
 
        return NULL;
 
4768
        printf ("Subject: %s\n", camel_message_info_subject (info));
 
4769
        printf ("To: %s\n", camel_message_info_to (info));
 
4770
        printf ("Cc: %s\n", camel_message_info_cc (info));
 
4771
        printf ("mailing list: %s\n", camel_message_info_mlist (info));
 
4772
        printf ("From: %s\n", camel_message_info_from (info));
 
4773
        printf ("UID: %s\n", camel_message_info_uid (info));
 
4774
        printf ("Flags: %04x\n", camel_message_info_flags (info));
 
4775
        camel_content_info_dump (((CamelMessageInfoBase *) info)->content, 0);
4958
4776
}
4959
4777
 
4960
4778
/**
4961
4779
 * camel_folder_summary_lock:
4962
4780
 * @summary: a #CamelFolderSummary
4963
 
 * @lock: lock type to lock
4964
4781
 *
4965
 
 * Locks @summary's @lock. Unlock it with camel_folder_summary_unlock().
 
4782
 * Locks @summary. Unlock it with camel_folder_summary_unlock().
4966
4783
 *
4967
4784
 * Since: 2.32
4968
4785
 **/
4969
4786
void
4970
 
camel_folder_summary_lock (CamelFolderSummary *summary,
4971
 
                           CamelFolderSummaryLock lock)
 
4787
camel_folder_summary_lock (CamelFolderSummary *summary)
4972
4788
{
4973
4789
        g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
4974
4790
 
4975
 
        switch (lock) {
4976
 
                case CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK:
4977
 
                        g_rec_mutex_lock (&summary->priv->summary_lock);
4978
 
                        break;
4979
 
                case CAMEL_FOLDER_SUMMARY_IO_LOCK:
4980
 
                        g_rec_mutex_lock (&summary->priv->io_lock);
4981
 
                        break;
4982
 
                case CAMEL_FOLDER_SUMMARY_FILTER_LOCK:
4983
 
                        g_rec_mutex_lock (&summary->priv->filter_lock);
4984
 
                        break;
4985
 
                case CAMEL_FOLDER_SUMMARY_ALLOC_LOCK:
4986
 
                        g_rec_mutex_lock (&summary->priv->alloc_lock);
4987
 
                        break;
4988
 
                case CAMEL_FOLDER_SUMMARY_REF_LOCK:
4989
 
                        g_rec_mutex_lock (&summary->priv->ref_lock);
4990
 
                        break;
4991
 
                default:
4992
 
                        g_return_if_reached ();
4993
 
        }
 
4791
        g_rec_mutex_lock (&summary->priv->summary_lock);
4994
4792
}
4995
4793
 
4996
4794
/**
4997
4795
 * camel_folder_summary_unlock:
4998
4796
 * @summary: a #CamelFolderSummary
4999
 
 * @lock: lock type to unlock
5000
4797
 *
5001
 
 * Unlocks @summary's @lock, previously locked with camel_folder_summary_lock().
 
4798
 * Unlocks @summary, previously locked with camel_folder_summary_lock().
5002
4799
 *
5003
4800
 * Since: 2.32
5004
4801
 **/
5005
4802
void
5006
 
camel_folder_summary_unlock (CamelFolderSummary *summary,
5007
 
                             CamelFolderSummaryLock lock)
 
4803
camel_folder_summary_unlock (CamelFolderSummary *summary)
5008
4804
{
5009
4805
        g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
5010
4806
 
5011
 
        switch (lock) {
5012
 
                case CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK:
5013
 
                        g_rec_mutex_unlock (&summary->priv->summary_lock);
5014
 
                        break;
5015
 
                case CAMEL_FOLDER_SUMMARY_IO_LOCK:
5016
 
                        g_rec_mutex_unlock (&summary->priv->io_lock);
5017
 
                        break;
5018
 
                case CAMEL_FOLDER_SUMMARY_FILTER_LOCK:
5019
 
                        g_rec_mutex_unlock (&summary->priv->filter_lock);
5020
 
                        break;
5021
 
                case CAMEL_FOLDER_SUMMARY_ALLOC_LOCK:
5022
 
                        g_rec_mutex_unlock (&summary->priv->alloc_lock);
5023
 
                        break;
5024
 
                case CAMEL_FOLDER_SUMMARY_REF_LOCK:
5025
 
                        g_rec_mutex_unlock (&summary->priv->ref_lock);
5026
 
                        break;
5027
 
                default:
5028
 
                        g_return_if_reached ();
5029
 
        }
 
4807
        g_rec_mutex_unlock (&summary->priv->summary_lock);
5030
4808
}
5031
4809
 
5032
4810
gint