| 1 | module sync |
| 2 | |
| 3 | // Pthread TLS API functions (via C interface) |
| 4 | fn C.pthread_key_create(key voidptr, voidptr) i32 |
| 5 | fn C.pthread_key_delete(key u64) i32 |
| 6 | fn C.pthread_setspecific(key u64, const_ptr voidptr) i32 |
| 7 | fn C.pthread_getspecific(key u64) voidptr |
| 8 | |
| 9 | // new_tls creates new TLS storage initialized with the given `value` |
| 10 | pub 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] |
| 35 | pub 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] |
| 47 | pub 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] |
| 56 | pub 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 | |