]> git.tdb.fi Git - r2c2.git/commitdiff
Make sure Block::signal_reserved is emitted consistently
authorMikko Rasa <tdb@tdb.fi>
Fri, 6 Feb 2015 14:37:46 +0000 (16:37 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 6 Feb 2015 14:48:23 +0000 (16:48 +0200)
Sigc++ apparently takes arguments as references, so if someone reached to
a signal with null train by reserving the block again, any remaining slots
of the release emission would also get the new train pointer.  This caused
the routing system to malfunction in certain cases as the router saw two
emissions for the same block reservation.

The simplest solution would be to pass t instead of train to emit(), but
then the ordering of the two emissions would be inconsistent.  Thus the
additional logic to delay further emissions until the outstanding one is
completed.

source/libr2c2/block.cpp
source/libr2c2/block.h

index a0d90f3a3ea153586342cc202707fe88ee313f3a..25b3bc8b85163d0bfd2ece6a54718f02b840ec6d 100644 (file)
@@ -1,4 +1,5 @@
 #include <algorithm>
+#include <msp/core/raii.h>
 #include <msp/strings/format.h>
 #include <msp/time/units.h>
 #include "block.h"
@@ -20,7 +21,9 @@ Block::Block(Layout &l, Track &start):
        turnout_addr(start.get_turnout_address()),
        conflict(false),
        sensor(0),
-       train(0)
+       train(0),
+       pending_train(0),
+       emitting_reserve(false)
 {
        add_track(start);
 
@@ -167,10 +170,19 @@ Block *Block::get_link(unsigned epi) const
 
 bool Block::reserve(Train *t)
 {
-       if(!t || !train)
+       if(!t || !(emitting_reserve ? pending_train : train))
        {
-               train = t;
-               signal_reserved.emit(train);
+               pending_train = t;
+               if(!emitting_reserve)
+               {
+                       while(pending_train!=train)
+                       {
+                               train = pending_train;
+                               SetFlag setf(emitting_reserve);
+                               signal_reserved.emit(train);
+                       }
+               }
+
                return true;
        }
        else
index f255e43f2e2421fb18b81bd9c0a6e862e0218a63..6823b2730343faa69c03b14b0f507701ad26b85d 100644 (file)
@@ -38,6 +38,8 @@ private:
        TrackCircuit *sensor;
        std::vector<Endpoint> endpoints;
        Train *train;
+       Train *pending_train;
+       bool emitting_reserve;
 
 public:
        Block(Layout &, Track &);