158 lines
3.9 KiB
JavaScript
158 lines
3.9 KiB
JavaScript
|
if(!dojo._hasResource["dojox.timing.ThreadPool"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||
|
dojo._hasResource["dojox.timing.ThreadPool"] = true;
|
||
|
dojo.provide("dojox.timing.ThreadPool");
|
||
|
dojo.require("dojox.timing");
|
||
|
|
||
|
dojo.experimental("dojox.timing.ThreadPool");
|
||
|
|
||
|
// dojox.timing.Timer is included as part of _base
|
||
|
/********************************************************************
|
||
|
This is a port of the original System.Threading.ThreadPool from
|
||
|
the f(m) class library.
|
||
|
|
||
|
Donated to the Dojo toolkit by the author :)
|
||
|
*********************************************************************/
|
||
|
(function(){
|
||
|
var t=dojox.timing;
|
||
|
t.threadStates={
|
||
|
UNSTARTED:"unstarted",
|
||
|
STOPPED:"stopped",
|
||
|
PENDING:"pending",
|
||
|
RUNNING:"running",
|
||
|
SUSPENDED:"suspended",
|
||
|
WAITING:"waiting",
|
||
|
COMPLETE:"complete",
|
||
|
ERROR:"error"
|
||
|
};
|
||
|
|
||
|
// Before rar says a word, we actually *use* these numbers for a purpose :)
|
||
|
t.threadPriorities={
|
||
|
LOWEST:1,
|
||
|
BELOWNORMAL:2,
|
||
|
NORMAL:3,
|
||
|
ABOVENORMAL:4,
|
||
|
HIGHEST:5
|
||
|
};
|
||
|
|
||
|
t.Thread=function(/* Function */fn, /* dojox.timing.threadPriorities? */priority){
|
||
|
var self=this;
|
||
|
this.state=t.threadStates.UNSTARTED;
|
||
|
this.priority=priority||t.threadPriorities.NORMAL;
|
||
|
this.lastError=null;
|
||
|
this.func=fn; // for lookup purposes.
|
||
|
this.invoke=function(){
|
||
|
self.state=t.threadStates.RUNNING;
|
||
|
try{
|
||
|
fn(this);
|
||
|
self.state=t.threadStates.COMPLETE;
|
||
|
}catch(e){
|
||
|
self.lastError=e;
|
||
|
self.state=t.threadStates.ERROR;
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// TODO: allow for changing of maxThreads and tick interval
|
||
|
t.ThreadPool=new (function(/* Number */mxthrs, /* Number */intvl){
|
||
|
var self=this;
|
||
|
var maxThreads=mxthrs;
|
||
|
var availableThreads=maxThreads;
|
||
|
var interval=intvl;
|
||
|
var fireInterval=Math.floor((interval/2)/maxThreads);
|
||
|
var queue=[];
|
||
|
var timers=new Array(maxThreads+1);
|
||
|
var timer=new dojox.timing.Timer();
|
||
|
var invoke=function(){
|
||
|
var tracker=timers[0]={};
|
||
|
for(var i=0; i<timers.length; i++){
|
||
|
window.clearTimeout(timers[i]);
|
||
|
var thread=queue.shift();
|
||
|
if(typeof(thread)=="undefined"){ break; }
|
||
|
tracker["thread-"+i]=thread;
|
||
|
timers[i]=window.setTimeout(thread.invoke,(fireInterval*i));
|
||
|
}
|
||
|
availableThreads=maxThreads-(i-1);
|
||
|
};
|
||
|
|
||
|
// public methods
|
||
|
this.getMaxThreads=function(){ return maxThreads; };
|
||
|
this.getAvailableThreads=function(){ return availableThreads; };
|
||
|
this.getTickInterval=function(){ return interval; };
|
||
|
this.queueUserWorkItem=function(/* Function || dojox.timing.Thread */fn){
|
||
|
var item=fn;
|
||
|
if(item instanceof Function){
|
||
|
item=new t.Thread(item);
|
||
|
}
|
||
|
var idx=queue.length;
|
||
|
for(var i=0; i<queue.length; i++){
|
||
|
if(queue[i].priority<item.priority){
|
||
|
idx=i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(idx<queue.length){
|
||
|
queue.splice(idx, 0, item);
|
||
|
} else {
|
||
|
queue.push(item);
|
||
|
}
|
||
|
return true;
|
||
|
};
|
||
|
this.removeQueuedUserWorkItem=function(/* Function || dojox.timing.Thread */item){
|
||
|
if(item instanceof Function){
|
||
|
var idx=-1;
|
||
|
for(var i=0; i<queue.length; i++){
|
||
|
if(queue[i].func==item){
|
||
|
idx=i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(idx>-1){
|
||
|
queue.splice(idx,1);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
var idx=-1;
|
||
|
for(var i=0; i<queue.length; i++){
|
||
|
if(queue[i]==item){
|
||
|
idx=i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(idx>-1){
|
||
|
queue.splice(idx,1);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
this.start=function(){ timer.start(); };
|
||
|
this.stop=function(){ timer.stop(); };
|
||
|
this.abort=function(){
|
||
|
this.stop();
|
||
|
for(var i=1; i<timers.length; i++){
|
||
|
if(timers[i]){
|
||
|
window.clearTimeout(timers[i]);
|
||
|
}
|
||
|
}
|
||
|
for(var thread in timers[0]){
|
||
|
this.queueUserWorkItem(thread);
|
||
|
}
|
||
|
timers[0]={};
|
||
|
};
|
||
|
this.reset=function(){
|
||
|
this.abort();
|
||
|
queue=[];
|
||
|
};
|
||
|
this.sleep=function(/* Number */nSleep){
|
||
|
timer.stop();
|
||
|
window.setTimeout(timer.start, nSleep);
|
||
|
};
|
||
|
|
||
|
// dedicate the timer to us.
|
||
|
timer.onTick=self.invoke;
|
||
|
})(16, 5000);
|
||
|
})();
|
||
|
|
||
|
}
|