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
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. */
}
/* 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. */
}
/* 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();
} 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;
} 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);
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)
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. */
}
/* 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;
}
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;
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);
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;
-}
+}
}