|
@@ -52,6 +52,22 @@ referencedClasses: []
|
|
|
}),
|
|
|
smalltalk.BlockClosure);
|
|
|
|
|
|
+smalltalk.addMethod(
|
|
|
+"_fork",
|
|
|
+smalltalk.method({
|
|
|
+selector: "fork",
|
|
|
+category: 'timeout/interval',
|
|
|
+fn: function (){
|
|
|
+var self=this;
|
|
|
+smalltalk.send(smalltalk.send((smalltalk.ForkPool || ForkPool),"_default",[]),"_fork_",[self]);
|
|
|
+return self},
|
|
|
+args: [],
|
|
|
+source: "fork\x0a\x09ForkPool default fork: self",
|
|
|
+messageSends: ["fork:", "default"],
|
|
|
+referencedClasses: ["ForkPool"]
|
|
|
+}),
|
|
|
+smalltalk.BlockClosure);
|
|
|
+
|
|
|
smalltalk.addMethod(
|
|
|
"_new",
|
|
|
smalltalk.method({
|
|
@@ -622,6 +638,141 @@ smalltalk.CompiledMethod);
|
|
|
|
|
|
|
|
|
|
|
|
+smalltalk.addClass('ForkPool', smalltalk.Object, ['poolSize', 'maxPoolSize', 'queue', 'worker'], 'Kernel-Methods');
|
|
|
+smalltalk.addMethod(
|
|
|
+"_addWorker",
|
|
|
+smalltalk.method({
|
|
|
+selector: "addWorker",
|
|
|
+category: 'action',
|
|
|
+fn: function (){
|
|
|
+var self=this;
|
|
|
+smalltalk.send(self["@worker"],"_valueWithTimeout_",[(0)]);
|
|
|
+self["@poolSize"]=smalltalk.send(self["@poolSize"],"__plus",[(1)]);
|
|
|
+return self},
|
|
|
+args: [],
|
|
|
+source: "addWorker\x0a\x09worker valueWithTimeout: 0.\x0a poolSize := poolSize + 1",
|
|
|
+messageSends: ["valueWithTimeout:", "+"],
|
|
|
+referencedClasses: []
|
|
|
+}),
|
|
|
+smalltalk.ForkPool);
|
|
|
+
|
|
|
+smalltalk.addMethod(
|
|
|
+"_fork_",
|
|
|
+smalltalk.method({
|
|
|
+selector: "fork:",
|
|
|
+category: 'action',
|
|
|
+fn: function (aBlock){
|
|
|
+var self=this;
|
|
|
+var $1;
|
|
|
+$1=smalltalk.send(self["@poolSize"],"__lt",[self["@maxPoolSize"]]);
|
|
|
+if(smalltalk.assert($1)){
|
|
|
+smalltalk.send(self,"_addWorker",[]);
|
|
|
+};
|
|
|
+smalltalk.send(self["@queue"],"_back_",[aBlock]);
|
|
|
+return self},
|
|
|
+args: ["aBlock"],
|
|
|
+source: "fork: aBlock\x0a\x09poolSize < maxPoolSize ifTrue: [ self addWorker ].\x0a\x09queue back: aBlock",
|
|
|
+messageSends: ["ifTrue:", "addWorker", "<", "back:"],
|
|
|
+referencedClasses: []
|
|
|
+}),
|
|
|
+smalltalk.ForkPool);
|
|
|
+
|
|
|
+smalltalk.addMethod(
|
|
|
+"_initialize",
|
|
|
+smalltalk.method({
|
|
|
+selector: "initialize",
|
|
|
+category: 'initialization',
|
|
|
+fn: function (){
|
|
|
+var self=this;
|
|
|
+var $1;
|
|
|
+var sentinel;
|
|
|
+self["@poolSize"]=(0);
|
|
|
+self["@maxPoolSize"]=smalltalk.send(smalltalk.send(self,"_class",[]),"_defaultMaxPoolSize",[]);
|
|
|
+self["@queue"]=smalltalk.send((smalltalk.Queue || Queue),"_new",[]);
|
|
|
+sentinel=smalltalk.send((smalltalk.Object || Object),"_new",[]);
|
|
|
+self["@worker"]=(function(){
|
|
|
+var block;
|
|
|
+self["@poolSize"]=smalltalk.send(self["@poolSize"],"__minus",[(1)]);
|
|
|
+self["@poolSize"];
|
|
|
+block=smalltalk.send(self["@queue"],"_frontIfAbsent_",[(function(){
|
|
|
+return sentinel;
|
|
|
+})]);
|
|
|
+block;
|
|
|
+$1=smalltalk.send(block,"__eq_eq",[sentinel]);
|
|
|
+if(! smalltalk.assert($1)){
|
|
|
+return smalltalk.send((function(){
|
|
|
+return smalltalk.send(block,"_value",[]);
|
|
|
+}),"_ensure_",[(function(){
|
|
|
+return smalltalk.send(self,"_addWorker",[]);
|
|
|
+})]);
|
|
|
+};
|
|
|
+});
|
|
|
+return self},
|
|
|
+args: [],
|
|
|
+source: "initialize\x0a\x09| sentinel |\x0a\x09poolSize := 0.\x0a maxPoolSize := self class defaultMaxPoolSize.\x0a queue := Queue new.\x0a sentinel := Object new.\x0a worker := [\x0a\x09\x09| block |\x0a poolSize := poolSize - 1.\x0a\x09\x09block := queue frontIfAbsent: [ sentinel ].\x0a block == sentinel ifFalse: [\x0a \x09[ block value ] ensure: [ self addWorker ]]].",
|
|
|
+messageSends: ["defaultMaxPoolSize", "class", "new", "-", "frontIfAbsent:", "ifFalse:", "ensure:", "addWorker", "value", "=="],
|
|
|
+referencedClasses: ["Queue", "Object"]
|
|
|
+}),
|
|
|
+smalltalk.ForkPool);
|
|
|
+
|
|
|
+
|
|
|
+smalltalk.ForkPool.klass.iVarNames = ['default'];
|
|
|
+smalltalk.addMethod(
|
|
|
+"_default",
|
|
|
+smalltalk.method({
|
|
|
+selector: "default",
|
|
|
+category: 'accessing',
|
|
|
+fn: function (){
|
|
|
+var self=this;
|
|
|
+var $1;
|
|
|
+if(($receiver = self["@default"]) == nil || $receiver == undefined){
|
|
|
+self["@default"]=smalltalk.send(self,"_new",[]);
|
|
|
+$1=self["@default"];
|
|
|
+} else {
|
|
|
+$1=self["@default"];
|
|
|
+};
|
|
|
+return $1;
|
|
|
+},
|
|
|
+args: [],
|
|
|
+source: "default\x0a\x09^default ifNil: [ default := self new ]",
|
|
|
+messageSends: ["ifNil:", "new"],
|
|
|
+referencedClasses: []
|
|
|
+}),
|
|
|
+smalltalk.ForkPool.klass);
|
|
|
+
|
|
|
+smalltalk.addMethod(
|
|
|
+"_defaultMaxPoolSize",
|
|
|
+smalltalk.method({
|
|
|
+selector: "defaultMaxPoolSize",
|
|
|
+category: 'accessing',
|
|
|
+fn: function (){
|
|
|
+var self=this;
|
|
|
+return (100);
|
|
|
+},
|
|
|
+args: [],
|
|
|
+source: "defaultMaxPoolSize\x0a\x09^100",
|
|
|
+messageSends: [],
|
|
|
+referencedClasses: []
|
|
|
+}),
|
|
|
+smalltalk.ForkPool.klass);
|
|
|
+
|
|
|
+smalltalk.addMethod(
|
|
|
+"_resetDefault",
|
|
|
+smalltalk.method({
|
|
|
+selector: "resetDefault",
|
|
|
+category: 'accessing',
|
|
|
+fn: function (){
|
|
|
+var self=this;
|
|
|
+self["@default"]=nil;
|
|
|
+return self},
|
|
|
+args: [],
|
|
|
+source: "resetDefault\x0a\x09default := nil",
|
|
|
+messageSends: [],
|
|
|
+referencedClasses: []
|
|
|
+}),
|
|
|
+smalltalk.ForkPool.klass);
|
|
|
+
|
|
|
+
|
|
|
smalltalk.addClass('Message', smalltalk.Object, ['selector', 'arguments'], 'Kernel-Methods');
|
|
|
smalltalk.Message.comment="Generally, the system does not use instances of Message for efficiency reasons.\x0aHowever, when a message is not understood by its receiver, the interpreter will make up an instance of it in order to capture the information involved in an actual message transmission. \x0aThis instance is sent it as an argument with the message `doesNotUnderstand:` to the receiver.\x0a\x0aSee boot.js, `messageNotUnderstood` and its counterpart `Object>>doesNotUnderstand:`"
|
|
|
smalltalk.addMethod(
|