|
1 | 1 | require "c/fibersapi"
|
2 | 2 |
|
3 | 3 | class Thread
|
| 4 | + protected class_getter(destructors : Array({LibC::DWORD, Proc(Void*, Nil)})) do |
| 5 | + Array({LibC::DWORD, Proc(Void*, Nil)}).new |
| 6 | + end |
| 7 | + |
4 | 8 | struct Local(T)
|
5 | 9 | @key : LibC::DWORD
|
6 | 10 |
|
7 | 11 | def initialize
|
8 | 12 | {% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %}
|
9 |
| - @key = LibC.FlsAlloc(nil) |
10 |
| - raise RuntimeError.from_winerror("FlsAlloc: out of indexes") if @key == LibC::TLS_OUT_OF_INDEXES |
| 13 | + @key = LibC.TlsAlloc() |
| 14 | + raise RuntimeError.from_winerror("TlsAlloc: out of indexes") if @key == LibC::TLS_OUT_OF_INDEXES |
11 | 15 | end
|
12 | 16 |
|
13 | 17 | def initialize(&destructor : Proc(T, Nil))
|
14 | 18 | {% raise "T must be a Reference or Pointer" unless T < Reference || T < Pointer %}
|
15 |
| - @key = LibC.FlsAlloc(destructor.unsafe_as(Proc(Void*, Nil))) |
16 |
| - raise RuntimeError.from_winerror("FlsAlloc: out of indexes") if @key == LibC::TLS_OUT_OF_INDEXES |
| 19 | + @key = LibC.TlsAlloc() |
| 20 | + raise RuntimeError.from_winerror("TlsAlloc: out of indexes") if @key == LibC::TLS_OUT_OF_INDEXES |
| 21 | + Thread.destructors << {@key, destructor.unsafe_as(Proc(Void*, Nil))} |
17 | 22 | end
|
18 | 23 |
|
19 | 24 | def get? : T?
|
20 |
| - pointer = LibC.FlsGetValue(@key) |
| 25 | + pointer = LibC.TlsGetValue(@key) |
21 | 26 | pointer.as(T) if pointer
|
22 | 27 | end
|
23 | 28 |
|
24 | 29 | def set(value : T) : T
|
25 |
| - ret = LibC.FlsSetValue(@key, value.as(Void*)) |
26 |
| - raise RuntimeError.from_winerror("FlsSetValue") if ret == 0 |
| 30 | + ret = LibC.TlsSetValue(@key, value.as(Void*)) |
| 31 | + raise RuntimeError.from_winerror("TlsSetValue") if ret == 0 |
27 | 32 | value
|
28 | 33 | end
|
29 | 34 | end
|
| 35 | + |
| 36 | + private def run_destructors |
| 37 | + @@destructors.try(&.each do |(key, destructor)| |
| 38 | + if pointer = LibC.TlsGetValue(key) |
| 39 | + destructor.call(pointer) # rescue nil |
| 40 | + end |
| 41 | + end) |
| 42 | + end |
30 | 43 | end
|
0 commit comments