@@ -17,8 +17,13 @@ private let OS_ACTIVITY_CURRENT = unsafeBitCast(dlsym(UnsafeMutableRawPointer(bi
1717class ActivityContextManager: ContextManager {
1818 static let instance = ActivityContextManager ( )
1919#if canImport(_Concurrency)
20+ #if swift(<5.5.2)
2021 @available ( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * )
2122 static let taskLocalContextManager = TaskLocalContextManager . instance
23+ #else
24+ @available ( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , * )
25+ static let taskLocalContextManager = TaskLocalContextManager . instance
26+ #endif
2227#endif
2328
2429 let rlock = NSRecursiveLock ( )
@@ -38,45 +43,80 @@ class ActivityContextManager: ContextManager {
3843 var contextMap = [ os_activity_id_t: [ String: AnyObject] ] ( )
3944
4045 func getCurrentContextValue( forKey key: OpenTelemetryContextKeys ) -> AnyObject ? {
41- #if canImport(_Concurrency)
42- if #available( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * ) {
43- // If running with task local, use first its stored value
44- if let contextValue = ActivityContextManager . taskLocalContextManager. getCurrentContextValue ( forKey: key) {
45- return contextValue
46- }
47- }
48- #endif
4946 var parentIdent : os_activity_id_t = 0
5047 let activityIdent = os_activity_get_identifier ( OS_ACTIVITY_CURRENT, & parentIdent)
5148 var contextValue : AnyObject ?
52- rlock. lock ( )
53- guard let context = contextMap [ activityIdent] ?? contextMap [ parentIdent] else {
49+ if activityIdent != 0 {
50+ rlock. lock ( )
51+ guard let context = contextMap [ activityIdent] ?? contextMap [ parentIdent] else {
52+ rlock. unlock ( )
53+ return nil
54+ }
55+ contextValue = context [ key. rawValue]
5456 rlock. unlock ( )
55- return nil
57+ return contextValue
58+ } else {
59+ // If activityIdent == 0, it means no active Span or we are inside an Task
60+ #if canImport(_Concurrency)
61+ #if swift(<5.5.2)
62+ if #available( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * ) {
63+ if let contextValue = ActivityContextManager . taskLocalContextManager. getCurrentContextValue ( forKey: key) {
64+ return contextValue
65+ }
66+ }
67+ #else
68+ if #available( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , * ) {
69+ if let contextValue = ActivityContextManager . taskLocalContextManager. getCurrentContextValue ( forKey: key) {
70+ return contextValue
71+ }
72+ }
73+ #endif
74+ #endif
5675 }
57- contextValue = context [ key. rawValue]
58- rlock. unlock ( )
59- return contextValue
76+ return nil
6077 }
6178
6279 func setCurrentContextValue( forKey key: OpenTelemetryContextKeys , value: AnyObject ) {
6380 var parentIdent : os_activity_id_t = 0
6481 var activityIdent = os_activity_get_identifier ( OS_ACTIVITY_CURRENT, & parentIdent)
65- rlock. lock ( )
66- if contextMap [ activityIdent] == nil || contextMap [ activityIdent] ? [ key. rawValue] != nil {
82+ if activityIdent != 0 {
83+ // We are inside an activity, it can be an activity created by us for a span context or another independent activty
84+ // We are surely not inside a Task
85+ rlock. lock ( )
86+ if contextMap [ activityIdent] == nil || contextMap [ activityIdent] ? [ key. rawValue] != nil {
87+ var scope : os_activity_scope_state_s
88+ ( activityIdent, scope) = createActivityContext ( )
89+ contextMap [ activityIdent] = [ String: AnyObject] ( )
90+ objectScope. setObject ( ScopeElement ( scope: scope) , forKey: value)
91+ }
92+ contextMap [ activityIdent] ? [ key. rawValue] = value
93+ rlock. unlock ( )
94+ } else {
6795 var scope : os_activity_scope_state_s
6896 ( activityIdent, scope) = createActivityContext ( )
69- contextMap [ activityIdent] = [ String: AnyObject] ( )
70- objectScope. setObject ( ScopeElement ( scope: scope) , forKey: value)
71- }
72- contextMap [ activityIdent] ? [ key. rawValue] = value
97+ if activityIdent == 0 {
98+ // If activityIdent == 0, means we are inside a Task, because we cannot create an activity, set the context inside the task
7399#if canImport(_Concurrency)
74- if #available( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * ) {
75- // If running with task local, set the value after the activity, so activity is not empty
76- ActivityContextManager . taskLocalContextManager. setCurrentContextValue ( forKey: key, value: value)
77- }
100+ #if swift(<5.5.2)
101+ if #available( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * ) {
102+ ActivityContextManager . taskLocalContextManager. setCurrentContextValue ( forKey: key, value: value)
103+ }
104+ #else
105+ if #available( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , * ) {
106+ ActivityContextManager . taskLocalContextManager. setCurrentContextValue ( forKey: key, value: value)
107+ }
108+
109+ #endif
78110#endif
79- rlock. unlock ( )
111+ } else {
112+ // We could create the activity so we store the context in the activity map
113+ rlock. lock ( )
114+ contextMap [ activityIdent] = [ String: AnyObject] ( )
115+ objectScope. setObject ( ScopeElement ( scope: scope) , forKey: value)
116+ contextMap [ activityIdent] ? [ key. rawValue] = value
117+ rlock. unlock ( )
118+ }
119+ }
80120 }
81121
82122 func createActivityContext( ) -> ( os_activity_id_t , os_activity_scope_state_s ) {
@@ -93,15 +133,26 @@ class ActivityContextManager: ContextManager {
93133 var scope = scope. scope
94134 os_activity_scope_leave ( & scope)
95135 objectScope. removeObject ( forKey: value)
96- }
136+ } else {
97137#if canImport(_Concurrency)
98- if #available( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * ) {
138+ #if swift(<5.5.2)
139+ if #available( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , * ) {
140+ // If there is a parent activity, set its content as the task local
141+ ActivityContextManager . taskLocalContextManager. removeContextValue ( forKey: key, value: value)
142+ if let currentContext = self . getCurrentContextValue ( forKey: key) {
143+ ActivityContextManager . taskLocalContextManager. setCurrentContextValue ( forKey: key, value: currentContext)
144+ }
145+ }
146+ #else
99147 // If there is a parent activity, set its content as the task local
100- ActivityContextManager . taskLocalContextManager. removeContextValue ( forKey: key, value: value)
101- if let currentContext = self . getCurrentContextValue ( forKey: key) {
102- ActivityContextManager . taskLocalContextManager. setCurrentContextValue ( forKey: key, value: currentContext)
148+ if #available( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , * ) {
149+ ActivityContextManager . taskLocalContextManager. removeContextValue ( forKey: key, value: value)
150+ if let currentContext = self . getCurrentContextValue ( forKey: key) {
151+ ActivityContextManager . taskLocalContextManager. setCurrentContextValue ( forKey: key, value: currentContext)
152+ }
103153 }
104- }
105154#endif
155+ #endif
156+ }
106157 }
107158}
0 commit comments