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(); } } } }