summaryrefslogtreecommitdiff
path: root/navit
diff options
context:
space:
mode:
authormvglasow <michael -at- vonglasow.com>2015-10-09 14:08:56 +0200
committermvglasow <michael -at- vonglasow.com>2015-10-14 11:12:28 +0200
commit0dfd784eaf655079648a663594dd8174abbc4390 (patch)
tree061bdda6e536a7b0e65bc623ddf380b0336ec352 /navit
parent418bbf2168c3e871a04921d5b29b15d0fc87888c (diff)
downloadnavit-0dfd784eaf655079648a663594dd8174abbc4390.tar.gz
Fix:core:Do not crash if navigation is stopped during maneuver generation
Signed-off-by: mvglasow <michael -at- vonglasow.com>
Diffstat (limited to 'navit')
-rw-r--r--navit/navigation.c52
-rw-r--r--navit/route.c11
-rw-r--r--navit/route.h1
3 files changed, 48 insertions, 16 deletions
diff --git a/navit/navigation.c b/navit/navigation.c
index b9da953b2..440d500f1 100644
--- a/navit/navigation.c
+++ b/navit/navigation.c
@@ -3765,13 +3765,26 @@ navigation_call_callbacks(struct navigation *this_, int force_speech)
}
/**
- * @brief Initiates maneuver creation.
+ * @brief Cleans up and initiates maneuver creation.
*
* This function is called by {@link navigation_update_idle(struct navigation *, struct map_rect *, struct item **, int *)}
* after it has retrieved all objects from the route map.
+ *
+ * It will reset the navigation object's idle event/callback, deallocate some temporary objects and
+ * reset the {@code busy} flag. Arguments correspond to those of
+ * {@link navigation_update_idle(struct navigation *, struct map_rect *, struct item **, int *)}.
+ *
+ * @param this_ Points to the navigation object
+ * @param mr Points to a map rect on the route map. After the function returns, the map rect os no
+ * longer valid.
+ * @param ritem Points to a buffer that will be freed.
+ * returns.
+ * @param first Points to a buffer that will be freed.
+ * @param cancel If true, only cleanup (deallocation of objects) will be done and no maneuvers will be generated.
+ * If false, maneuvers will be generated.
*/
static void
-navigation_update_done(struct navigation *this_, struct map_rect *mr, struct item **ritem, int *first) {
+navigation_update_done(struct navigation *this_, struct map_rect *mr, struct item **ritem, int *first, int cancel) {
int incr = 0;
time_t now;
@@ -3782,19 +3795,21 @@ navigation_update_done(struct navigation *this_, struct map_rect *mr, struct ite
this_->idle_ev=NULL;
this_->idle_cb=NULL;
- time(&now);
- dbg(lvl_info, "generating maneuvers, time elapsed: %.f s\n", difftime(now, this_->starttime));
-
- if (*first)
- navigation_destroy_itms_cmds(this_, NULL);
- else {
- if (! *ritem) {
- navigation_itm_new(this_, NULL);
- make_maneuvers(this_,this_->route);
+ if (!cancel) {
+ time(&now);
+ dbg(lvl_info, "generating maneuvers, time elapsed: %.f s\n", difftime(now, this_->starttime));
+
+ if (*first)
+ navigation_destroy_itms_cmds(this_, NULL);
+ else {
+ if (! *ritem) {
+ navigation_itm_new(this_, NULL);
+ make_maneuvers(this_,this_->route);
+ }
+ calculate_dest_distance(this_, incr);
+ profile(0,"end");
+ navigation_call_callbacks(this_, FALSE);
}
- calculate_dest_distance(this_, incr);
- profile(0,"end");
- navigation_call_callbacks(this_, FALSE);
}
map_rect_destroy(mr);
g_free(ritem);
@@ -3802,7 +3817,7 @@ navigation_update_done(struct navigation *this_, struct map_rect *mr, struct ite
this_->busy = 0;
time(&now);
- dbg(lvl_info, "done generating maneuvers, time elapsed: %.f s\n", difftime(now, this_->starttime));
+ dbg(lvl_info, "done, time elapsed: %.f s\n", difftime(now, this_->starttime));
}
/**
@@ -3830,12 +3845,17 @@ navigation_update_idle(struct navigation *this_, struct map_rect *mr, struct ite
struct navigation_itm *itm;
time_t now;
+ if (!route_has_graph(this_->route)) {
+ navigation_update_done(this_, mr, ritem, first, 1);
+ return;
+ }
+
while ((count > 0)) {
count--;
if (!(*ritem = map_rect_get_item(mr))) {
time(&now);
dbg(lvl_info, "processed %d map items, time elapsed: %.f s\n", (100 - count), difftime(now, this_->starttime));
- navigation_update_done(this_, mr, ritem, first);
+ navigation_update_done(this_, mr, ritem, first, 0);
return;
}
if ((*ritem)->type == type_route_start && this_->turn_around > -this_->turn_around_limit+1)
diff --git a/navit/route.c b/navit/route.c
index 7214b35d7..11519b6d9 100644
--- a/navit/route.c
+++ b/navit/route.c
@@ -3898,6 +3898,17 @@ route_get_graph_map(struct route *this_)
return route_get_map_helper(this_, &this_->graph_map, "route_graph","Route Graph");
}
+
+/**
+ * @brief Whether the route has a valid graph.
+ *
+ * @return True if the route has a graph, false if not.
+ */
+int
+route_has_graph(struct route *this_) {
+ return (this_->graph != NULL);
+}
+
void
route_set_projection(struct route *this_, enum projection pro)
{
diff --git a/navit/route.h b/navit/route.h
index 5daae7f89..b5c2b01aa 100644
--- a/navit/route.h
+++ b/navit/route.h
@@ -111,6 +111,7 @@ void route_info_free(struct route_info *inf);
struct street_data *route_info_street(struct route_info *rinf);
struct map *route_get_map(struct route *this_);
struct map *route_get_graph_map(struct route *this_);
+int route_has_graph(struct route *this_);
void route_set_projection(struct route *this_, enum projection pro);
void route_set_destinations(struct route *this_, struct pcoord *dst, int count, int async);
int route_set_attr(struct route *this_, struct attr *attr);