Skip to content

Instantly share code, notes, and snippets.

@ysbaddaden
Created May 14, 2015 10:26
Show Gist options
  • Save ysbaddaden/a24270c1ac6f23655f34 to your computer and use it in GitHub Desktop.
Save ysbaddaden/a24270c1ac6f23655f34 to your computer and use it in GitHub Desktop.
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