bool lock(SessionId owner,bool exclusive, unsigned timeout) { CTimeMon tm(timeout); sect.enter(); loop { unsigned num = owners.ordinality(); if (exclusive) { if (num==0) { owners.append(owner); exclusivenest = 1; break; } else if (exclusivenest && (owners.item(0)==owner)) { exclusivenest++; break; } } else if (!exclusivenest) { owners.append(owner); break; } waiting++; sect.leave(); unsigned remaining; if (tm.timedout(&remaining)||!sem.wait(remaining)) { sect.enter(); if (!sem.wait(0)) { waiting--; sect.leave(); return false; } } else sect.enter(); } sect.leave(); return true; }
void unlock(SessionId owner) { sect.enter(); if (exclusivenest) { exclusivenest--; if (exclusivenest) { // still locked assertex(owners.item(0)==owner); sect.leave(); return; } } verifyex(owners.zap(owner)); if (owners.ordinality()==0) { exclusivenest = 0; if (waiting) { sem.signal(waiting); waiting = 0; } } else { assertex(!exclusivenest); } sect.leave(); }