import java.util.*;
public class Arrow extends Process implements Lock {
int holder; // Neighbor in direction of privileged node.
boolean using = false; // True if we are in critical section.
LinkedList<Integer> requestQ = new LinkedList<Integer>(); // requesting neighbors
boolean asked = false; // Eliminates redundant requests for the privilege.
boolean initialized = false;
public Arrow(MsgHandler initComm) {
super(initComm);
// if(myId==0) initialize(0);
}
private void initialize(int src) {
holder = src;
initialized = true;
for (int i: neighbors)
if (i != src)
sendMsg(i, "INITIALIZE");
}
public synchronized void requestCS() {
while (!initialized) myWait();
requestQ.add(myId);
assignPrivilege();
if(!using) makeRequest();
while(!using) myWait();
}
private void assignPrivilege() {
if ((holder==myId) && !using && !requestQ.isEmpty()) {
holder = requestQ.remove(); // New holder gets the privilege.
asked = false;
if(holder == myId)
using = true; // New holder is me, enter the CS.
else
sendMsg(holder, "PRIVILEGE") ;
}
}
private void makeRequest() {
if(holder!=myId && requestQ.size()!=0 && !asked) {
sendMsg(holder, "REQUEST");
asked = true;
}
}
public synchronized void releaseCS() {
using = false;
assignPrivilege(); makeRequest();
}
public synchronized void handleMsg(Msg m, int src, String tag) {
if (tag.equals("INITIALIZE")) initialize(src);
else {
while (!initialized) myWait();
if (tag.equals("REQUEST")) {
requestQ.add(src);
assignPrivilege(); makeRequest();
} else if (tag.equals("PRIVILEGE")) {
holder = myId;
assignPrivilege(); makeRequest();
}
}
}
}