From 337f99b53559b08abb937fff57f13947f0dd147f Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Tue, 5 Feb 2008 16:41:27 +0200 Subject: [PATCH] Stop downloads if auto download is disabled. --- src/cb.c | 6 +- src/map-download.c | 166 +++++++++++++++++++++++++++------------------ 2 files changed, 106 insertions(+), 66 deletions(-) diff --git a/src/cb.c b/src/cb.c index a74b4c6..ca6c292 100644 --- a/src/cb.c +++ b/src/cb.c @@ -465,9 +465,13 @@ gboolean menu_cb_auto_download(GtkAction * action) { if ((_auto_download = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)) )) { - if (_curr_repo->url == REPOTYPE_NONE) + if (_curr_repo->url == REPOTYPE_NONE) { popup_error(_window, _("NOTE: You must set a Map URI in the current repository in order to download maps.")); + /* set_action_activate("", FALSE); */ + } map_force_redraw(); +} else { + map_download_stop(); } return TRUE; diff --git a/src/map-download.c b/src/map-download.c index 0b272d6..bc84afb 100644 --- a/src/map-download.c +++ b/src/map-download.c @@ -61,6 +61,11 @@ static guint _num_downloads=0; static guint _curr_download=0; +static GQueue *curl_easy_queue=NULL; +static GTree *pui_tree=NULL; +static GTree *downloading_tree=NULL; +static GHashTable *pui_by_easy=NULL; + static gchar *map_construct_url(guint tilex, guint tiley, guint zoom); static gboolean @@ -125,18 +130,16 @@ while (_curl_multi && (msg = curl_multi_info_read(_curl_multi, &num_msgs))) { if (msg->easy_handle == _autoroute_data.curl_easy) { /* This is the autoroute download. */ /* Now, parse the autoroute and update the display. */ - if (_autoroute_data.enabled && parse_gpx(&_route, - _autoroute_data.rdl_data.bytes, - _autoroute_data.rdl_data.bytes_read, 0)) { + if (_autoroute_data.enabled && parse_gpx(&_route, _autoroute_data.rdl_data.bytes, _autoroute_data.rdl_data.bytes_read, 0)) { /* Find the nearest route point, if we're connected. */ route_find_nearest_point(); map_force_redraw(); } cancel_autoroute(TRUE); /* We're done. Clean up. */ } else { - ProgressUpdateInfo *pui = g_hash_table_lookup(_pui_by_easy, msg->easy_handle); - g_queue_push_head(_curl_easy_queue, msg->easy_handle); - g_hash_table_remove(_pui_by_easy, msg->easy_handle); + ProgressUpdateInfo *pui = g_hash_table_lookup(pui_by_easy, msg->easy_handle); + g_queue_push_head(curl_easy_queue, msg->easy_handle); + g_hash_table_remove(pui_by_easy, msg->easy_handle); fclose(pui->file); if (msg->data.result != CURLE_OK) g_unlink(pui->dest_str); /* Delete so we try again. */ @@ -147,27 +150,27 @@ while (_curl_multi && (msg = curl_multi_info_read(_curl_multi, &num_msgs))) { } /* Up to 1 transfer per tile. */ -while (num_transfers < (BUF_WIDTH_TILES * BUF_HEIGHT_TILES) && g_tree_nnodes(_pui_tree)) { +while (num_transfers < (BUF_WIDTH_TILES * BUF_HEIGHT_TILES) && g_tree_nnodes(pui_tree)) { ProgressUpdateInfo *pui; - g_tree_foreach(_pui_tree, (GTraverseFunc) get_next_pui, &pui); + g_tree_foreach(pui_tree, (GTraverseFunc)get_next_pui, &pui); if (pui->retries) { /* This is a download. */ FILE *f; - g_tree_steal(_pui_tree, pui); - g_tree_insert(_downloading_tree, pui, pui); + g_tree_steal(pui_tree, pui); + g_tree_insert(downloading_tree, pui, pui); - pui->src_str = map_construct_url(pui->tilex, pui->tiley, pui->zoom); - pui->dest_str = g_strdup_printf("%s/%u/%u/%u.jpg", - pui->repo->cache_dir, pui->zoom, - pui->tilex, pui->tiley); + pui->src_str=map_construct_url(pui->tilex, pui->tiley, pui->zoom); if (!pui->src_str) { /* Failed to generate URL. */ + g_debug("Failed to generate tile download URL"); g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_download_idle_refresh, pui, NULL); continue; } + pui->dest_str=g_strdup_printf("%s/%u/%u/%u.jpg", pui->repo->cache_dir, pui->zoom, pui->tilex, pui->tiley); + /* Check to see if we need to overwrite. */ if (pui->retries > 0) { /* We're not updating - check if file already exists. */ @@ -178,26 +181,25 @@ while (num_transfers < (BUF_WIDTH_TILES * BUF_HEIGHT_TILES) && g_tree_nnodes(_pu } /* Attempt to open the file for writing. */ - if (!(f = g_fopen(pui->dest_str, "w")) && errno == ENOENT) { + if (!(f=g_fopen(pui->dest_str, "w")) && errno == ENOENT) { /* Directory doesn't exist yet - create it, then we'll retry */ gchar buffer[BUFFER_SIZE]; - g_snprintf(buffer, sizeof(buffer), "%s/%u/%u", - pui->repo->cache_dir, pui->zoom, pui->tilex); + g_snprintf(buffer, sizeof(buffer), "%s/%u/%u", pui->repo->cache_dir, pui->zoom, pui->tilex); g_mkdir_with_parents(buffer, 0775); - f = g_fopen(pui->dest_str, "w"); + f=g_fopen(pui->dest_str, "w"); } if (f) { CURL *curl_easy; pui->file = f; - curl_easy = g_queue_pop_tail(_curl_easy_queue); + curl_easy = g_queue_pop_tail(curl_easy_queue); if (!curl_easy) { /* Need a new curl_easy. */ MACRO_CURL_EASY_INIT(curl_easy); } curl_easy_setopt(curl_easy, CURLOPT_URL, pui->src_str); curl_easy_setopt(curl_easy, CURLOPT_WRITEDATA, f); - g_hash_table_insert(_pui_by_easy, curl_easy, pui); + g_hash_table_insert(pui_by_easy, curl_easy, pui); if (!_curl_multi) { /* Initialize CURL. */ _curl_multi = curl_multi_init(); @@ -208,9 +210,7 @@ while (num_transfers < (BUF_WIDTH_TILES * BUF_HEIGHT_TILES) && g_tree_nnodes(_pu } else { /* Unable to open tile file for writing. */ gchar buffer[BUFFER_SIZE]; - g_snprintf(buffer, sizeof(buffer), "%s:\n%s", - _("Failed to open file for writing"), - pui->dest_str); + g_snprintf(buffer, sizeof(buffer), "%s:\n%s", _("Failed to open file for writing"), pui->dest_str); MACRO_BANNER_SHOW_INFO(_window, buffer); g_idle_add_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)map_download_idle_refresh, pui, NULL); continue; @@ -218,24 +218,22 @@ while (num_transfers < (BUF_WIDTH_TILES * BUF_HEIGHT_TILES) && g_tree_nnodes(_pu } else if (--deletes_left) { /* This is a delete. */ gchar buffer[BUFFER_SIZE]; - g_tree_steal(_pui_tree, pui); - g_tree_insert(_downloading_tree, pui, pui); + g_tree_steal(pui_tree, pui); + g_tree_insert(downloading_tree, pui, pui); - g_snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg", - pui->repo->cache_dir, pui->zoom, - pui->tilex, pui->tiley); + g_snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg", pui->repo->cache_dir, pui->zoom, pui->tilex, pui->tiley); g_unlink(buffer); g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_download_idle_refresh, pui, NULL); } else break; } -if (!(num_transfers || g_tree_nnodes(_pui_tree))) { +if (!(num_transfers || g_tree_nnodes(pui_tree))) { /* Destroy curl after 50 counts (5 seconds). */ if (--destroy_counter) { /* Clean up curl. */ CURL *curr; - while ((curr = g_queue_pop_tail(_curl_easy_queue))) + while ((curr = g_queue_pop_tail(curl_easy_queue))) curl_easy_cleanup(curr); curl_multi_cleanup(_curl_multi); @@ -375,6 +373,24 @@ default: return ""; } +void +map_download_progress_clear(void) +{ +g_assert(_progress_item); +gtk_progress_bar_set_fraction(_progress_item, 0.0); +gtk_progress_bar_set_text(_progress_item, ""); +} + +void +map_download_progress_set(gint currd, gint numd) +{ +gchar buffer[64]; + +g_assert(_progress_item); +g_snprintf(buffer, sizeof(buffer), _("Downloading maps (%d/%d)"), currd, numd); +gtk_progress_bar_set_text(_progress_item, buffer); +gtk_progress_bar_set_fraction(_progress_item, currd/(double)numd); +} gboolean map_download_idle_refresh(ProgressUpdateInfo * pui) @@ -411,8 +427,8 @@ else { if (pui->retries) { /* removal automatically calls progress_update_info_free(). */ - g_tree_steal(_downloading_tree, pui); - g_tree_insert(_pui_tree, pui, pui); + g_tree_steal(downloading_tree, pui); + g_tree_insert(pui_tree, pui, pui); if (iap_is_connected() && !_curl_sid) _curl_sid = g_timeout_add(100,(GSourceFunc)map_download_timeout, NULL); /* Don't do anything else. */ @@ -424,18 +440,13 @@ else { } /* removal automatically calls progress_update_info_free(). */ -g_tree_remove(_downloading_tree, pui); +g_tree_remove(downloading_tree, pui); if (++_curr_download == _num_downloads) { _num_downloads = _curr_download = 0; - gtk_progress_bar_set_fraction(_progress_item, 0.0); - gtk_progress_bar_set_text(_progress_item, ""); + map_download_progress_clear(); } else { - gchar buffer[64]; - - g_snprintf(buffer, sizeof(buffer), _("Downloading maps (%d/%d)"), _curr_download, _num_downloads); - gtk_progress_bar_set_text(_progress_item, buffer); - gtk_progress_bar_set_fraction(_progress_item, _curr_download / (double)_num_downloads); + map_download_progress_set(_curr_download, _num_downloads); } return FALSE; } @@ -462,7 +473,7 @@ if (!retries) pui->retries = retries; pui->repo = _curr_repo; -if (g_tree_lookup(_pui_tree, pui) || g_tree_lookup(_downloading_tree, pui)) { +if (g_tree_lookup(pui_tree, pui) || g_tree_lookup(downloading_tree, pui)) { /* Already downloading. */ g_slice_free(ProgressUpdateInfo, pui); return; @@ -471,7 +482,7 @@ pui->src_str = NULL; pui->dest_str = NULL; pui->file = NULL; -g_tree_insert(_pui_tree, pui, pui); +g_tree_insert(pui_tree, pui, pui); if (iap_is_connected() && !_curl_sid) _curl_sid = g_timeout_add(100, (GSourceFunc) map_download_timeout, NULL); @@ -482,54 +493,79 @@ if (!_num_downloads++) void map_download_init(void) { -_curl_easy_queue = g_queue_new(); -_pui_tree = g_tree_new_full((GCompareDataFunc) download_comparefunc, NULL, (GDestroyNotify) progress_update_info_free, NULL); -_downloading_tree = g_tree_new_full((GCompareDataFunc) download_comparefunc, NULL, (GDestroyNotify) progress_update_info_free, NULL); -_pui_by_easy = g_hash_table_new(g_direct_hash, g_direct_equal); +curl_easy_queue = g_queue_new(); +pui_tree = g_tree_new_full((GCompareDataFunc)download_comparefunc, NULL, (GDestroyNotify) progress_update_info_free, NULL); +downloading_tree = g_tree_new_full((GCompareDataFunc)download_comparefunc, NULL, (GDestroyNotify) progress_update_info_free, NULL); +pui_by_easy = g_hash_table_new(g_direct_hash, g_direct_equal); } -void -map_download_deinit(void) +gboolean +map_download_stop(void) { -/* Clean up CURL. */ if (_curl_multi) { CURL *curr; CURLMsg *msg; - gint num_transfers, num_msgs; + gint num_msgs; - /* First, remove all downloads from _pui_tree. */ - g_tree_destroy(_pui_tree); - - /* Finish up all downloads. */ - while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(_curl_multi, &num_transfers) || num_transfers) { - /* XXX: should inform the user why it's taking so damn long... */ + /* Clear the tree and create it again */ + if (pui_tree) { + g_tree_destroy(pui_tree); + pui_tree = g_tree_new_full((GCompareDataFunc)download_comparefunc, NULL, (GDestroyNotify) progress_update_info_free, NULL); } /* Close all finished files. */ while ((msg = curl_multi_info_read(_curl_multi, &num_msgs))) { if (msg->msg == CURLMSG_DONE) { /* This is a map download. */ - ProgressUpdateInfo *pui = g_hash_table_lookup(_pui_by_easy, msg->easy_handle); - g_queue_push_head(_curl_easy_queue, msg->easy_handle); - g_hash_table_remove(_pui_by_easy, msg->easy_handle); + ProgressUpdateInfo *pui = g_hash_table_lookup(pui_by_easy, msg->easy_handle); + g_queue_push_head(curl_easy_queue, msg->easy_handle); + g_hash_table_remove(pui_by_easy, msg->easy_handle); fclose(pui->file); curl_multi_remove_handle(_curl_multi, msg->easy_handle); } } - while ((curr = g_queue_pop_tail(_curl_easy_queue))) + g_debug("Stopping downloads"); + while ((curr = g_queue_pop_tail(curl_easy_queue))) curl_easy_cleanup(curr); - curl_multi_cleanup(_curl_multi); _curl_multi = NULL; + return TRUE; +} +g_debug("No downloads to stop"); +return FALSE; +} + +/* + * Clean up CURL and structures + */ +void +map_download_deinit(void) +{ +if (_curl_multi) { + CURL *curr; + gint num_transfers; + + /* Finish up all downloads. */ + while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(_curl_multi, &num_transfers) || num_transfers) { + g_debug("NT: %d", num_transfers); + } - g_queue_free(_curl_easy_queue); - g_tree_destroy(_downloading_tree); - g_hash_table_destroy(_pui_by_easy); + /* Stop all transfers and cleanup */ + map_download_stop(); + + if (pui_tree) + g_tree_destroy(pui_tree); + if (downloading_tree) + g_tree_destroy(downloading_tree); + if (pui_by_easy) + g_hash_table_destroy(pui_by_easy); + if (curl_easy_queue) + g_queue_free(curl_easy_queue); } if (_curl_sid) { g_source_remove(_curl_sid); _curl_sid = 0; -} +} } -- 2.39.5