@@ -7,6 +7,7 @@ import Foundation
77import OpenTelemetryApi
88
99public class TracerProviderSdk : TracerProvider {
10+ private var tracerLock = pthread_rwlock_t ( )
1011 private var tracerProvider = [ InstrumentationLibraryInfo: TracerSdk] ( )
1112 internal var sharedState : TracerSharedState
1213 internal static let emptyName = " unknown "
@@ -19,6 +20,7 @@ public class TracerProviderSdk: TracerProvider {
1920 sampler: Sampler = Samplers . parentBased ( root: Samplers . alwaysOn) ,
2021 spanProcessors: [ SpanProcessor ] = [ ] )
2122 {
23+ pthread_rwlock_init ( & tracerLock, nil )
2224 sharedState = TracerSharedState ( clock: clock,
2325 idGenerator: idGenerator,
2426 resource: resource,
@@ -27,6 +29,10 @@ public class TracerProviderSdk: TracerProvider {
2729 spanProcessors: spanProcessors)
2830 }
2931
32+ deinit {
33+ pthread_rwlock_destroy ( & tracerLock)
34+ }
35+
3036 public func get( instrumentationName: String , instrumentationVersion: String ? = nil ) -> Tracer {
3137 if sharedState. hasBeenShutdown {
3238 return DefaultTracer . instance
@@ -39,20 +45,24 @@ public class TracerProviderSdk: TracerProvider {
3945 instrumentationName = TracerProviderSdk . emptyName
4046 }
4147 let instrumentationLibraryInfo = InstrumentationLibraryInfo ( name: instrumentationName, version: instrumentationVersion ?? " " )
42- if let tracer = tracerProvider [ instrumentationLibraryInfo] {
43- return tracer
44- } else {
45- // Re-check if the value was added since the previous check, this can happen if multiple
46- // threads try to access the same named tracer during the same time. This way we ensure that
47- // we create only one TracerSdk per name.
48- if let tracer = tracerProvider [ instrumentationLibraryInfo] {
49- // A different thread already added the named Tracer, just reuse.
50- return tracer
48+
49+ if pthread_rwlock_rdlock ( & tracerLock) == 0 {
50+ let existingTracer = tracerProvider [ instrumentationLibraryInfo]
51+ pthread_rwlock_unlock ( & tracerLock)
52+
53+ if existingTracer != nil {
54+ return existingTracer!
5155 }
52- let tracer = TracerSdk ( sharedState: sharedState, instrumentationLibraryInfo: instrumentationLibraryInfo)
56+ }
57+
58+ let tracer = TracerSdk ( sharedState: sharedState, instrumentationLibraryInfo: instrumentationLibraryInfo)
59+
60+ if pthread_rwlock_wrlock ( & tracerLock) == 0 {
5361 tracerProvider [ instrumentationLibraryInfo] = tracer
54- return tracer
62+ pthread_rwlock_unlock ( & tracerLock )
5563 }
64+
65+ return tracer
5666 }
5767
5868 /// Returns the active Clock.
0 commit comments