2011-01-14 20:49:41 +01:00
|
|
|
/* cortexLocks.js
|
|
|
|
* PURPOSE
|
|
|
|
* AUTHOR
|
|
|
|
* LICENSE
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
*/
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
/* locks -> [ class: [type, locks], ] */
|
2011-01-14 20:49:41 +01:00
|
|
|
var locks = new Array();
|
2011-04-01 07:42:52 +02:00
|
|
|
/* -> [ class : lock] (you can only req/acq 1 lock per class */
|
|
|
|
var locksReq = new Array();
|
|
|
|
var locksAcq = new Array();
|
2011-01-14 20:49:41 +01:00
|
|
|
|
|
|
|
function copyobj(arr) {
|
|
|
|
c = new Object();
|
|
|
|
for (i in arr) {
|
|
|
|
c[i] = arr[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
function locksClassType(klass) {
|
|
|
|
return locks[klass]['type'];
|
|
|
|
}
|
|
|
|
|
|
|
|
function locksClassLocks(klass) {
|
|
|
|
return locks[klass]['locks'];
|
|
|
|
}
|
|
|
|
|
2011-01-26 08:49:52 +01:00
|
|
|
function registerLockFn(ltype, fnName, fn) {
|
|
|
|
registerFn("locks." +ltype+"."+fnName, fn);
|
|
|
|
}
|
2011-04-01 07:42:52 +02:00
|
|
|
/*
|
|
|
|
function execLockFn(fnName, args) {
|
|
|
|
type = locksClassType(args['class']);
|
|
|
|
args['type'] = type;
|
|
|
|
locks = locksClassLocks(args['class']);
|
|
|
|
args['locks'] = locks;
|
|
|
|
return execFn("locks."+type+"."+fnName, args);
|
|
|
|
}*/
|
|
|
|
|
|
|
|
function locksInitClass(klass, type) {
|
|
|
|
locks[klass]['type'] = type;
|
|
|
|
locks[klass]['locks'] = new Array();
|
|
|
|
|
|
|
|
locksReq[klass] = new Array();
|
|
|
|
locksAcq[klass] = new Array();
|
2011-01-26 08:49:52 +01:00
|
|
|
}
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**** Core Lock Functions
|
|
|
|
* get(table, info) BR -> getLock
|
|
|
|
* equal(a, b) - > locksEqual
|
|
|
|
* ?msg(lock)
|
2011-01-26 08:49:52 +01:00
|
|
|
*/
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
function getLock(info) {
|
|
|
|
type = locksClassType(info['class']);
|
|
|
|
info['type'] = type;
|
|
|
|
locks = locksClassLocks(info['class']);
|
|
|
|
info['locks'] = locks;
|
|
|
|
return execFn("locks."+type+".get", info);
|
|
|
|
}
|
|
|
|
|
|
|
|
registerLockFn("basic", "get",
|
2011-01-26 08:49:52 +01:00
|
|
|
function (args) {
|
2011-04-01 07:42:52 +02:00
|
|
|
lock = args['locks'][args['name']];
|
|
|
|
if ( ! lock.name) {
|
|
|
|
lock.name =args['name'];
|
|
|
|
lock.locked = false;
|
|
|
|
lock.type = 'basic';
|
|
|
|
}
|
|
|
|
return lock;
|
2011-01-26 08:49:52 +01:00
|
|
|
});
|
|
|
|
|
2011-03-01 08:40:37 +01:00
|
|
|
function genRangeCell(name, start, end, next) {
|
|
|
|
var c = new Object();
|
|
|
|
c.name = name;
|
2011-04-01 07:42:52 +02:00
|
|
|
c.type = 'range';
|
2011-03-01 08:40:37 +01:00
|
|
|
c.start=start;
|
|
|
|
c.end = end;
|
|
|
|
c.next = next;
|
|
|
|
c.locked = false;
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getRangeLock(rangeLocks, name, start, end) {
|
|
|
|
log("getRangeLock for (" + name + " from " + start + " to " + end + ")");
|
|
|
|
if (!rangeLocks[name]) {
|
|
|
|
log("no locks for " + name + ", so MAKING");
|
|
|
|
rangeLocks[name] = genRangeCell(name, start, end);
|
|
|
|
return rangeLocks[name];
|
|
|
|
}
|
|
|
|
log("locks exist for " + name + " so SEARCHING forward");
|
|
|
|
var rlock = rangeLocks[name];
|
|
|
|
|
|
|
|
if(end < rlock.start) {
|
|
|
|
log("Space before first lock, MAKING HERE");
|
|
|
|
rangeLocks[name] = genRangeCell(name, start, end);
|
|
|
|
rangeLocks[name].next = rlock;
|
|
|
|
return rangeLocks[name];
|
|
|
|
}
|
|
|
|
|
|
|
|
while(rlock.next && rlock.start < rlock.end+1) {
|
|
|
|
log("looking at (" + rlock.start + " to " + rlock.end + ")");
|
|
|
|
if (rlock.start == start && rlock.end == end) {
|
|
|
|
log("FOUND IT");
|
|
|
|
return rlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rlock.end < start && rlock.next.start > end) {
|
|
|
|
log("GAP between (" + rlock.start + " to " + rlock.end + ") and (" + rlock.next.start + " to " + rlock.next.end + ") where we should be so MAKING THERE");
|
|
|
|
var nlock = rlock.next;
|
|
|
|
rlock.next = genRangeCell(name, start, end);
|
|
|
|
rlock.next.next = nlock;
|
|
|
|
return rlock.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
rlock = rlock.next;
|
|
|
|
}
|
|
|
|
log("SEARCH ended");
|
|
|
|
if (rlock.start == start && rlock.end == end) {
|
|
|
|
log("Found it!");
|
|
|
|
return rlock;
|
|
|
|
} else {
|
|
|
|
if (rlock.end < start) {
|
|
|
|
log("There is space at the end to make what we want");
|
|
|
|
rlock.next = genRangeCell(name, start, end);
|
|
|
|
return rlock.next;
|
|
|
|
} else {
|
|
|
|
log("search ended after what we wanted, FAIL");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
registerLockFn("range", "get",
|
2011-01-26 08:49:52 +01:00
|
|
|
function (args) {
|
2011-03-01 08:40:37 +01:00
|
|
|
var l = getRangeLock(arg['locks'] , args['name'], args['start'], args'[end']);
|
2011-01-26 08:49:52 +01:00
|
|
|
if (l == null)
|
|
|
|
error("retrieveLock for range got null");
|
|
|
|
return l;
|
|
|
|
});
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
function lockTypesEqual(a, b) {
|
|
|
|
if(a == null || b == null)
|
|
|
|
return false;
|
|
|
|
if(a['type'] != b['type'])
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-26 08:49:52 +01:00
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
registerLockFn("basic", "equals",
|
|
|
|
function(args) { // locksEqual(a, b)
|
|
|
|
var a = args['a'];
|
|
|
|
var b = arbs['b'];
|
|
|
|
if (!lockTypesEqual(a, b))
|
|
|
|
return false;
|
|
|
|
if (a.name == b.name)
|
|
|
|
return true;
|
|
|
|
else
|
2011-03-01 08:40:37 +01:00
|
|
|
return false;
|
|
|
|
});
|
2011-04-01 07:42:52 +02:00
|
|
|
|
|
|
|
registerLockFn("range", "equals",
|
|
|
|
function(args) { // locksEqual(a, b)
|
|
|
|
var a = args['a'];
|
|
|
|
var b = arbs['b'];
|
|
|
|
if (!lockTypesEqual(a, b))
|
2011-03-01 08:40:37 +01:00
|
|
|
return false;
|
2011-04-01 07:42:52 +02:00
|
|
|
|
|
|
|
log("locksEqual? " + a.name + " (" + a.start + " to " + a.end + ") and " + b.name + " (" + b.start + " to " + b.end + ")");
|
|
|
|
if (a.name == b.name && a.start == b.start && a.end == b.end) {
|
|
|
|
log("true");
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
log("false");
|
|
|
|
return false;
|
|
|
|
}
|
2011-03-01 08:40:37 +01:00
|
|
|
});
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
functions locksEqual(a, b) {
|
|
|
|
args = new Array();
|
|
|
|
args['a'] = a;
|
|
|
|
args['b'] = b;
|
|
|
|
return execFn("locks."+a['type']+".equals", args);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** Non Networked Lock functions
|
|
|
|
* lock
|
|
|
|
* release
|
|
|
|
* isLocked
|
|
|
|
* removeLocks
|
|
|
|
*/
|
|
|
|
|
|
|
|
function isLocked(lock) {
|
|
|
|
return lock.locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
function lock(lock) {
|
|
|
|
lock['locked'] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function release(lock) {
|
|
|
|
lock['locked'] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************** REVIEW HERE ******************/
|
2011-03-01 08:40:37 +01:00
|
|
|
|
2011-03-17 07:02:40 +01:00
|
|
|
registerLockFn("basic", "remove",
|
2011-03-01 08:40:37 +01:00
|
|
|
function(args) {
|
|
|
|
for(var i in args['locks']) {
|
|
|
|
var lock = args['locks'][i];
|
|
|
|
if (!lock)
|
|
|
|
continue;
|
|
|
|
if (lock.addr == addr) {
|
|
|
|
lock.locked = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2011-03-17 07:02:40 +01:00
|
|
|
registerLockFn("range", "remove",
|
2011-03-01 08:40:37 +01:00
|
|
|
function(args) {
|
|
|
|
for(var i in args['locks']) {
|
|
|
|
log("freeing " + i + " locks");
|
|
|
|
var rlock = args['locks'][i];
|
|
|
|
while (rlock != null) {
|
|
|
|
log("looking at " + i + " (" + rlock.start + " to " + rlock.end + ") : " + rlock.addr);
|
|
|
|
if (rlock.addr == args['addr']) {
|
|
|
|
log("unlocking");
|
|
|
|
rlock.locked = false;
|
|
|
|
}
|
|
|
|
rlock = rlock.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2011-03-17 07:02:40 +01:00
|
|
|
function genLockTry(lockTry) {
|
|
|
|
lockTry.time = getTime();
|
|
|
|
lockTry.dlc = dlc+1;
|
|
|
|
lockTry.name = name;
|
|
|
|
lockTry.addr = localNodeAddr;
|
|
|
|
lockTry.type = type;
|
|
|
|
lockTry.okay = 1;
|
|
|
|
lockTry.locked = false;
|
|
|
|
var d = new Date();
|
|
|
|
lockTry.localTime = d.getTime();
|
|
|
|
}
|
|
|
|
|
|
|
|
function genGetLockMsg() {
|
|
|
|
var m = new Object();
|
|
|
|
m["query"] = "getLock";
|
|
|
|
m["time"] = lockTry.time;
|
|
|
|
m["addr"] = localNodeAddr;
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2011-04-01 07:42:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
registerLockFn("basic", "release",
|
|
|
|
function (args) {
|
|
|
|
var lock = myLocks[type];
|
|
|
|
myLocks[type] = null;
|
|
|
|
|
|
|
|
lock.locked = false;
|
|
|
|
|
|
|
|
|
|
|
|
var m = new Object();
|
|
|
|
m["query"] = "releaseLock";
|
|
|
|
m["type"] = type;
|
|
|
|
m["name"] = lock.name;
|
|
|
|
if (type == "range") {
|
|
|
|
m["start"] = lock.start;
|
|
|
|
m["end"] = lock.end;
|
|
|
|
}
|
|
|
|
|
|
|
|
bcastMsg(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**** Netowkr Lock using functions
|
|
|
|
* aquire
|
|
|
|
* grant(resp, lock
|
|
|
|
* deny(resp, lock
|
|
|
|
* handleLockReq
|
|
|
|
* handleLockResp
|
|
|
|
* lockGranted
|
|
|
|
* checkLocks
|
|
|
|
* ...
|
|
|
|
*/
|
|
|
|
|
|
|
|
registerLockFn("basic", "aquire",
|
2011-03-17 07:02:40 +01:00
|
|
|
function(args) {
|
|
|
|
var locks = args['locks'];
|
|
|
|
var name = args['name'];
|
|
|
|
var lockTry;
|
|
|
|
|
|
|
|
if(locks[name] == null) {
|
|
|
|
locks[name] = new Object();
|
|
|
|
}
|
|
|
|
lockTry = locks[name];
|
|
|
|
|
|
|
|
genLockTry(lockTry);
|
|
|
|
|
|
|
|
lockTrys[args['family']] = lockTry;
|
|
|
|
setTestStatus("Acquiring lock for test '" + name + "' " + lockTry.okay + "/" + numberOfNodes + "...", "yellow");
|
|
|
|
|
|
|
|
var m = getLockMsg();
|
|
|
|
m["name"] = name;
|
|
|
|
m["type"] = "basic";
|
|
|
|
|
|
|
|
bcastMsg(m);
|
|
|
|
});
|
|
|
|
|
|
|
|
registerLockFn("range", "aquire",
|
|
|
|
function(args) {
|
|
|
|
var name = args['name'];
|
|
|
|
var start = args['start'];
|
|
|
|
var end = args['end'];
|
|
|
|
|
|
|
|
lockTry = getRangeLock(args['locks'], name, start, end);
|
|
|
|
if (!lockTry) {
|
|
|
|
error("Cannot get range lock in getLock(" + name +", "+ start + ", " + end + ")");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
genLockTry(lockTry);
|
|
|
|
|
|
|
|
lockTrys[args['family']] = lockTry;
|
|
|
|
setWorkStatus("Acquiring lock for work '" + name + "' (" + lockTry.start + " to " + lockTry.end + ")" + lockTry.okay + "/" + numberOfNodes + "...", "yellow");
|
|
|
|
|
|
|
|
var m = getLockMsg();
|
|
|
|
m["name"] = name;
|
|
|
|
m["type"] = "range";
|
|
|
|
|
|
|
|
|
|
|
|
m["start"] = start;
|
|
|
|
m["end"] = end;
|
|
|
|
|
|
|
|
bcastMsg(m);
|
|
|
|
});
|
|
|
|
|
2011-01-14 20:49:41 +01:00
|
|
|
function sendReqs(addr) {
|
|
|
|
for(ltype in lockTrys) {
|
|
|
|
for (i in lockTrys[ltype]) {
|
|
|
|
var lock = lockTrys[ltype][i];
|
|
|
|
if (lock == null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
var m = copyobj(lock);
|
|
|
|
m["query"] = "getLock";
|
|
|
|
m["type"] = ltype;
|
|
|
|
sendMsg(m, addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function sendLocks(addr) {
|
|
|
|
for (ltype in locks) {
|
|
|
|
for (var i in locks[ltype]) {
|
|
|
|
log ("testLog[" + i + "]");
|
|
|
|
var l = testLocks[ltype][i];
|
|
|
|
var m = copyobj(l);
|
|
|
|
|
|
|
|
m["query"] = "addLock";
|
|
|
|
m["type"] = ltype;
|
|
|
|
|
|
|
|
sendMsg(m, addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleAddLock(resp) {
|
|
|
|
if(resp['locked'] == null)
|
|
|
|
resp['locked'] = false;
|
|
|
|
// dont add/overwrite if exists?
|
|
|
|
var lock = retrieveLock(resp);
|
|
|
|
|
|
|
|
if (resp['type'] == "test" ) {//&& (lock == null || lock.addr == null)) {
|
|
|
|
var locks = getLockType(resp['type']);
|
|
|
|
|
|
|
|
|
|
|
|
locks[resp['name']] = resp
|
|
|
|
if(resp['running'] == true) {
|
|
|
|
runningTests.push(resp['name']);
|
|
|
|
}
|
|
|
|
} else if(resp['type'] == "range" && lock.addr == null) {
|
|
|
|
log("Add range lock: " + resp['name'] + " (" + resp['start'] + " to " + resp['end'] + ") : ");
|
2011-03-01 08:40:37 +01:00
|
|
|
var lock = getRangeLock(LOCKS, resp['name'], resp['start'], resp['end']);
|
2011-01-14 20:49:41 +01:00
|
|
|
|
|
|
|
lock.addr = resp['addr'];
|
|
|
|
lock.locked = resp['locked'];
|
|
|
|
lock.done = resp['done'];
|
|
|
|
lock.results = resp['results'];
|
|
|
|
lock.name = resp['name'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-01 08:40:37 +01:00
|
|
|
addMessageHandler("addLock", handlerAddLock());
|
|
|
|
|
2011-01-25 08:27:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function removeNodeLocks(addr) {
|
|
|
|
removeNodeRangeLocks(resp['addr']);
|
|
|
|
}
|
|
|
|
|
|
|
|
addMsgHandler("deadNode",
|
|
|
|
function (resp) {
|
2011-03-01 08:40:37 +01:00
|
|
|
BASIC
|
2011-01-26 08:49:52 +01:00
|
|
|
|
2011-01-25 08:27:20 +01:00
|
|
|
removeNodeLocks(resp['addr']);
|
2011-01-26 08:49:52 +01:00
|
|
|
});
|