// wait for a slot to be available, then take it. If there are slots, the promise resolves immediately, if not, it is added to the release queue and will resolve when there is one available for it.
// wait for a slot to be available, then take it. If there are slots, the promise resolves immediately, if not, it is added to the release queue and will resolve when there is one available for it.
acquire:()=>{
acquire:()=>{
new Promise((resolve,reject)=>{// next.waiters.push(error => error ? reject(error) : resolve()))
return new Promise((resolve,reject)=>{// next.waiters.push(error => error ? reject(error) : resolve()))
// release a raw lock on the semaphore. if there are pending `acquire()` promises, the length is not decremented, but the next queued up acquire is resolved insetad.
// release a raw lock on the semaphore. if there are pending `acquire()` promises, the length is not decremented, but the next queued up acquire is resolved insetad.
release:()=>{
release:()=>{
if(next.waiters.length>0){// There are pending waiters
if(next.waiters.length>0)// There are pending waiters
//TODO: ,dispose: (error = new SemaphoreDisposed()) => { } // reject all `waiters`, and cause all new `acquire()`s to immediately reject.
//TODO: ,dispose: (error = new SemaphoreDisposed()) => { } // reject all `waiters`, and cause all new `acquire()`s to immediately reject.
};
};
@ -77,16 +70,13 @@ function Semaphore(cap)
this.using=async(func)=>{
this.using=async(func)=>{
//if(!func || (typeof obj !== "function" && !isPromise(func))) throw `Parameter '{func}' is not a function or Promise.`;
//if(!func || (typeof obj !== "function" && !isPromise(func))) throw `Parameter '{func}' is not a function or Promise.`;
console.log("waiting lock...");
awaitself.acquire_raw();
awaitnext.acquire();//self.acquire_raw();
console.log("running thunk...");
try{
try{
constrv=func();
constrv=func();
if(isPromise(rv))returnawaitrv;
if(isPromise(rv))returnawaitrv;
elsereturnrv;
elsereturnrv;
}finally{
}finally{
console.log("releasing lock...");
self.release_raw();
next.release();//self.release_raw();
}
}
};
};
}
}
@ -96,9 +86,9 @@ Semaphore.Mutex = () => new Semaphore(1);
constsem_example=async()=>{
constsem_example=async()=>{
varsemaphore=Semaphore.Mutex();//XXX: WHY doesn't this work? acquire just reutrns immediately, even when `resolve` is proven to NOT be called in the promise body???