/* After this call is executed successfully, the occupied parking stand * becomes Available,and the used runway is InOperation for the * length of operation duration parameter and can't handle any other * operations during this time. After operation finishes, the runway becomes * Available again. The call is non-blocking, i.e. it returns before the * runway is cleared. */ public PerformResult PerformTakeOff(TakeOffRequestToken token) { token.Stop(); token.Elapsed -= OnExpiredTakeOffToken; if (DateTime.Now <= token.expiration && !token.hasExpired) { Runway runway = GetRunwayById(token.runwayId); // Check if the runway exists and if it has been properly reserved if (runway == null || runway.state != Runway.RunwayState.Reserved) { ReleaseTakeOffResources(token); return(PerformResult.InvalidParameters); } runway.aircraftId = token.aircraftId; runway.Elapsed += OnTakeOffOperationComplete; ParkingStand parkingStand = GetParkingStandByAircraftId(token.aircraftId); parkingStand.aircraftId = Guid.Empty; parkingStand.state = ParkingStand.ParkingStandState.Available; token.Dispose(); runway.Operate(); return(PerformResult.Success); } else // Token has expired { if (!token.hasExpired) // If the token's expiration date has passed but the elapsed event hasn't fired yet, then release the resources { ReleaseTakeOffResources(token); } return(PerformResult.ExpiredToken); } }
// Release resources resereved by a takeoff request token that will not be used. private void ReleaseTakeOffResources(TakeOffRequestToken token) { Runway runway = GetRunwayById(token.runwayId); runway.state = Runway.RunwayState.Available; runway.aircraftId = Guid.Empty; token.Dispose(); }
// Releases resources when the takeoff token's timer elapses. private void OnExpiredTakeOffToken(object source, ElapsedEventArgs e) { TakeOffRequestToken token = (TakeOffRequestToken)source; // Unsubscribe from the token's timer. token.Elapsed -= OnExpiredTakeOffToken; // Release the token's resources. ReleaseTakeOffResources(token); }
/* After a successful call, the resources necessary to perform the operation * should be reserved for the time of the returned authorization. */ public RequestResult RequestTakeOff(Guid aircraftId) { mutex.WaitOne(); // A runway is available. if (NumberOfAvailableRunways() > 0) { Guid runwayId = ReserveAvailableRunway(); // Create the takeoff request token TakeOffRequestToken token = new TakeOffRequestToken(TokenValiditySeconds, aircraftId, runwayId); // Subscribe for token's expiration to ensure reserved resources can be released. token.Elapsed += OnExpiredTakeOffToken; mutex.ReleaseMutex(); return(new RequestResult(RequestResult.RequestState.Proceed, token)); } else { mutex.ReleaseMutex(); return(new RequestResult(RequestResult.RequestState.Hold, null)); } }