Changeset 2537
- Timestamp:
- 07/31/07 15:27:00
- Files:
-
- trunk/ChangeLog (modified) (1 diff)
- trunk/libtinymail-camel/tny-camel-folder.c (modified) (3 diffs)
- trunk/libtinymail-camel/tny-camel-folder.h (modified) (1 diff)
- trunk/libtinymail/tny-folder.c (modified) (1 diff)
- trunk/libtinymail/tny-folder.h (modified) (2 diffs)
- trunk/libtinymail/tny-merge-folder.c (modified) (2 diffs)
- trunk/libtinymail/tny-shared.h (modified) (1 diff)
- trunk/libtinymailui-gtk/tny-gtk-header-list-model.c (modified) (2 diffs)
- trunk/tests/shared/account-store.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r2536 r2537 1 2007-07-31 Philip Van Hoof <pvanhoof@gnome.org> 2 3 * Introduction of tny_folder_get_headers_async 4 * Adaptation of TnyGtkHeaderListModel to use the new API 5 6 * This was a major API change 7 1 8 2007-07-31 Philip Van Hoof <pvanhoof@gnome.org> 2 9 trunk/libtinymail-camel/tny-camel-folder.c
r2536 r2537 1514 1514 tny_list_prepend (headers, (GObject*) header); 1515 1515 g_object_unref (header); 1516 1517 return; 1518 } 1519 1520 1521 1522 typedef struct 1523 { 1524 GError *err; 1525 TnyFolder *self; 1526 TnyList *headers; 1527 gboolean refresh; 1528 TnyGetHeadersCallback callback; 1529 gpointer user_data; 1530 guint depth; 1531 TnySessionCamel *session; 1532 1533 GCond* condition; 1534 gboolean had_callback; 1535 GMutex *mutex; 1536 1537 } GetHeadersInfo; 1538 1539 1540 static void 1541 tny_camel_folder_get_headers_async_destroyer (gpointer thr_user_data) 1542 { 1543 GetHeadersInfo *info = thr_user_data; 1544 1545 /* thread reference */ 1546 g_object_unref (info->self); 1547 g_object_unref (info->headers); 1548 1549 if (info->err) 1550 g_error_free (info->err); 1551 1552 _tny_session_stop_operation (info->session); 1553 1554 if (info->condition) { 1555 g_mutex_lock (info->mutex); 1556 g_cond_broadcast (info->condition); 1557 info->had_callback = TRUE; 1558 g_mutex_unlock (info->mutex); 1559 } 1560 1561 return; 1562 } 1563 1564 static gboolean 1565 tny_camel_folder_get_headers_async_callback (gpointer thr_user_data) 1566 { 1567 GetHeadersInfo *info = thr_user_data; 1568 if (info->callback) 1569 info->callback (info->self, FALSE, info->headers, &info->err, info->user_data); 1570 return FALSE; 1571 } 1572 1573 static gpointer 1574 tny_camel_folder_get_headers_async_thread (gpointer thr_user_data) 1575 { 1576 GetHeadersInfo *info = (GetHeadersInfo*) thr_user_data; 1577 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 1578 1579 GError *err = NULL; 1580 1581 tny_folder_get_headers (info->self, info->headers, info->refresh, &err); 1582 1583 if (err != NULL) 1584 info->err = g_error_copy ((const GError *) err); 1585 else 1586 info->err = NULL; 1587 1588 info->mutex = g_mutex_new (); 1589 info->condition = g_cond_new (); 1590 info->had_callback = FALSE; 1591 1592 execute_callback (info->depth, G_PRIORITY_DEFAULT, 1593 tny_camel_folder_get_headers_async_callback, info, 1594 tny_camel_folder_get_headers_async_destroyer); 1595 1596 /* Wait on the queue for the mainloop callback to be finished */ 1597 g_mutex_lock (info->mutex); 1598 if (!info->had_callback) 1599 g_cond_wait (info->condition, info->mutex); 1600 g_mutex_unlock (info->mutex); 1601 1602 g_mutex_free (info->mutex); 1603 g_cond_free (info->condition); 1604 1605 g_slice_free (GetHeadersInfo, info); 1606 1607 return NULL; 1608 } 1609 1610 static void 1611 tny_camel_folder_get_headers_async_cancelled_destroyer (gpointer thr_user_data) 1612 { 1613 GetHeadersInfo *info = thr_user_data; 1614 g_error_free (info->err); 1615 g_object_unref (info->self); 1616 g_object_unref (info->headers); 1617 g_slice_free (GetHeadersInfo, info); 1618 return; 1619 } 1620 1621 static gboolean 1622 tny_camel_folder_get_headers_async_cancelled_callback (gpointer thr_user_data) 1623 { 1624 GetHeadersInfo *info = thr_user_data; 1625 if (info->callback) 1626 info->callback (info->self, TRUE, info->headers, &info->err, info->user_data); 1627 return FALSE; 1628 } 1629 1630 static void 1631 tny_camel_folder_get_headers_async (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 1632 { 1633 TNY_CAMEL_FOLDER_GET_CLASS (self)->get_headers_async_func (self, headers, refresh, callback, status_callback, user_data); 1634 return; 1635 } 1636 1637 1638 static void 1639 tny_camel_folder_get_headers_async_default (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 1640 { 1641 GetHeadersInfo *info; 1642 GError *err = NULL; 1643 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 1644 1645 /* Idle info for the callbacks */ 1646 info = g_slice_new (GetHeadersInfo); 1647 info->session = TNY_FOLDER_PRIV_GET_SESSION (priv); 1648 info->self = self; 1649 info->headers = headers; 1650 info->refresh = refresh; 1651 info->callback = callback; 1652 info->user_data = user_data; 1653 info->depth = g_main_depth (); 1654 info->condition = NULL; 1655 1656 if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 1657 TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH)) 1658 { 1659 if (callback) { 1660 info->err = g_error_copy (err); 1661 g_object_ref (info->self); 1662 g_object_ref (info->headers); 1663 1664 execute_callback (info->depth, G_PRIORITY_DEFAULT, 1665 tny_camel_folder_get_headers_async_cancelled_callback, info, 1666 tny_camel_folder_get_headers_async_cancelled_destroyer); 1667 } 1668 g_error_free (err); 1669 return; 1670 } 1671 1672 /* thread reference */ 1673 g_object_ref (info->self); 1674 g_object_ref (info->headers); 1675 1676 _tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 1677 tny_camel_folder_get_headers_async_thread, info); 1516 1678 1517 1679 return; … … 4670 4832 klass->set_msg_receive_strategy_func = tny_camel_folder_set_msg_receive_strategy; 4671 4833 klass->get_headers_func = tny_camel_folder_get_headers; 4834 klass->get_headers_async_func = tny_camel_folder_get_headers_async; 4672 4835 klass->get_msg_func = tny_camel_folder_get_msg; 4673 4836 klass->find_msg_func = tny_camel_folder_find_msg; … … 4731 4894 class->set_msg_remove_strategy_func = tny_camel_folder_set_msg_remove_strategy_default; 4732 4895 class->get_headers_func = tny_camel_folder_get_headers_default; 4896 class->get_headers_async_func = tny_camel_folder_get_headers_async_default; 4733 4897 class->get_msg_func = tny_camel_folder_get_msg_default; 4734 4898 class->find_msg_func = tny_camel_folder_find_msg_default; trunk/libtinymail-camel/tny-camel-folder.h
r2438 r2537 66 66 void (*get_msg_async_func) (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, TnyStatusCallback status_callback, gpointer user_data); 67 67 void (*get_headers_func) (TnyFolder *self, TnyList *headers, gboolean refresh, GError **err); 68 void (*get_headers_async_func) (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data); 68 69 const gchar* (*get_name_func) (TnyFolder *self); 69 70 const gchar* (*get_id_func) (TnyFolder *self); trunk/libtinymail/tny-folder.c
r2506 r2537 1186 1186 } 1187 1187 1188 1189 /** 1190 * tny_folder_get_headers_async: 1191 * @self: a TnyFolder object 1192 * @headers: A #TnyList instance where the headers will be put 1193 * @refresh: whether or not to synchronize with the service first 1194 * @callback: the callback that happens when the operation finished 1195 * @status_callback: status callback 1196 * @user_data: user data 1197 * 1198 * Get the list of message header instances that are in @self. Also read 1199 * about tny_folder_refresh. 1200 * 1201 * API warning: it's possible that between the @refresh and @callback, a pointer 1202 * to a query object will be placed. This will introduce both an API and ABI 1203 * breakage. 1204 **/ 1205 void 1206 tny_folder_get_headers_async (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 1207 { 1208 #ifdef DBC /* require */ 1209 g_assert (TNY_IS_FOLDER (self)); 1210 g_assert (headers); 1211 g_assert (TNY_IS_LIST (headers)); 1212 g_assert (TNY_FOLDER_GET_IFACE (self)->get_headers_async_func != NULL); 1213 #endif 1214 1215 TNY_FOLDER_GET_IFACE (self)->get_headers_async_func (self, headers, refresh, callback, status_callback, user_data); 1216 return; 1217 } 1218 1219 1188 1220 /** 1189 1221 * tny_folder_get_id: trunk/libtinymail/tny-folder.h
r2485 r2537 101 101 void (*get_msg_async_func) (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, TnyStatusCallback status_callback, gpointer user_data); 102 102 void (*get_headers_func) (TnyFolder *self, TnyList *headers, gboolean refresh, GError **err); 103 void (*get_headers_async_func) (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data); 103 104 const gchar* (*get_name_func) (TnyFolder *self); 104 105 const gchar* (*get_id_func) (TnyFolder *self); … … 139 140 void tny_folder_get_msg_async (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, TnyStatusCallback status_callback, gpointer user_data); 140 141 void tny_folder_get_headers (TnyFolder *self, TnyList *headers, gboolean refresh, GError **err); 142 void tny_folder_get_headers_async (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data); 141 143 TnyAccount* tny_folder_get_account (TnyFolder *self); 142 144 const gchar* tny_folder_get_id (TnyFolder *self); trunk/libtinymail/tny-merge-folder.c
r2531 r2537 429 429 430 430 /* thread reference */ 431 g_object_ref ( G_OBJECT (info->self));432 g_object_ref ( G_OBJECT (info->header));431 g_object_ref (info->self); 432 g_object_ref (info->header); 433 433 434 434 thread = g_thread_create (get_msg_async_thread, info, FALSE, NULL); 435 436 return; 437 } 438 439 440 441 typedef struct 442 { 443 TnyFolder *self; 444 TnyList *headers; 445 TnyRefreshFolderCallback callback; 446 TnyStatusCallback status_callback; 447 gpointer user_data; 448 gboolean cancelled, refresh; 449 guint depth; 450 GError *err; 451 } GetHeadersFolderInfo; 452 453 454 static void 455 get_headers_async_destroyer (gpointer thr_user_data) 456 { 457 GetHeadersFolderInfo *info = thr_user_data; 458 459 /* thread reference */ 460 g_object_unref (info->self); 461 g_object_unref (info->headers); 462 463 if (info->err) 464 g_error_free (info->err); 465 466 g_slice_free (GetHeadersFolderInfo, thr_user_data); 467 468 return; 469 } 470 471 static gboolean 472 get_headers_async_callback (gpointer thr_user_data) 473 { 474 GetHeadersFolderInfo *info = thr_user_data; 475 if (info->callback) 476 info->callback (info->self, info->cancelled, &info->err, info->user_data); 477 return FALSE; 478 } 479 480 481 static gpointer 482 get_headers_async_thread (gpointer thr_user_data) 483 { 484 GetHeadersFolderInfo *info = thr_user_data; 485 TnyFolder *self = info->self; 486 TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 487 TnyIterator *iter; 488 GError *err = NULL; 489 490 g_static_rec_mutex_lock (priv->lock); 491 492 info->cancelled = FALSE; 493 494 iter = tny_list_create_iterator (priv->mothers); 495 while (!tny_iterator_is_done (iter)) 496 { 497 TnyFolder *cur = TNY_FOLDER (tny_iterator_get_current (iter)); 498 499 tny_folder_get_headers (cur, info->headers, info->refresh, &err); 500 501 /* TODO: Handler err */ 502 503 /* TODO: Handle progress status callbacks ( info->status_callback ) 504 * you might have to start using refresh_async for that (in a 505 * serialized way, else you'd launch a buch of concurrent threads 506 * and ain't going to be nice, perhaps). */ 507 508 g_object_unref (cur); 509 tny_iterator_next (iter); 510 } 511 g_object_unref (iter); 512 513 info->err = NULL; 514 515 g_static_rec_mutex_unlock (priv->lock); 516 517 if (info->callback) 518 { 519 if (info->depth > 0) 520 { 521 g_idle_add_full (G_PRIORITY_HIGH, 522 get_headers_async_callback, 523 info, get_headers_async_destroyer); 524 } else { 525 get_headers_async_callback (info); 526 get_headers_async_destroyer (info); 527 } 528 } else { /* Thread reference */ 529 g_object_unref (info->self); 530 g_object_unref (info->headers); 531 } 532 533 g_thread_exit (NULL); 534 535 return NULL; 536 } 537 538 539 static void 540 tny_merge_folder_get_headers_async (TnyFolder *self, TnyList *headers, gboolean refresh, TnyGetHeadersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 541 { 542 GetHeadersFolderInfo *info; 543 GThread *thread; 544 545 info = g_slice_new (GetHeadersFolderInfo); 546 info->err = NULL; 547 info->self = self; 548 info->headers = headers; 549 info->refresh = refresh; 550 info->callback = callback; 551 info->status_callback = status_callback; 552 info->user_data = user_data; 553 info->depth = g_main_depth (); 554 555 /* thread reference */ 556 g_object_ref (self); 557 g_object_ref (headers); 558 559 thread = g_thread_create (get_headers_async_thread, info, FALSE, NULL); 435 560 436 561 return; … … 1309 1434 klass->get_msg_async_func = tny_merge_folder_get_msg_async; 1310 1435 klass->get_headers_func = tny_merge_folder_get_headers; 1436 klass->get_headers_async_func = tny_merge_folder_get_headers_async; 1311 1437 klass->get_name_func = tny_merge_folder_get_name; 1312 1438 klass->get_id_func = tny_merge_folder_get_id; trunk/libtinymail/tny-shared.h
r2435 r2537 60 60 typedef void (*TnyForgetPassFunc) (TnyAccount *self); 61 61 typedef void (*TnyRefreshFolderCallback) (TnyFolder *self, gboolean cancelled, GError **err, gpointer user_data); 62 typedef void (*TnyGetHeadersCallback) (TnyFolder *self, gboolean cancelled, TnyList *headers, GError **err, gpointer user_data); 62 63 typedef void (*TnyGetMsgCallback) (TnyFolder *folder, gboolean cancelled, TnyMsg *msg, GError **err, gpointer user_data); 63 64 typedef void (*TnySyncFolderCallback) (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data); trunk/libtinymailui-gtk/tny-gtk-header-list-model.c
r2536 r2537 914 914 } 915 915 916 static void 917 get_hdrs_callback (TnyFolder *self, gboolean cancelled, TnyList *headers, GError **err, gpointer user_data) 918 { 919 return; 920 } 921 922 static void 923 get_hdrs_status_callback (GObject *self, TnyStatus *status, gpointer user_data) 924 { 925 return; 926 } 916 927 917 928 /** … … 957 968 /* Get a new list of headers */ 958 969 /* TODO add error handling and reporting here */ 959 tny_folder_get_headers (folder, TNY_LIST (self), refresh, NULL);970 tny_folder_get_headers_async (folder, TNY_LIST (self), refresh, get_hdrs_callback, get_hdrs_status_callback, NULL); 960 971 961 972 iter.stamp = priv->stamp; trunk/tests/shared/account-store.c
r2443 r2537 173 173 174 174 self->session = tny_session_camel_new (TNY_ACCOUNT_STORE (self)); 175 tny_session_camel_set_async_connecting (self->session, FALSE);176 175 177 176 self->force_online = force_online;
