]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/trainrouteplanner.cpp
Check that occupied_track is not null before accessing it
[r2c2.git] / source / libr2c2 / trainrouteplanner.cpp
index 45e83e267fb2b37e8b260630442e4a055089f667..3f8739347d455405f1f2a6fef03c6b2c02c5e3a9 100644 (file)
@@ -175,7 +175,7 @@ TrainRoutePlanner::TrainRoutingState::TrainRoutingState(const TrainRoutingState
 
 TrainRoutePlanner::TrainRoutingState::~TrainRoutingState()
 {
-       if(!--occupied_tracks->refcount)
+       if(occupied_tracks && !--occupied_tracks->refcount)
                delete occupied_tracks;
 }
 
@@ -184,7 +184,7 @@ Time::TimeDelta TrainRoutePlanner::TrainRoutingState::get_time_to_next_track() c
        return ((track->get_type().get_path_length(path)-offset)/info->speed)*Time::sec+delay;
 }
 
-bool TrainRoutePlanner::TrainRoutingState::is_occupied(Track &trk) const
+bool TrainRoutePlanner::TrainRoutingState::is_occupying(Track &trk) const
 {
        OccupiedTrack *occ = occupied_tracks;
        for(unsigned n=occ->n_tracks; n>0; --n, occ=occ->next)
@@ -336,17 +336,24 @@ bool TrainRoutePlanner::RoutingStep::update_states()
 
 bool TrainRoutePlanner::RoutingStep::check_deadlocks() const
 {
-       for(unsigned i=0; i<trains.size(); ++i)
+       for(vector<TrainRoutingState>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
        {
-               const TrainRoutingState &train = trains[i];
-               if(train.state!=BLOCKED)
+               if(i->state!=BLOCKED)
                        continue;
 
-               if(train.blocked_by<0)
+               if(i->blocked_by<0)
                        return true;
 
-               if(trains[train.blocked_by].blocked_by==static_cast<int>(i))
-                       return true;
+               int slow = i->blocked_by;
+               int fast = trains[slow].blocked_by;
+               while(fast>=0 && trains[fast].blocked_by>=0)
+               {
+                       if(fast==slow)
+                               return true;
+
+                       slow = trains[slow].blocked_by;
+                       fast = trains[trains[fast].blocked_by].blocked_by;
+               }
        }
 
        return false;
@@ -355,7 +362,7 @@ bool TrainRoutePlanner::RoutingStep::check_deadlocks() const
 int TrainRoutePlanner::RoutingStep::get_occupant(Track &track) const
 {
        for(unsigned i=0; i<trains.size(); ++i)
-               if(trains[i].is_occupied(track))
+               if(trains[i].is_occupying(track))
                        return i;
 
        return -1;