GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — JavaScriptKit/Sources/JavaScriptKit/ThreadLocal.swift at main · wfltaylor/JavaScriptKit Expand file tree/ Copy pathThreadLocal.swiftMore file actions 131 lines (119 loc) · 3.9 KB / Copy pathThreadLocal.swiftFile metadata and controls131 lines (119 loc) · 3.9 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 #if arch(wasm32) #if canImport(wasi_pthread) import wasi_pthread #endif #elseif canImport(Darwin) import Darwin #elseif canImport(Android) import Android #elseif canImport(Glibc) import Glibc #else #error("Unsupported platform") #endif /// A property wrapper that provides thread-local storage for a value. /// /// The value is stored in a thread-local variable, which is a separate copy for each thread. @propertyWrapper final class ThreadLocal<Value>: Sendable { #if _runtime(_multithreaded) /// The wrapped value stored in the thread-local storage. /// The initial value is `nil` for each thread. var wrappedValue: Value? { get { guard let pointer = pthread_getspecific(key) else { return nil } return fromPointer(pointer) } set { if let oldPointer = pthread_getspecific(key) { release(oldPointer) } if let newValue = newValue { let pointer = toPointer(newValue) pthread_setspecific(key, pointer) } } } private let key: pthread_key_t private let toPointer: @Sendable (Value) -> UnsafeMutableRawPointer private let fromPointer: @Sendable (UnsafeMutableRawPointer) -> Value private let release: @Sendable (UnsafeMutableRawPointer) -> Void /// A constructor that requires `Value` to be `AnyObject` to be /// able to store the value directly in the thread-local storage. init() where Value: AnyObject { var key = pthread_key_t() pthread_key_create(&key, nil) self.key = key self.toPointer = { Unmanaged.passRetained($0).toOpaque() } self.fromPointer = { Unmanaged<Value>.fromOpaque($0).takeUnretainedValue() } self.release = { Unmanaged<Value>.fromOpaque($0).release() } } private class Box { let value: Value init(_ value: Value) { self.value = value } } /// A constructor that doesn't require `Value` to be `AnyObject` but /// boxing the value in heap-allocated memory. init(boxing _: Void) { var key = pthread_key_t() pthread_key_create(&key, nil) self.key = key self.toPointer = { let box = Box($0) let pointer = Unmanaged.passRetained(box).toOpaque() return pointer } self.fromPointer = { let box = Unmanaged<Box>.fromOpaque($0).takeUnretainedValue() return box.value } self.release = { Unmanaged<Box>.fromOpaque($0).release() } } #else // Fallback implementation for platforms that don't support pthread private class SendableBox: @unchecked Sendable { var value: Value? = nil } private let _storage = SendableBox() var wrappedValue: Value? { get { _storage.value } set { _storage.value = newValue } } init() where Value: AnyObject { wrappedValue = nil } init(boxing _: Void) { wrappedValue = nil } #endif deinit { preconditionFailure("ThreadLocal can only be used as an immortal storage, cannot be deallocated") } } /// A property wrapper that lazily initializes a thread-local value /// for each thread that accesses the value. @propertyWrapper final class LazyThreadLocal<Value>: Sendable { private let storage: ThreadLocal<Value> var wrappedValue: Value { if let value = storage.wrappedValue { return value } let value = initialValue() storage.wrappedValue = value return value } private let initialValue: @Sendable () -> Value init(initialize: @Sendable @escaping () -> Value) where Value: AnyObject { self.storage = ThreadLocal() self.initialValue = initialize } init(initialize: @Sendable @escaping () -> Value) { self.storage = ThreadLocal(boxing: ()) self.initialValue = initialize } } |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |