v / vlib / sync / tls_default.c.v
62 lines · 56 sloc · 1.78 KB · a87a4d73b9ab25cfff0822f4e94cf2a2d9e64323
Raw
1module sync
2
3// Pthread TLS API functions (via C interface)
4fn C.pthread_key_create(key voidptr, voidptr) i32
5fn C.pthread_key_delete(key u64) i32
6fn C.pthread_setspecific(key u64, const_ptr voidptr) i32
7fn C.pthread_getspecific(key u64) voidptr
8
9// new_tls creates new TLS storage initialized with the given `value`
10pub fn new_tls[T](value T) !ThreadLocalStorage[T] {
11 $if T !in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize, f32, f64, rune, int, voidptr,
12 $pointer] {
13 return error('new_tls: invalid type ${T.name}')
14 }
15 mut key := u64(0)
16 // Validate key allocation
17 if C.pthread_key_create(voidptr(&key), 0) == 0 {
18 // Initialize storage and verify success
19 if C.pthread_setspecific(key, convert_t_to_voidptr(value)!) == 0 {
20 return ThreadLocalStorage[T]{
21 key: key
22 in_use: true
23 }
24 } else {
25 return error('new_tls: Failed to initialize TLS value: ${value}')
26 }
27 }
28
29 // Handle allocation failure
30 return error('new_tls: Failed to allocate TLS index')
31}
32
33// set updates the `value` in TLS storage.
34@[inline]
35pub fn (mut t ThreadLocalStorage[T]) set(value T) ! {
36 if t.in_use {
37 if C.pthread_setspecific(t.key, convert_t_to_voidptr(value)!) != 0 {
38 return error('set: Failed to update TLS value: ${value}')
39 }
40 } else {
41 return error('set: TLS storage is already destroyed')
42 }
43}
44
45// get retrieves the current value from TLS storage.
46@[inline]
47pub fn (mut t ThreadLocalStorage[T]) get() !T {
48 if t.in_use {
49 return convert_voidptr_to_t[T](C.pthread_getspecific(t.key))
50 }
51 return error('get: TLS storage is already destroyed')
52}
53
54// destroy releases TLS resources (must be called manually).
55@[inline]
56pub fn (mut t ThreadLocalStorage[T]) destroy() ! {
57 if C.pthread_key_delete(t.key) == 0 {
58 t.in_use = false
59 } else {
60 return error('destroy: Failed to release TLS resources')
61 }
62}
63