pthreads: `ThreadPool` accept any `Task`
authorAlexis Laferrière <alexis.laf@xymus.net>
Fri, 3 Feb 2017 19:35:56 +0000 (14:35 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Fri, 3 Feb 2017 22:45:02 +0000 (17:45 -0500)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/pthreads/threadpool.nit

index 02042ba..cd14ab1 100644 (file)
@@ -20,7 +20,7 @@ import concurrent_collections
 
 # A simple ThreadPool implemented with an array
 class ThreadPool
-       private var queue = new ConcurrentList[JoinTask].wrap(new List[JoinTask])
+       private var queue = new ConcurrentList[Task]
        private var mutex = new Mutex
        private var cond = new NativePthreadCond
 
@@ -47,13 +47,13 @@ end
 private class PoolThread
        super Thread
 
-       var queue: ConcurrentList[JoinTask]
+       var queue: ConcurrentList[Task]
        var mutex: Mutex
        var cond : NativePthreadCond
 
        redef fun main do
                loop
-                       var t: nullable JoinTask = null
+                       var t = null
                        mutex.lock
                        if queue.is_empty then cond.wait(mutex.native.as(not null))
                        if not queue.is_empty then
@@ -62,21 +62,22 @@ private class PoolThread
                        mutex.unlock
                        if t != null then
                                t.main
-                               t.mutex.lock
-                               t.is_done = true
-                               var tcond = t.cond
-                               if tcond != null then tcond.signal
-                               t.mutex.unlock
+                               t.after_main
                        end
                end
        end
 end
 
+redef class Task
+       # Additional work executed after `main` from a `ThreadPool`
+       private fun after_main do end
+end
+
 # A Task which is joinable, meaning it can return a value and if the value is not set yet, it blocks the execution
 class JoinTask
        super Task
 
-       # Is `self` done ?
+       # Is `self` done?
        var is_done = false
 
        private var mutex = new Mutex
@@ -92,4 +93,15 @@ class JoinTask
                end
                mutex.unlock
        end
+
+       redef fun after_main do
+               # TODO move this at the end of main so all `JoinTask` can be joined
+               # no matter what calls `main`.
+
+               mutex.lock
+               is_done = true
+               var tcond = cond
+               if tcond != null then tcond.signal
+               mutex.unlock
+       end
 end