Created
May 14, 2015 10:26
-
-
Save ysbaddaden/a24270c1ac6f23655f34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/thread/lib_pthread.cr b/src/thread/lib_pthread.cr | |
index 5094260..96f2530 100644 | |
--- a/src/thread/lib_pthread.cr | |
+++ b/src/thread/lib_pthread.cr | |
@@ -17,6 +17,7 @@ lib LibPThread | |
fun create = pthread_create(thread : Thread*, attr : Void*, start : Void* ->, arg : Void*) : Int32 | |
fun exit = pthread_exit(value : Void*) | |
+ fun yield = pthread_yield() : Int32 | |
fun join = pthread_join(thread : Thread, value : Void**) : Int32 | |
fun mutex_init = pthread_mutex_init(mutex : Mutex*, mutex_attr : MutexAttr) : Int32 | |
diff --git a/src/thread/thread.cr b/src/thread/thread.cr | |
index b10d57d..e024ece 100644 | |
--- a/src/thread/thread.cr | |
+++ b/src/thread/thread.cr | |
@@ -1,6 +1,21 @@ | |
require "./*" | |
class Thread(T, R) | |
+ @[ThreadLocal] | |
+ $__crystal_current_thread = nil | |
+ | |
+ def self.current | |
+ if thread = $__crystal_current_thread | |
+ thread | |
+ else | |
+ raise "Could not get current thread" | |
+ end | |
+ end | |
+ | |
+ def self.pass | |
+ LibPThread.yield | |
+ end | |
+ | |
def self.new(&func : -> R) | |
Thread(Nil, R).new(nil) { func.call } | |
end | |
@@ -8,19 +23,17 @@ class Thread(T, R) | |
def initialize(arg : T, &func : T -> R) | |
@func = func | |
@arg = arg | |
- ret = LibPThread.create(out @th, nil, ->(data) { | |
- (data as Thread(T, R)).start | |
+ | |
+ success = LibPThread.create(out @th, nil, ->(data) { | |
+ ($__crystal_current_thread = data as Thread(T, R)).start | |
}, self as Void*) | |
- if ret != 0 | |
- raise Errno.new("pthread_create") | |
- end | |
+ raise Errno.new("pthread_create") if success != 0 | |
end | |
def join | |
- if LibPThread.join(@th, out _ret) != 0 | |
- raise Errno.new("pthread_join") | |
- end | |
+ success = LibPThread.join(@th, out _ret) | |
+ raise Errno.new("pthread_join") if success != 0 | |
if exception = @exception | |
raise exception | |
@@ -44,6 +57,8 @@ class Thread(T, R) | |
@ret = @func.call(@arg) | |
rescue ex | |
@exception = ex | |
+ ensure | |
+ $__crystal_current_thread = nil | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment