Control: tags -1 upstream fixed-upstream patch

On 2023-11-09 08:49:50 +0100, Paul Gevers wrote:
> Control: forwarded -1 https://github.com/viking-gps/viking/issues/202
> 
> Hi,
> 
> Thanks. I have forwarded the issue upstream.

I've attached a patch. This is the upstream patch by Rob Norris

  https://github.com/viking-gps/viking/commit/21ecac2

which I ported for viking 1.10 in Debian 12:

* 2 hunks were rejected in src/vikmapslayer.c due to changes in
  reindented code (I just had to re-add the "if").

* the compilation was failing due to undefined variable dr,
  so I just had to take the current code at this point, giving
  this simple change in src/vikmapslayer.c:

+        DownloadResult_t dr = DOWNLOAD_NOT_REQUIRED;
         if (need_download) {
-          DownloadResult_t dr = vik_map_source_download( 
MAPS_LAYER_NTH_TYPE(mdi->maptype), &(mdi->mapcoord), mdi->filename_buf, handle);
+          dr = vik_map_source_download( MAPS_LAYER_NTH_TYPE(mdi->maptype), 
&(mdi->mapcoord), mdi->filename_buf, handle);

I've done several tests, and everything is now fine on my machine.

-- 
Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
Description: avoid segmentation fault on map download when quitting
Bug-Debian: https://bugs.debian.org/1055624
Forwarded: https://github.com/viking-gps/viking/issues/202

Index: viking-1.10/src/curl_download.c
===================================================================
--- viking-1.10.orig/src/curl_download.c
+++ viking-1.10/src/curl_download.c
@@ -249,6 +249,8 @@ CURL_download_t curl_download_uri ( cons
       g_warning("%s: http response: %ld for uri %s", __FUNCTION__, response, 
uri);
       res = CURL_DOWNLOAD_ERROR;
     }
+  } else if (res == CURLE_ABORTED_BY_CALLBACK) {
+    res = CURL_DOWNLOAD_ABORTED;
   } else {
     g_warning ( "%s: curl error: %d for uri %s", __FUNCTION__, res, uri );
     res = CURL_DOWNLOAD_ERROR;
Index: viking-1.10/src/curl_download.h
===================================================================
--- viking-1.10.orig/src/curl_download.h
+++ viking-1.10/src/curl_download.h
@@ -32,7 +32,8 @@ G_BEGIN_DECLS
 typedef enum {
   CURL_DOWNLOAD_NO_ERROR = 0,
   CURL_DOWNLOAD_NO_NEWER_FILE,
-  CURL_DOWNLOAD_ERROR
+  CURL_DOWNLOAD_ERROR,
+  CURL_DOWNLOAD_ABORTED
 } CURL_download_t;
 
 typedef struct {
Index: viking-1.10/src/download.c
===================================================================
--- viking-1.10.orig/src/download.c
+++ viking-1.10/src/download.c
@@ -401,7 +401,11 @@ static DownloadResult_t download( const
 
   DownloadResult_t result = DOWNLOAD_SUCCESS;
 
-  if (ret != CURL_DOWNLOAD_NO_ERROR && ret != CURL_DOWNLOAD_NO_NEWER_FILE) {
+  if (ret == CURL_DOWNLOAD_ABORTED) {
+    g_debug("%s: download aborted: curl_download_get_url=%d", __FUNCTION__, 
ret);
+    failure = TRUE;
+    result = DOWNLOAD_USER_ABORTED;
+  } else if (ret == CURL_DOWNLOAD_ERROR) {
     g_debug("%s: download failed: curl_download_get_url=%d", __FUNCTION__, 
ret);
     failure = TRUE;
     result = DOWNLOAD_HTTP_ERROR;
Index: viking-1.10/src/download.h
===================================================================
--- viking-1.10.orig/src/download.h
+++ viking-1.10/src/download.h
@@ -107,6 +107,7 @@ typedef enum {
   DOWNLOAD_CONTENT_ERROR = -1,
   DOWNLOAD_SUCCESS = 0,
   DOWNLOAD_NOT_REQUIRED = 1, // Also 'successful'. e.g. Because file already 
exists and no time checks used
+  DOWNLOAD_USER_ABORTED = 2, // Not an error, but not really successful either 
- no actual download completed
 } DownloadResult_t;
 
 /* TODO: convert to Glib */
Index: viking-1.10/src/vikdemlayer.c
===================================================================
--- viking-1.10.orig/src/vikdemlayer.c
+++ viking-1.10/src/vikdemlayer.c
@@ -1348,6 +1348,7 @@ static void srtm_dem_download_thread ( D
     }
     case DOWNLOAD_SUCCESS:
     case DOWNLOAD_NOT_REQUIRED:
+    case DOWNLOAD_USER_ABORTED:
     default:
       break;
   }
Index: viking-1.10/src/vikmapslayer.c
===================================================================
--- viking-1.10.orig/src/vikmapslayer.c
+++ viking-1.10/src/vikmapslayer.c
@@ -359,6 +359,7 @@ void maps_layer_uninit ()
 {
   vik_mutex_free ( rq_mutex );
   g_hash_table_destroy ( requests );
+  rq_mutex = NULL;
 }
 
 /****************************************/
@@ -447,10 +448,15 @@ gboolean req_hash_remove_id  (gpointer k
 
 static void requests_clear ( guint maptype )
 {
-  guint id = vik_map_source_get_uniq_id ( MAPS_LAYER_NTH_TYPE(maptype) );
-  g_mutex_lock ( rq_mutex );
-  g_hash_table_foreach_remove ( requests, req_hash_remove_id, 
GUINT_TO_POINTER(id) );
-  g_mutex_unlock ( rq_mutex );
+  // Ensure mutex (and therefore hash) is available
+  //  as can become unavailable on program exit
+  //  yet this function may still be called from existing threads
+  if ( rq_mutex ) {
+    guint id = vik_map_source_get_uniq_id ( MAPS_LAYER_NTH_TYPE(maptype) );
+    g_mutex_lock ( rq_mutex );
+    g_hash_table_foreach_remove ( requests, req_hash_remove_id, 
GUINT_TO_POINTER(id) );
+    g_mutex_unlock ( rq_mutex );
+  }
 }
 
 /**
@@ -1669,13 +1675,18 @@ static gchar *create_request_string ( Ma
 
 static void mark_request_complete ( MapDownloadInfo *mdi, gint x, gint y )
 {
-  gchar *request = create_request_string ( mdi, x, y );
-  g_mutex_lock ( rq_mutex );
-  (void)g_hash_table_remove ( requests, request );
-  g_mutex_unlock ( rq_mutex );
-  if ( vik_verbose )
-    g_debug ( "%s: %s", __FUNCTION__, request );
-  g_free ( request );
+  // Ensure mutex (and therefore hash) is available
+  //  as can become unavailable on program exit
+  //  yet this function may still be called from existing threads
+  if ( rq_mutex ) {
+    gchar *request = create_request_string ( mdi, x, y );
+    g_mutex_lock ( rq_mutex );
+    (void)g_hash_table_remove ( requests, request );
+    g_mutex_unlock ( rq_mutex );
+    if ( vik_verbose )
+      g_debug ( "%s: %s", __FUNCTION__, request );
+    g_free ( request );
+  }
 }
 
 static int map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata )
@@ -1794,8 +1805,9 @@ static int map_download_thread ( MapDown
 
         mdi->mapcoord.x = x; mdi->mapcoord.y = y;
 
+        DownloadResult_t dr = DOWNLOAD_NOT_REQUIRED;
         if (need_download) {
-          DownloadResult_t dr = vik_map_source_download( 
MAPS_LAYER_NTH_TYPE(mdi->maptype), &(mdi->mapcoord), mdi->filename_buf, handle);
+          dr = vik_map_source_download( MAPS_LAYER_NTH_TYPE(mdi->maptype), 
&(mdi->mapcoord), mdi->filename_buf, handle);
           switch ( dr ) {
             case DOWNLOAD_PARAMETERS_ERROR:
             case DOWNLOAD_HTTP_ERROR:
@@ -1816,6 +1828,8 @@ static int map_download_thread ( MapDown
             case DOWNLOAD_NOT_REQUIRED:
              need_download = FALSE;
              break;
+            case DOWNLOAD_USER_ABORTED:
+              break;
             default:
               break;
           }
@@ -1823,17 +1837,23 @@ static int map_download_thread ( MapDown
 
         mark_request_complete ( mdi, x, y );
 
-        g_mutex_lock(mdi->mutex);
-        if (remove_mem_cache)
+        // Avoid attempting to update mapcache when download aborted
+        //  1. Since no real change to track
+        //  2. more importantly, if the program is ending then the mapcache 
may have been removed
+        if ( dr != DOWNLOAD_USER_ABORTED ) {
+
+          g_mutex_lock(mdi->mutex);
+          if (remove_mem_cache)
             a_mapcache_remove_all_shrinkfactors ( x, y, mdi->mapcoord.z, 
vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(mdi->maptype)), 
mdi->mapcoord.scale, mdi->vml->filename );
-        if (mdi->refresh_display && mdi->map_layer_alive) {
-          /* TODO: check if it's on visible area */
-          if ( need_download ) {
-            vik_layer_emit_update ( VIK_LAYER(mdi->vml), FALSE ); // NB update 
display from background
+          if (mdi->refresh_display && mdi->map_layer_alive) {
+            /* TODO: check if it's on visible area */
+            if ( need_download ) {
+              vik_layer_emit_update ( VIK_LAYER(mdi->vml), FALSE ); // NB 
update display from background
+            }
           }
+          g_mutex_unlock(mdi->mutex);
+          mdi->mapcoord.x = mdi->mapcoord.y = 0; /* we're temporarily between 
downloads */
         }
-        g_mutex_unlock(mdi->mutex);
-        mdi->mapcoord.x = mdi->mapcoord.y = 0; /* we're temporarily between 
downloads */
       }
     }
   }

Reply via email to