Created
May 13, 2010 18:28
-
-
Save GaretJax/400189 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private process TicketShop { | |
// Wait to receive the array containing the references to all cars | |
receive this.cars(this.cars); | |
// Light sanity check to ensure that we have a valid cars array | |
// NOTE: We don't test for null values here and the whole array is | |
// passed by reference (are we sure? How behaves JR when passing | |
// values around using messages between multiple virtual machines?) | |
assert this.cars != null && this.cars.length > 0; | |
// Wait until the park is open | |
receive this.open(); | |
out("The roller coaster is now open!"); | |
int prev = this.cars.length - 1; // The index of the previous car | |
// Send to each car a message containing his ID and the car which comes | |
// before it on the ramp. | |
// | |
// The previous car is then used to synchronize the cars queue and to | |
// avoid overtakings along the ride. | |
for (int i = 0; i<this.cars.length; i++) { | |
send this.cars[i].prevCar(i, prev, this.cars[prev]); | |
prev = (prev + 1) % this.cars.length; | |
} | |
// Notify the first car in the queue that the roller coaster is now open | |
send this.cars[this.cars.length-1].ready(); | |
// The name of the last registered passenger (used only for the output) | |
String name; | |
// This loops runs until it blocks because a part of passengers has already | |
// finished their iterations and the remaining passengers are not enough to | |
// fill up a car. This causes a deadlock which is detected by the JR | |
// runtime, causing it to execute the registered quiescence action. | |
// | |
// This function will do one more iteration and then the JR park will | |
// definitively close. | |
while (!this.stopped) { | |
out("Waiting for the next car"); | |
int id; // The id of the next free car | |
int capacity; // The capacity of the next free car | |
// The callback used to send the "ride start" message | |
cap void (remote Passenger[]) start; | |
// The seats of the passengers of this car | |
remote Passenger[] passengers = new remote Passenger[capacity]; | |
// Wait for the next free car | |
receive nextCar(start, id, capacity); | |
out("Car %d is now ready, load %d passengers!", id, capacity); | |
// Collect tickets | |
for (int i = 0; i < capacity; i++) { | |
// Wait for a passenger | |
receive nextPassenger(name, passengers[i]); | |
// If the last passenger was null, then shorten the array to hold | |
// only non null values and start the car with only the passengers | |
// currently in the array. | |
// This happens only when the quiescence action sends a nextPassenger | |
// message holding null values to start the last ride. | |
if (passengers[i] == null) { | |
assert this.stopped; // We start the last tour with an incomplete | |
// car only if the park is already closed. | |
// Temporary array to shorten the current one | |
remote Passenger[] temp = passengers; | |
passengers = new remote Passenger[i]; | |
System.arraycopy(temp, 0, passengers, 0, i); | |
// Stop waiting for others passengers, they will never arrive. | |
break; | |
} | |
// Let the passenger take his place | |
out("%s (%d/%d) is sitting down", name, i + 1, capacity); | |
} | |
if (passengers.length > 0) { // Start the ride only if there is at least | |
// one passenger. | |
if (passengers.length == capacity) { // The car is full | |
out("Car %d is now full, start it!", id); | |
} else { | |
out("Starting car %d with %d out of %d passengers.", id, passengers.length, capacity); | |
} | |
// Start the car | |
send start(passengers); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment