https://kotlinlang.org logo
#announcements
Title
# announcements
a

Animesh Sahu

08/06/2019, 4:29 AM
Hello people! I am having some troubles creating a thread pool. First of all, reference to projects for which i'm having problem: 1. https://github.com/Animeshz/threadpool (isn't completed yet, i.e. problem is in here) 2. https://github.com/Animeshz/promise (dependency, don't think so there's problem here but maybe co-related) the problem is that the code in the done block isn't executing always (like it executes sometime whereas sometime isn't). https://github.com/Animeshz/threadpool/blob/master/src/test/kotlin/com/animeshz/threadpool/PoolTest.kt#L14 Summary what is going on: 1. While when in creating the pool itself i registered a shutdown hook which prevent the jvm to exit before all tasks have been executed, https://github.com/Animeshz/threadpool/blob/master/src/main/kotlin/com/animeshz/threadpool/Pool.kt#L41 2. And shutdown hook calls join function in the pool which blocks the jvm calling .join() on all the worker threads. And also starts a periodic timer which checks for the worker threads being completed by checking currentlyBusy property on the worker(that i'll explain in point 3) and kills which are not busy. https://github.com/Animeshz/threadpool/blob/master/src/main/kotlin/com/animeshz/threadpool/Pool.kt#L53 3. Worker threads transition their currentlyBusy state by if check when queue(stack) is empty, and "that should only happens if the promise is done executing all the handlers"(but done is not getting executed sometime) , and loops back to stack.dequeue(), and that blocks the thread by an ReentrantLock and since periodic timer in last point i mentioned, interrupts the thread when currentlyBusy property gets false. https://github.com/Animeshz/threadpool/blob/master/src/main/kotlin/com/animeshz/threadpool/Worker.kt#L53 I'm really unable to catch why is that done() block is not executing
k

kralli

08/06/2019, 7:05 AM
Your code is inherently thread-unsafe, to a dangerous level. Anyway, your Implementation of
Promise
is causing the error. More specifically the following part:
Copy code
val r = result
when {
    r !== null -> return r.done(onFulfilled)
    else -> handlers.add { promise: PromiseInterface -> promise.done(onFulfilled) }
}
What happens inside your code is, that the promise is done even before
.done { }
has been called. But because you return
null
as a result of the task, the implementation of
done
is assuming that the promise isn’t done yet and registers the handler. You need to maintain the state of the promise separately and thread-safe.
Also
join
is never called, because there are still non-daemon threads running like the timer in
init
of
Pool
and the
Worker
itself.
Both
currentlyBusy
and
lastEmptyStack
in
Worker
are not thread-safe. Also the logic in
run
does not account for a potential change in size of the queue between
isEmpty()
and
dequeue()
. This could cause the thread to be marked as busy even though it’s waiting for a task.