Changeset 2536
- Timestamp:
- 07/31/07 10:21:03
- Files:
-
- trunk/ChangeLog (modified) (2 diffs)
- trunk/bindings/python/tinymailmodule.c (modified) (2 diffs)
- trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c (modified) (1 diff)
- trunk/libtinymail-camel/tny-camel-account-priv.h (modified) (1 diff)
- trunk/libtinymail-camel/tny-camel-account.c (modified) (10 diffs)
- trunk/libtinymail-camel/tny-camel-account.h (modified) (3 diffs)
- trunk/libtinymail-camel/tny-camel-folder.c (modified) (108 diffs)
- trunk/libtinymail-camel/tny-camel-queue.c (modified) (4 diffs)
- trunk/libtinymail-camel/tny-camel-send-queue.c (modified) (3 diffs)
- trunk/libtinymail-camel/tny-camel-store-account-priv.h (modified) (2 diffs)
- trunk/libtinymail-camel/tny-camel-store-account.c (modified) (20 diffs)
- trunk/libtinymail-camel/tny-session-camel-priv.h (modified) (1 diff)
- trunk/libtinymail-camel/tny-session-camel.c (modified) (22 diffs)
- trunk/libtinymail-camel/tny-session-camel.h (modified) (1 diff)
- trunk/libtinymail-gnome-desktop/tny-gnome-account-store.c (modified) (2 diffs)
- trunk/libtinymail-gnome-desktop/tny-gnome-account-store.h (modified) (1 diff)
- trunk/libtinymail-gpe/tny-gpe-account-store.c (modified) (2 diffs)
- trunk/libtinymail-gpe/tny-gpe-account-store.h (modified) (1 diff)
- trunk/libtinymail-maemo/tny-maemo-account-store.c (modified) (2 diffs)
- trunk/libtinymail-maemo/tny-maemo-account-store.h (modified) (1 diff)
- trunk/libtinymail-olpc/tny-olpc-account-store.h (modified) (1 diff)
- trunk/libtinymail/tny-account-store.c (modified) (3 diffs)
- trunk/libtinymail/tny-account-store.h (modified) (2 diffs)
- trunk/libtinymail/tny-account.c (modified) (1 diff)
- trunk/libtinymail/tny-account.h (modified) (2 diffs)
- trunk/libtinymail/tny-combined-account.c (modified) (2 diffs)
- trunk/libtinymailui-gtk/tny-gtk-folder-store-tree-model.c (modified) (26 diffs)
- trunk/libtinymailui-gtk/tny-gtk-folder-store-tree-model.h (modified) (2 diffs)
- trunk/libtinymailui-gtk/tny-gtk-header-list-model.c (modified) (2 diffs)
- trunk/tests/c-demo/tny-demoui-summary-view.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r2534 r2536 1 2007-07-31 Philip Van Hoof <pvanhoof@gnome.org> 2 3 * Merging back devel/pvanhoof/sessionwork to trunk/ 4 5 2007-07-31 Philip Van Hoof <pvanhoof@gnome.org> 6 7 * Cleaning up, coding style fixes 8 * Review of TnyCamelFolder and TnyCamelStoreAccount 9 10 2007-07-30 Philip Van Hoof <pvanhoof@gnome.org> 11 12 * Various fixes that make Modest actually work with this 13 1 14 2007-07-30 Javier Fernandez Garcia-Boente <jfernandez@igalia.com> 2 15 … … 23 36 24 37 * Merging the Cond patch from devel/sessionwork 38 39 2007-07-29 Philip Van Hoof <pvanhoof@gnome.org> 40 41 * The long awaited alert, get_pass and forget_pass now in the mainloop 42 43 * This was a major API and behaviour change 44 45 2007-07-29 Philip Van Hoof <pvanhoof@gnome.org> 46 47 * Fixed a race condition when the account was or is connection or not 48 yet finished connecting while the connection-status-changed signal was 49 already being used. Introduced a new API for this 50 * Introduced the tny_account_is_ready API, which indicates when an 51 account is not only valid as instance, but also fully registered 52 within the system. 53 * Implemented some missing implementations in TnyCombinedAccount 54 55 * This was a major API change 56 57 2007-07-27 Philip Van Hoof <pvanhoof@gnome.org> 58 59 * Dealing with remotely removed folders 60 * The poke status calls are now on the same queue as the other 61 operations 62 * Rewritten the TnySessionCamel infrastructure that connects accounts 63 and sets them up 64 * Added support for detecting folder changes to 65 TnyGtkFolderStoreTreeModel 66 * API change on tny_camel_account_set_online. The last argument is now 67 a callback rather than a GError. In the callback you can know about 68 when the account got connected and if not, why it failed 69 70 * Cond locks in the queues of the store accounts while the callbacks 71 are happening. This is a significant policy change in locking 72 behaviour that should be well tested. 73 74 * This was a major API change in TnyAccount 75 76 2007-07-27 Philip Van Hoof <pvanhoof@gnome.org> 77 78 * Branchpoint "devel/sessionwork" 25 79 26 80 2007-07-26 Philip Van Hoof <pvanhoof@gnome.org> trunk/bindings/python/tinymailmodule.c
r643 r2536 2 2 3 3 void pytinymail_register_classes (PyObject *d); 4 void pytinymail_add_constants(PyObject *module, const gchar *strip_prefix); 4 /*void pytinymail_add_constants(PyObject *module, const gchar *strip_prefix);*/ 5 5 extern PyMethodDef pytinymail_functions[]; 6 6 … … 16 16 17 17 pytinymail_register_classes (d); 18 pytinymail_add_constants (m, "TNY_");18 /*pytinymail_add_constants (m, "TNY_");*/ 19 19 20 20 if (PyErr_Occurred ()) { trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c
r2443 r2536 1007 1007 { 1008 1008 int len = strlen (type), i; 1009 char *resp ;1010 1009 char *resp = NULL; 1010 1011 1011 len = strlen (type); 1012 1012 trunk/libtinymail-camel/tny-camel-account-priv.h
r2412 r2536 68 68 GList *chooks; 69 69 TnyConnectionStatus status; 70 gboolean is_connecting ;70 gboolean is_connecting, is_ready; 71 71 }; 72 72 trunk/libtinymail-camel/tny-camel-account.c
r2484 r2536 697 697 priv->session = session; 698 698 699 _tny_session_camel_ add_account_1(session, self);699 _tny_session_camel_register_account (session, self); 700 700 701 701 TNY_CAMEL_ACCOUNT_GET_CLASS (self)->prepare_func (self, FALSE, FALSE); … … 887 887 888 888 if (priv->session) 889 _tny_session_camel_a dd_account_2(priv->session, TNY_CAMEL_ACCOUNT (self));889 _tny_session_camel_activate_account (priv->session, TNY_CAMEL_ACCOUNT (self)); 890 890 891 891 g_static_rec_mutex_unlock (priv->service_lock); … … 1122 1122 TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 1123 1123 1124 priv->is_ready = FALSE; 1124 1125 priv->is_connecting = FALSE; 1125 1126 priv->in_auth = FALSE; … … 1160 1161 } 1161 1162 1162 /** 1163 * tny_camel_account_set_online: 1164 * @self: a #TnyCamelAccount object 1165 * @online: whether or not the account is online 1166 * @err: a #GError instance or NULL 1167 * 1168 * Set the connectivity status of an account. 1169 * Setting this to FALSE means that the account will not attempt to use the network, 1170 * and will use only the cache. 1171 * Setting this to TRUE means that the account may use the network to provide up-to-date 1172 * information. 1173 * 1174 **/ 1175 void 1176 tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err) 1177 { 1178 TNY_CAMEL_ACCOUNT_GET_CLASS (self)->set_online_func (self, online, err); 1179 } 1163 /* The is the protected version that will actually set it online. This should 1164 * always happen in a thread. In fact, it will always happen in the operations 1165 * queue of @self (else it's a bug). */ 1180 1166 1181 1167 void … … 1322 1308 1323 1309 1324 typedef struct { 1325 TnyCamelAccount *self; 1326 gboolean online; 1327 GError **err; 1328 GMainLoop *loop; 1329 } SetOnlineInfo; 1330 1331 static gpointer 1332 set_online_thread (gpointer data) 1333 { 1334 SetOnlineInfo *info = (SetOnlineInfo *) data; 1335 1336 _tny_camel_account_set_online (info->self, info->online, info->err); 1337 1338 if (g_main_loop_is_running (info->loop)) 1339 g_main_loop_quit (info->loop); 1340 1341 g_thread_exit (NULL); 1342 return NULL; 1343 } 1344 1310 1311 1312 1313 /** 1314 * tny_camel_account_set_online: 1315 * @self: a #TnyCamelAccount object 1316 * @online: whether or not the account is online 1317 * @callback: a callback when the account went online 1318 * 1319 * Set the connectivity status of an account. Setting this to FALSE means that 1320 * the account will not attempt to use the network, and will use only the cache. 1321 * Setting this to TRUE means that the account may use the network to 1322 * provide up-to-date information. 1323 * 1324 * The @callback will be invoke as soon as the account is actually online. It's 1325 * guaranteed that the @callback will happen in the mainloop, if available. 1326 * 1327 **/ 1345 1328 void 1346 tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, GError **err) 1347 { 1348 if (g_main_depth () != 0) 1349 { 1350 /* We are being called from the mainnloop */ 1351 SetOnlineInfo *info = g_slice_new (SetOnlineInfo); 1352 GThread *thread = NULL; 1353 1354 info->self = TNY_CAMEL_ACCOUNT (g_object_ref (self)); 1355 info->online = online; 1356 info->err = err; 1357 info->loop = g_main_loop_new (NULL, FALSE); 1358 1359 thread = g_thread_create (set_online_thread, info, TRUE, NULL); 1360 1361 g_main_loop_run (info->loop); 1362 1363 g_main_loop_unref (info->loop); 1364 g_object_unref (info->self); 1365 g_slice_free (SetOnlineInfo, info); 1366 1367 } else 1368 _tny_camel_account_set_online (self, online, err); 1369 } 1370 1329 tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback) 1330 { 1331 TNY_CAMEL_ACCOUNT_GET_CLASS (self)->set_online_func (self, online, callback); 1332 } 1333 1334 typedef struct 1335 { 1336 TnyCamelAccount *account; 1337 GError *err; 1338 TnyCamelSetOnlineCallback callback; 1339 1340 GCond* condition; 1341 gboolean had_callback; 1342 GMutex *mutex; 1343 1344 } OnSetOnlineInfo; 1345 1346 gboolean 1347 on_set_online_done_idle_func (gpointer data) 1348 { 1349 OnSetOnlineInfo *info = (OnSetOnlineInfo *) data; 1350 if (info->callback) 1351 info->callback (info->account, info->err); 1352 return FALSE; 1353 } 1354 1355 static void 1356 on_set_online_done_destroy_func (gpointer data) 1357 { 1358 OnSetOnlineInfo *info = (OnSetOnlineInfo *) data; 1359 1360 /* We copied it, so we must also free it */ 1361 if (info->err) 1362 g_error_free (info->err); 1363 1364 /* Thread reference */ 1365 g_object_unref (info->account); 1366 1367 if (info->condition) { 1368 g_mutex_lock (info->mutex); 1369 g_cond_broadcast (info->condition); 1370 info->had_callback = TRUE; 1371 g_mutex_unlock (info->mutex); 1372 } 1373 1374 return; 1375 } 1376 1377 /** 1378 * When using a #GMainLoop this method will execute a callback using 1379 * g_idle_add_full. Note that without a #GMainLoop, the callbacks 1380 * could happen in a worker thread (depends on who call it) at an 1381 * unknown moment in time (check your locking in this case). 1382 */ 1383 static void 1384 execute_callback (gint depth, 1385 gint priority, 1386 GSourceFunc idle_func, 1387 gpointer data, 1388 GDestroyNotify destroy_func) 1389 { 1390 if (depth > 0){ 1391 g_idle_add_full (priority, idle_func, data, destroy_func); 1392 } else { 1393 idle_func (data); 1394 destroy_func (data); 1395 } 1396 } 1397 1398 static void 1399 on_set_online_done (TnySessionCamel *self, TnyCamelAccount *account, GError *err, gpointer user_data) 1400 { 1401 OnSetOnlineInfo *info = g_slice_new (OnSetOnlineInfo); 1402 1403 /* Thread reference */ 1404 info->account = TNY_CAMEL_ACCOUNT (g_object_ref (account)); 1405 1406 /* We must copy the err because this context will destroy it! */ 1407 if (err) 1408 info->err = g_error_copy (err); 1409 else 1410 info->err = NULL; 1411 1412 info->callback = (TnyCamelSetOnlineCallback) user_data; 1413 1414 info->mutex = g_mutex_new (); 1415 info->condition = g_cond_new (); 1416 info->had_callback = FALSE; 1417 1418 execute_callback (/* info->depth */ 10, G_PRIORITY_HIGH, 1419 on_set_online_done_idle_func, 1420 info, on_set_online_done_destroy_func); 1421 1422 /* Wait on the queue for the mainloop callback to be finished */ 1423 g_mutex_lock (info->mutex); 1424 if (!info->had_callback) 1425 g_cond_wait (info->condition, info->mutex); 1426 g_mutex_unlock (info->mutex); 1427 1428 g_mutex_free (info->mutex); 1429 g_cond_free (info->condition); 1430 1431 g_slice_free (OnSetOnlineInfo, info); 1432 1433 return; 1434 } 1435 1436 void 1437 tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback) 1438 { 1439 1440 /* In case we are a store account, this means that we need to throw the 1441 * request to go online to the account's queue. */ 1442 1443 if (TNY_IS_CAMEL_STORE_ACCOUNT (self)) 1444 { 1445 TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 1446 TnySessionCamel *session = priv->session; 1447 1448 _tny_camel_store_account_queue_going_online ( 1449 TNY_CAMEL_STORE_ACCOUNT (self), session, online, 1450 on_set_online_done, (gpointer) callback); 1451 } 1452 1453 1454 /* Else, if it's a transport account, we don't have any transport 1455 * account implementations that actually need to go online at this 1456 * moment yet. At the moment of transferring the first message, the 1457 * current implementations will automatically connect themselves. */ 1458 1459 if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (self)) 1460 { 1461 g_signal_emit (self, 1462 tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online); 1463 return; 1464 } 1465 } 1466 1467 static gboolean 1468 tny_camel_account_is_ready (TnyAccount *self) 1469 { 1470 TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 1471 return priv->is_ready; 1472 } 1371 1473 1372 1474 static void … … 1388 1490 1389 1491 if (priv->session) { 1390 _tny_session_camel_ forget_account (priv->session, (TnyCamelAccount*) object);1492 _tny_session_camel_unregister_account (priv->session, (TnyCamelAccount*) object); 1391 1493 camel_object_unref (priv->session); 1392 1494 } … … 1481 1583 klass->start_operation_func = tny_camel_account_start_operation; 1482 1584 klass->stop_operation_func = tny_camel_account_stop_operation; 1585 klass->is_ready_func = tny_camel_account_is_ready; 1483 1586 1484 1587 return; … … 1669 1772 } 1670 1773 1671 iter = g_list_next (iter); 1774 iter = g_list_next (iter); 1672 1775 } 1673 1776 g_list_free (authtypes); … … 1741 1844 { 1742 1845 TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 1846 GetSupportedAuthInfo *info = NULL; 1847 1743 1848 g_return_if_fail (callback); 1744 1849 g_return_if_fail (priv->session); … … 1765 1870 1766 1871 /* Idle info for the status callback: */ 1767 GetSupportedAuthInfo *info = g_slice_new (GetSupportedAuthInfo);1872 info = g_slice_new (GetSupportedAuthInfo); 1768 1873 info->session = priv->session; 1769 1874 info->err = NULL; trunk/libtinymail-camel/tny-camel-account.h
r2352 r2536 48 48 extern guint tny_camel_account_signals [TNY_CAMEL_ACCOUNT_LAST_SIGNAL]; 49 49 50 typedef void (*TnyCamelSetOnlineCallback) (TnyCamelAccount *account, GError *err); 51 50 52 51 53 struct _TnyCamelAccount … … 89 91 90 92 void (*add_option_func) (TnyCamelAccount *self, const gchar *option); 91 void (*set_online_func) (TnyCamelAccount *self, gboolean online, GError **err);93 void (*set_online_func) (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback); 92 94 93 95 /* Abstract methods */ … … 103 105 void tny_camel_account_add_option (TnyCamelAccount *self, const gchar *option); 104 106 void tny_camel_account_set_session (TnyCamelAccount *self, TnySessionCamel *session); 105 void tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err);107 void tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback); 106 108 107 109 trunk/libtinymail-camel/tny-camel-folder.c
r2530 r2536 515 515 gboolean haderr = FALSE; 516 516 517 g_assert (TNY_IS_CAMEL_MSG (msg)); 518 519 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 520 TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_ADD_MSG)) 517 if (!TNY_IS_CAMEL_MSG (msg)) 518 { 519 g_critical ("You must not use a non-TnyCamelMsg implementation " 520 "of TnyMsg with TnyCamelFolder types. This indicates a " 521 "problem in the software (unsupported operation)\n"); 522 g_assert (TNY_IS_CAMEL_MSG (msg)); 523 } 524 525 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 526 priv->account, err, TNY_FOLDER_ERROR, 527 TNY_FOLDER_ERROR_ADD_MSG)) 521 528 return; 522 529 … … 539 546 gint a = 0, len = 0, nlen = 0; 540 547 CamelException ex2 = CAMEL_EXCEPTION_INITIALISER; 548 541 549 len = priv->folder->summary->messages->len; 542 550 dst_orig_uids = g_ptr_array_sized_new (len); 543 for (a = 0; a < len; a++) { 544 CamelMessageInfo *om = camel_folder_summary_index (priv->folder->summary, a); 551 552 for (a = 0; a < len; a++) 553 { 554 CamelMessageInfo *om = 555 camel_folder_summary_index (priv->folder->summary, a); 545 556 if (om && om->uid) 546 557 g_ptr_array_add (dst_orig_uids, g_strdup (om->uid)); … … 548 559 camel_message_info_free (om); 549 560 } 550 561 551 562 camel_folder_append_message (priv->folder, message, NULL, NULL, &ex); 552 563 priv->unread_length = camel_folder_get_unread_message_count (priv->folder); … … 558 569 for (a = 0; a < nlen; a++) 559 570 { 560 CamelMessageInfo *om = camel_folder_summary_index (priv->folder->summary, a); 561 if (om && om->uid) { 571 CamelMessageInfo *om = 572 camel_folder_summary_index (priv->folder->summary, a); 573 574 if (om && om->uid) 575 { 562 576 gint b = 0; 563 577 gboolean found = FALSE; … … 649 663 g_assert (TNY_IS_HEADER (header)); 650 664 651 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 652 TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REMOVE_MSG)) 665 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 666 priv->account, err, TNY_FOLDER_ERROR, 667 TNY_FOLDER_ERROR_REMOVE_MSG)) 653 668 return; 654 669 … … 670 685 tny_msg_remove_strategy_perform_remove (priv->remove_strat, self, header, err); 671 686 672 673 687 /* Notify about unread count */ 674 688 _tny_camel_folder_check_unread_count (TNY_CAMEL_FOLDER (self)); … … 796 810 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 797 811 priv->cached_length = len; 798 799 812 return; 800 813 } … … 806 819 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 807 820 priv->local_size = len; 808 809 821 return; 810 822 } … … 820 832 { 821 833 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 822 823 834 return priv->cached_length; 824 835 } … … 835 846 { 836 847 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 837 838 848 return TNY_ACCOUNT (g_object_ref (priv->account)); 839 849 } … … 852 862 } 853 863 854 /** 855 * When using a #GMainLoop this method will execute a callback using 864 /* When using a #GMainLoop this method will execute a callback using 856 865 * g_idle_add_full. Note that without a #GMainLoop, the callbacks 857 866 * could happen in a worker thread (depends on who call it) at an 858 * unknown moment in time (check your locking in this case). 859 */ 867 * unknown moment in time (check your locking in this case). */ 868 860 869 static void 861 870 execute_callback (gint depth, … … 888 897 CamelException ex = CAMEL_EXCEPTION_INITIALISER; 889 898 890 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 891 TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_SYNC)) 899 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 900 priv->account, err, TNY_FOLDER_ERROR, 901 TNY_FOLDER_ERROR_SYNC)) 892 902 return; 893 903 … … 949 959 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 950 960 961 /* thread reference */ 951 962 _tny_camel_folder_unreason (priv); 952 953 /* thread reference */954 963 g_object_unref (G_OBJECT (self)); 964 955 965 if (info->err) 956 966 g_error_free (info->err); … … 961 971 info->stopper = NULL; 962 972 963 g_mutex_lock (info->mutex); 964 g_cond_broadcast (info->condition); 965 info->had_callback = TRUE; 966 g_mutex_unlock (info->mutex); 973 if (info->condition) { 974 g_mutex_lock (info->mutex); 975 g_cond_broadcast (info->condition); 976 info->had_callback = TRUE; 977 g_mutex_unlock (info->mutex); 978 } 967 979 968 980 return; … … 976 988 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 977 989 TnyFolderChange *change = tny_folder_change_new (self); 978 979 if (info->callback)980 info->callback (info->self, info->cancelled, &info->err, info->user_data);981 982 tny_idle_stopper_stop (info->stopper);983 990 984 991 tny_folder_change_set_new_all_count (change, priv->cached_length); … … 987 994 g_object_unref (change); 988 995 996 if (info->callback) 997 info->callback (info->self, info->cancelled, &info->err, info->user_data); 998 999 tny_idle_stopper_stop (info->stopper); 1000 989 1001 return FALSE; 990 1002 } … … 1024 1036 { 1025 1037 tny_camel_folder_sync_async_destroyer (info); 1038 g_slice_free (SyncFolderInfo, thr_user_data); 1026 1039 g_static_rec_mutex_unlock (priv->folder_lock); 1027 1040 return NULL; … … 1068 1081 tny_camel_folder_sync_async_destroyer); 1069 1082 1083 1070 1084 /* Wait on the queue for the mainloop callback to be finished */ 1071 1085 g_mutex_lock (info->mutex); … … 1086 1100 { 1087 1101 SyncFolderInfo *info = thr_user_data; 1088 1089 1102 g_error_free (info->err); 1090 1103 g_object_unref (info->self); 1091 1104 g_slice_free (SyncFolderInfo, thr_user_data); 1105 return; 1092 1106 } 1093 1107 … … 1096 1110 { 1097 1111 SyncFolderInfo *info = thr_user_data; 1098 1099 1112 if (info->callback) 1100 1113 info->callback (info->self, TRUE, &info->err, info->user_data); 1101 1102 1114 return FALSE; 1103 1115 } 1116 1104 1117 void 1105 1118 tny_camel_folder_sync_async_default (TnyFolder *self, gboolean expunge, TnySyncFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data) … … 1119 1132 info->depth = g_main_depth (); 1120 1133 info->expunge = expunge; 1134 info->condition = NULL; 1121 1135 1122 1136 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, … … 1126 1140 info->err = g_error_copy (err); 1127 1141 g_object_ref (info->self); 1128 1129 1142 execute_callback (info->depth, G_PRIORITY_DEFAULT, 1130 1143 tny_camel_folder_sync_async_cancelled_callback, info, … … 1138 1151 1139 1152 /* thread reference */ 1140 g_object_ref ( G_OBJECT (self));1153 g_object_ref (info->self); 1141 1154 _tny_camel_folder_reason (priv); 1142 1155 … … 1159 1172 gpointer user_data; 1160 1173 gboolean cancelled; 1161 /* This stops us from calling a status callback after the operation has1162 * finished. */1163 1174 TnyIdleStopper* stopper; 1164 1175 guint depth; … … 1174 1185 1175 1186 /** This is the GDestroyNotify callback provided to g_idle_add_full() 1176 * for tny_camel_folder_refresh_async_callback(). 1177 */ 1187 * for tny_camel_folder_refresh_async_callback().*/ 1188 1178 1189 static void 1179 1190 tny_camel_folder_refresh_async_destroyer (gpointer thr_user_data) … … 1183 1194 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 1184 1195 1196 /* thread reference */ 1185 1197 _tny_camel_folder_unreason (priv); 1186 1187 /* thread reference */1188 1198 g_object_unref (G_OBJECT (self)); 1199 1189 1200 if (info->err) 1190 1201 g_error_free (info->err); … … 1195 1206 info->stopper = NULL; 1196 1207 1197 g_mutex_lock (info->mutex); 1198 g_cond_broadcast (info->condition); 1199 info->had_callback = TRUE; 1200 g_mutex_unlock (info->mutex); 1208 if (info->condition) { 1209 g_mutex_lock (info->mutex); 1210 g_cond_broadcast (info->condition); 1211 info->had_callback = TRUE; 1212 g_mutex_unlock (info->mutex); 1213 } 1201 1214 1202 1215 return; … … 1210 1223 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 1211 1224 TnyFolderChange *change = tny_folder_change_new (self); 1212 1213 if (info->callback)1214 info->callback (info->self, info->cancelled, &info->err, info->user_data);1215 1216 /* Prevent status callbacks from being called after this1217 * (can happen because the 2 idle callbacks have different priorities)1218 * by causing tny_idle_stopper_is_stopped() to return TRUE. */1219 tny_idle_stopper_stop (info->stopper);1220 1225 1221 1226 tny_folder_change_set_new_all_count (change, priv->cached_length); … … 1224 1229 g_object_unref (change); 1225 1230 1231 if (info->callback) 1232 info->callback (info->self, info->cancelled, &info->err, info->user_data); 1233 1234 /* Prevent status callbacks from being called after this 1235 * (can happen because the 2 idle callbacks have different priorities) 1236 * by causing tny_idle_stopper_is_stopped() to return TRUE. */ 1237 1238 tny_idle_stopper_stop (info->stopper); 1239 1226 1240 return FALSE; 1227 1241 } … … 1261 1275 { 1262 1276 tny_camel_folder_refresh_async_destroyer (info); 1277 g_slice_free (RefreshFolderInfo, info); 1263 1278 g_static_rec_mutex_unlock (priv->folder_lock); 1264 1279 return NULL; … … 1300 1315 info->had_callback = FALSE; 1301 1316 1302 if (info->callback) 1303 { 1304 execute_callback (info->depth, G_PRIORITY_DEFAULT, 1305 tny_camel_folder_refresh_async_callback, info, 1306 tny_camel_folder_refresh_async_destroyer); 1307 } else { /* Thread reference */ 1308 g_object_unref (G_OBJECT (self)); 1309 _tny_camel_folder_unreason (priv); 1310 } 1317 execute_callback (info->depth, G_PRIORITY_DEFAULT, 1318 tny_camel_folder_refresh_async_callback, info, 1319 tny_camel_folder_refresh_async_destroyer); 1311 1320 1312 1321 /* Wait on the queue for the mainloop callback to be finished */ … … 1334 1343 { 1335 1344 RefreshFolderInfo *info = thr_user_data; 1336 1337 1345 g_error_free (info->err); 1338 1346 g_object_unref (info->self); 1339 1347 g_slice_free (RefreshFolderInfo, thr_user_data); 1348 return; 1340 1349 } 1341 1350 … … 1344 1353 { 1345 1354 RefreshFolderInfo *info = thr_user_data; 1346 1347 1355 if (info->callback) 1348 1356 info->callback (info->self, TRUE, &info->err, info->user_data); 1349 1350 1357 return FALSE; 1351 1358 } … … 1365 1372 * become zero while doing stuff on the instance in the background, don't you? 1366 1373 **/ 1374 1367 1375 static void 1368 1376 tny_camel_folder_refresh_async_default (TnyFolder *self, TnyRefreshFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data) … … 1381 1389 info->user_data = user_data; 1382 1390 info->depth = g_main_depth (); 1391 info->condition = NULL; 1383 1392 1384 1393 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, … … 1388 1397 info->err = g_error_copy (err); 1389 1398 g_object_ref (info->self); 1390 1391 1399 execute_callback (info->depth, G_PRIORITY_DEFAULT, 1392 1400 tny_camel_folder_refresh_async_cancelled_callback, info, … … 1432 1440 TnyFolderChange *change = NULL; 1433 1441 1434 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 1435 TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH)) 1442 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 1443 priv->account, err, TNY_FOLDER_ERROR, 1444 TNY_FOLDER_ERROR_REFRESH)) 1436 1445 return; 1437 1446 … … 1445 1454 } 1446 1455 1447 /*_tny_camel_account_start_camel_operation (TNY_CAMEL_ACCOUNT (priv->account),1448 NULL, NULL, NULL); */1449 1450 1456 oldlen = priv->cached_length; 1451 1457 oldurlen = priv->unread_length; … … 1454 1460 camel_folder_refresh_info (priv->folder, &ex); 1455 1461 priv->want_changes = TRUE; 1456 1457 /* _tny_camel_account_stop_camel_operation (TNY_CAMEL_ACCOUNT (priv->account)); */1458 1462 1459 1463 priv->cached_length = camel_folder_get_message_count (priv->folder); … … 1461 1465 priv->unread_length = (guint) camel_folder_get_unread_message_count (priv->folder); 1462 1466 update_iter_counts (priv); 1463 1464 1467 1465 1468 if (camel_exception_is_set (&ex)) … … 1507 1510 1508 1511 header = _tny_camel_header_new (); 1509 1510 _tny_camel_header_set_folder (TNY_CAMEL_HEADER (header), TNY_CAMEL_FOLDER (self), priv); 1511 _tny_camel_header_set_camel_message_info (TNY_CAMEL_HEADER (header), mi, FALSE); 1512 1513 tny_list_prepend (headers, (GObject*)header); 1514 1515 g_object_unref (G_OBJECT (header)); 1512 _tny_camel_header_set_folder ((TnyCamelHeader *) header, (TnyCamelFolder *) self, priv); 1513 _tny_camel_header_set_camel_message_info ((TnyCamelHeader *) header, mi, FALSE); 1514 tny_list_prepend (headers, (GObject*) header); 1515 g_object_unref (header); 1516 1516 1517 1517 return; … … 1538 1538 return; 1539 1539 1540 /* we reason the folder to make sure it does not1541 * lose all the references and uncache, causing an interlock */1542 _tny_camel_folder_reason (priv);1543 1540 g_static_rec_mutex_lock (priv->folder_lock); 1544 1541 … … 1550 1547 } 1551 1548 1552 g_object_ref (G_OBJECT (headers)); 1553 1549 /* We reason the folder to make sure it does not lose all the references 1550 * and uncache, causing an interlock */ 1551 _tny_camel_folder_reason (priv); 1552 1553 g_object_ref (headers); 1554 1554 ptr = g_slice_new (FldAndPriv); 1555 1555 ptr->self = self; … … 1577 1577 g_slice_free (FldAndPriv, ptr); 1578 1578 1579 g_object_unref (G_OBJECT (headers)); 1579 g_object_unref (headers); 1580 1580 1581 g_static_rec_mutex_unlock (priv->folder_lock); 1581 1582 _tny_camel_folder_unreason (priv); … … 1613 1614 { 1614 1615 GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 1616 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 1617 1618 /* thread reference */ 1619 _tny_camel_folder_unreason (priv); 1620 g_object_unref (info->self); 1621 1622 if (info->err) 1623 g_error_free (info->err); 1624 1625 _tny_session_stop_operation (info->session); 1626 1627 tny_idle_stopper_destroy (info->stopper); 1628 info->stopper = NULL; 1629 1630 if (info->condition) { 1631 g_mutex_lock (info->mutex); 1632 g_cond_broadcast (info->condition); 1633 info->had_callback = TRUE; 1634 g_mutex_unlock (info->mutex); 1635 } 1636 1637 return; 1638 } 1639 1640 1641 static gboolean 1642 tny_camel_folder_get_msg_async_callback (gpointer thr_user_data) 1643 { 1644 GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 1615 1645 TnyFolderChange *change; 1616 1646 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); … … 1625 1655 } 1626 1656 1627 /* thread reference */1628 _tny_camel_folder_unreason (priv);1629 g_object_unref (info->self);1630 1631 if (info->err)1632 g_error_free (info->err);1633 1634 _tny_session_stop_operation (info->session);1635 1636 tny_idle_stopper_destroy (info->stopper);1637 info->stopper = NULL;1638 1639 g_mutex_lock (info->mutex);1640  
