public class DrinkMutex extends Process implements Lock { private static final int tranquil = 0, thirsty = 1, drinking = 2; Boolean bottle[] = null, requestBottle[] = null, needBottle[] = null; /* needBottle = required resources */ DinMutex din; int myState = tranquil; public DrinkMutex(MsgHandler initComm) { super(initComm); din = new DinMutex(initComm); /* create diner instance for each drinker */ bottle = new Boolean[n]; requestBottle = new Boolean[n]; needBottle = new Boolean[n]; for (int i : neighbors) if (myId > i) { bottle[i] = false; requestBottle[i] = true; } else { bottle[i] = true; requestBottle[i] = false; } } public synchronized void requestCS() { myState = thirsty; needBottle[myId] = true; /* this for testing only - pass in required resources array instead */ if (haveBottles()) myState = drinking; else { din.requestCS(); /* force diner to hungry state */ for (int i : neighbors) if (needBottle[i] && requestBottle[i] && !bottle[i]) sendBool(i, "Request", requestBottle[i]); } while (myState != drinking) myWait(); } public synchronized void releaseCS() { myState = tranquil; din.releaseCS(); /* force diner to thinking state */ for (int i : neighbors) { needBottle[i] = false; /* clear required resources array */ if (requestBottle[i]) sendBool(i, "Bottle", bottle[i]); } } boolean haveBottles() { for (int i : neighbors) if (needBottle[i] && !bottle[i]) return false; return true; } void sendBool(int dest, String tag, Boolean b) { sendMsg(dest, tag); b = false; } public synchronized void handleMsg(Msg m, int src, String tag) { if (tag.equals("Request")) { requestBottle[src] = true; if (!needBottle[src]) sendBool(src, "Bottle", bottle[src]); else if ((myState != drinking) && !din.fork[src]) { sendBool(src, "Bottle", bottle[src]); if (needBottle[src]) sendBool(src, "Request", requestBottle[src]); } } else if (tag.equals("Bottle")) { bottle[src] = true; if (haveBottles()) myState = drinking; } } }