Changeset - r9831:848a57462435
[Not reviewed]
master
0 3 0
frosch - 16 years ago 2008-08-03 14:16:57
frosch@openttd.org
(svn r13974) -Fix [YAPP]: A train crash could lead to stale reservations. (michi_cc)
3 files changed with 24 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/pbs.cpp
Show inline comments
 
@@ -204,13 +204,24 @@ static PBSTileInfo FollowReservation(Own
 
	return PBSTileInfo(tile, trackdir, false);
 
}
 

	
 
/** Callback for VehicleFromPos to find a train on a specific track. */
 
static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
 
{
 
	PBSTileInfo info = *(PBSTileInfo *)data;
 

	
 
	if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) && HasBit((TrackBits)v->u.rail.track, TrackdirToTrack(info.trackdir))) return v;
 

	
 
	return NULL;
 
}
 

	
 
/**
 
 * Follow a train reservation to the last tile.
 
 *
 
 * @param v the vehicle
 
 * @param train_on_res Is set to a train we might encounter
 
 * @returns The last tile of the reservation or the current train tile if no reservation present.
 
 */
 
PBSTileInfo FollowTrainReservation(const Vehicle *v)
 
PBSTileInfo FollowTrainReservation(const Vehicle *v, Vehicle **train_on_res)
 
{
 
	assert(v->type == VEH_TRAIN);
 

	
 
@@ -221,19 +232,10 @@ PBSTileInfo FollowTrainReservation(const
 

	
 
	PBSTileInfo res = FollowReservation(v->owner, GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes, tile, trackdir);
 
	res.okay = IsSafeWaitingPosition(v, res.tile, res.trackdir, true, _settings_game.pf.forbid_90_deg);
 
	if (train_on_res != NULL) *train_on_res = VehicleFromPos(res.tile, &res, FindTrainOnTrackEnum);
 
	return res;
 
}
 

	
 
/** Callback for VehicleFromPos to find a train on a specific track. */
 
static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
 
{
 
	PBSTileInfo info = *(PBSTileInfo *)data;
 

	
 
	if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) && HasBit((TrackBits)v->u.rail.track, TrackdirToTrack(info.trackdir))) return v;
 

	
 
	return NULL;
 
}
 

	
 
/**
 
 * Find the train which has reserved a specific path.
 
 *
src/pbs.h
Show inline comments
 
@@ -27,7 +27,7 @@ struct PBSTileInfo {
 
	PBSTileInfo(TileIndex _t, Trackdir _td, bool _okay) : tile(_t), trackdir(_td), okay(_okay) {}
 
};
 

	
 
PBSTileInfo FollowTrainReservation(const Vehicle *v);
 
PBSTileInfo FollowTrainReservation(const Vehicle *v, Vehicle **train_on_res = NULL);
 
bool IsSafeWaitingPosition(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false);
 
bool IsWaitingPositionFree(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false);
 

	
src/train_cmd.cpp
Show inline comments
 
@@ -3059,7 +3059,8 @@ bool TryPathReserve(Vehicle *v, bool mar
 
		}
 
	}
 

	
 
	PBSTileInfo origin = FollowTrainReservation(v);
 
	Vehicle *other_train = NULL;
 
	PBSTileInfo origin = FollowTrainReservation(v, &other_train);
 
	/* If we have a reserved path and the path ends at a safe tile, we are finished already. */
 
	if (origin.okay && (v->tile != origin.tile || first_tile_okay)) {
 
		/* Can't be stuck then. */
 
@@ -3067,6 +3068,14 @@ bool TryPathReserve(Vehicle *v, bool mar
 
		ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
		return true;
 
	}
 
	/* The path we are driving on is alread blocked by some other train.
 
	 * This can only happen when tracks and signals are changed. A crash
 
	 * is probably imminent, don't do any further reservation because
 
	 * it might cause stale reservations. */
 
	if (other_train != NULL && v->tile != origin.tile) {
 
		if (mark_as_stuck) MarkTrainAsStuck(v);
 
		return false;
 
	}
 

	
 
	/* If we are in a depot, tentativly reserve the depot. */
 
	if (v->u.rail.track & TRACK_BIT_DEPOT) {
0 comments (0 inline, 0 general)