@@ -24,56 +24,78 @@ import ServiceContextModule
24
24
/// ``instrument``: Returns whatever you passed to ``bootstrap(_:)`` as an ``Instrument``.
25
25
@available ( macOS 10 . 15 , iOS 13 , tvOS 13 , watchOS 6 , * ) // for TaskLocal ServiceContext
26
26
public enum InstrumentationSystem {
27
- private static let lock = ReadWriteLock ( )
28
- private static var _instrument : Instrument = NoOpInstrument ( )
29
- private static var isInitialized = false
27
+ /// Marked as @unchecked Sendable due to the synchronization being
28
+ /// performed manually using locks.
29
+ private final class Storage : @unchecked Sendable {
30
+ private let lock = ReadWriteLock ( )
31
+ private var _instrument : Instrument = NoOpInstrument ( )
32
+ private var _isInitialized = false
33
+
34
+ func bootstrap( _ instrument: Instrument ) {
35
+ self . lock. withWriterLock {
36
+ precondition (
37
+ !self . _isInitialized, """
38
+ InstrumentationSystem can only be initialized once per process. Consider using MultiplexInstrument if
39
+ you need to use multiple instruments.
40
+ """
41
+ )
42
+ self . _instrument = instrument
43
+ self . _isInitialized = true
44
+ }
45
+ }
46
+
47
+ func bootstrapInternal( _ instrument: Instrument ? ) {
48
+ self . lock. withWriterLock {
49
+ self . _instrument = instrument ?? NoOpInstrument ( )
50
+ }
51
+ }
52
+
53
+ var instrument : Instrument {
54
+ self . lock. withReaderLock { self . _instrument }
55
+ }
56
+
57
+ func _findInstrument( where predicate: ( Instrument ) -> Bool ) -> Instrument ? {
58
+ self . lock. withReaderLock {
59
+ if let multiplex = self . _instrument as? MultiplexInstrument {
60
+ return multiplex. firstInstrument ( where: predicate)
61
+ } else if predicate ( self . _instrument) {
62
+ return self . _instrument
63
+ } else {
64
+ return nil
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ private static let shared = Storage ( )
30
71
31
72
/// Globally select the desired ``Instrument`` implementation.
32
73
///
33
74
/// - Parameter instrument: The ``Instrument`` you want to share globally within your system.
34
75
/// - Warning: Do not call this method more than once. This will lead to a crash.
35
76
public static func bootstrap( _ instrument: Instrument ) {
36
- self . lock. withWriterLock {
37
- precondition (
38
- !self . isInitialized, """
39
- InstrumentationSystem can only be initialized once per process. Consider using MultiplexInstrument if
40
- you need to use multiple instruments.
41
- """
42
- )
43
- self . _instrument = instrument
44
- self . isInitialized = true
45
- }
77
+ self . shared. bootstrap ( instrument)
46
78
}
47
79
48
80
/// For testing scenarios one may want to set instruments multiple times, rather than the set-once semantics enforced by ``bootstrap(_:)``.
49
81
///
50
82
/// - Parameter instrument: the instrument to boostrap the system with, if `nil` the ``NoOpInstrument`` is bootstrapped.
51
83
internal static func bootstrapInternal( _ instrument: Instrument ? ) {
52
- self . lock. withWriterLock {
53
- self . _instrument = instrument ?? NoOpInstrument ( )
54
- }
84
+ self . shared. bootstrapInternal ( instrument)
55
85
}
56
86
57
87
/// Returns the globally configured ``Instrument``.
58
88
///
59
89
/// Defaults to a no-op ``Instrument`` if ``bootstrap(_:)`` wasn't called before.
60
90
public static var instrument : Instrument {
61
- self . lock . withReaderLock { self . _instrument }
91
+ shared . instrument
62
92
}
63
93
}
64
94
65
95
@available ( macOS 10 . 15 , iOS 13 , tvOS 13 , watchOS 6 , * ) // for TaskLocal ServiceContext
66
96
extension InstrumentationSystem {
67
97
/// INTERNAL API: Do Not Use
68
98
public static func _findInstrument( where predicate: ( Instrument ) -> Bool ) -> Instrument ? {
69
- self . lock. withReaderLock {
70
- if let multiplex = self . _instrument as? MultiplexInstrument {
71
- return multiplex. firstInstrument ( where: predicate)
72
- } else if predicate ( self . _instrument) {
73
- return self . _instrument
74
- } else {
75
- return nil
76
- }
77
- }
99
+ self . shared. _findInstrument ( where: predicate)
78
100
}
79
101
}
0 commit comments