1
- // RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library) | %FileCheck %s
1
+ // RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-stdlib -parse- as-library) | %FileCheck %s
2
2
3
3
// REQUIRES: executable_test
4
4
// REQUIRES: concurrency
10
10
// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574
11
11
// UNSUPPORTED: OS=windows-msvc
12
12
13
+ import Swift
14
+ import _Concurrency
13
15
import Distributed
16
+ import Dispatch
17
+
18
+ @_silgen_name ( " swift_task_isCurrentExecutor " )
19
+ private func isCurrentExecutor( _ executor: Builtin . Executor ) -> Bool
20
+
21
+ func getExecutor( _ a: AnyActor ) -> Builtin . Executor {
22
+ let pack = ( a, UnsafeRawPointer ? . none)
23
+ return unsafeBitCast ( pack, to: Builtin . Executor. self)
24
+ }
25
+
26
+ func isCurrent( _ a: AnyActor ) -> Bool {
27
+ return isCurrentExecutor ( getExecutor ( a) )
28
+ }
29
+
30
+ func isMainThread( ) -> Bool {
31
+ isCurrentExecutor ( Builtin . buildMainActorExecutorRef ( ) )
32
+ }
14
33
15
34
actor A { }
16
35
@@ -28,26 +47,54 @@ distributed actor DA_userDefined {
28
47
nonisolated deinit { }
29
48
}
30
49
31
- distributed actor DA_userDefined2 {
50
+ distributed actor DA_userDefined_nonisolated {
32
51
init ( system: FakeActorSystem ) {
33
52
self . actorSystem = system
34
53
}
35
54
36
55
nonisolated deinit {
37
- print ( " Deinitializing \( self . id) remote: \( __isRemoteActor ( self ) ) " )
56
+ print ( " Deinitializing \( self . id) remote: \( __isRemoteActor ( self ) ) isolated: \( isCurrent ( self ) ) " )
38
57
}
39
58
}
40
59
41
- distributed actor DA_state {
42
- var name = " Hello "
43
- var age = 42
44
-
60
+ distributed actor DA_userDefined_isolated {
45
61
init ( system: FakeActorSystem ) {
46
62
self . actorSystem = system
47
63
}
48
64
65
+ deinit {
66
+ print ( " Deinitializing \( self . id) remote: \( __isRemoteActor ( self ) ) isolated: \( isCurrent ( self ) ) " )
67
+ }
68
+ }
69
+
70
+ distributed actor DA_state_nonisolated {
71
+ var name : String
72
+ var age : Int
73
+
74
+ init ( name: String , age: Int , system: FakeActorSystem ) {
75
+ self . name = name
76
+ self . age = age
77
+ self . actorSystem = system
78
+ }
79
+
49
80
nonisolated deinit {
50
- print ( " Deinitializing \( self . id) remote: \( __isRemoteActor ( self ) ) " )
81
+ print ( " Deinitializing \( self . id) name= \( name) age= \( age) remote: \( __isRemoteActor ( self ) ) isolated: \( isCurrent ( self ) ) " )
82
+ return
83
+ }
84
+ }
85
+
86
+ distributed actor DA_state_isolated {
87
+ var name : String
88
+ var age : Int
89
+
90
+ init ( name: String , age: Int , system: FakeActorSystem ) {
91
+ self . name = name
92
+ self . age = age
93
+ self . actorSystem = system
94
+ }
95
+
96
+ deinit {
97
+ print ( " Deinitializing \( self . id) name= \( name) age= \( age) remote: \( __isRemoteActor ( self ) ) isolated: \( isCurrent ( self ) ) " )
51
98
return
52
99
}
53
100
}
@@ -69,6 +116,16 @@ final class FakeActorSystem: @unchecked Sendable, DistributedActorSystem {
69
116
typealias ResultHandler = FakeResultHandler
70
117
71
118
var n = 0
119
+ let group : DispatchGroup
120
+
121
+ init ( group: DispatchGroup ) {
122
+ self . group = group
123
+ }
124
+
125
+ deinit {
126
+ print ( " Deinit ActorSystem: mainThread= \( isMainThread ( ) ) " )
127
+ group. leave ( )
128
+ }
72
129
73
130
func resolve< Act> ( id: ActorID , as actorType: Act . Type ) throws -> Act ?
74
131
where Act: DistributedActor ,
@@ -174,7 +231,7 @@ typealias DefaultDistributedActorSystem = FakeActorSystem
174
231
// ==== Execute ----------------------------------------------------------------
175
232
176
233
func test( ) {
177
- let system = DefaultDistributedActorSystem ( )
234
+ let group = DispatchGroup ( )
178
235
179
236
// no lifecycle things make sense for a normal actor, double check we didn't emit them
180
237
print ( " before A " )
@@ -183,46 +240,98 @@ func test() {
183
240
// CHECK: before A
184
241
// CHECK: after A
185
242
243
+ group. enter ( )
186
244
_ = { ( ) -> DA in
187
- DA ( system: system )
245
+ DA ( system: DefaultDistributedActorSystem ( group : group ) )
188
246
} ( )
247
+ group. wait ( )
189
248
// CHECK: assign type:DA, address:[[ADDRESS:.*]]
190
249
// CHECK: ready actor:main.DA, address:ActorAddress(address: "[[ADDR1:addr-[0-9]]]")
191
250
// CHECK: resign address:ActorAddress(address: "[[ADDR1]]")
251
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=true
192
252
253
+ group. enter ( )
193
254
_ = { ( ) -> DA_userDefined in
194
- DA_userDefined ( system: system )
255
+ DA_userDefined ( system: DefaultDistributedActorSystem ( group : group ) )
195
256
} ( )
257
+ group. wait ( )
196
258
// CHECK: assign type:DA_userDefined, address:[[ADDRESS:.*]]
197
259
// CHECK: ready actor:main.DA_userDefined, address:ActorAddress(address: "[[ADDR2:addr-[0-9]]]")
198
260
// CHECK: resign address:ActorAddress(address: "[[ADDR2]]")
261
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=true
199
262
200
263
// resign must happen as the _last thing_ after user-deinit completed
201
- _ = { ( ) -> DA_userDefined2 in
202
- DA_userDefined2 ( system: system)
264
+ group. enter ( )
265
+ _ = { ( ) -> DA_userDefined_nonisolated in
266
+ DA_userDefined_nonisolated ( system: DefaultDistributedActorSystem ( group: group) )
203
267
} ( )
204
- // CHECK: assign type:DA_userDefined2, address:[[ADDRESS:.*]]
205
- // CHECK: ready actor:main.DA_userDefined2, address:ActorAddress(address: "[[ADDR3:addr-[0-9]]]")
206
- // CHECK: Deinitializing ActorAddress(address: "[[ADDR3]]") remote:false
268
+ group. wait ( )
269
+ // CHECK: assign type:DA_userDefined_nonisolated, address:[[ADDRESS:.*]]
270
+ // CHECK: ready actor:main.DA_userDefined_nonisolated, address:ActorAddress(address: "[[ADDR3:addr-[0-9]]]")
271
+ // CHECK: Deinitializing ActorAddress(address: "[[ADDR3]]") remote:false isolated:false
207
272
// CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR3]]")
208
-
273
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=true
274
+
209
275
// resign must happen as the _last thing_ after user-deinit completed
210
- _ = { ( ) -> DA_state in
211
- DA_state ( system: system)
276
+ group. enter ( )
277
+ _ = { ( ) -> DA_userDefined_isolated in
278
+ DA_userDefined_isolated ( system: DefaultDistributedActorSystem ( group: group) )
212
279
} ( )
213
- // CHECK: assign type:DA_state, address:[[ADDRESS:.*]]
214
- // CHECK: ready actor:main.DA_state, address:ActorAddress(address: "[[ADDR4:addr-[0-9]]]")
215
- // CHECK: Deinitializing ActorAddress(address: "[[ADDR4]]") remote:false
280
+ group. wait ( )
281
+ // CHECK: assign type:DA_userDefined_isolated, address:[[ADDRESS:.*]]
282
+ // CHECK: ready actor:main.DA_userDefined_isolated, address:ActorAddress(address: "[[ADDR4:addr-[0-9]]]")
283
+ // CHECK: Deinitializing ActorAddress(address: "[[ADDR4]]") remote:false isolated:true
216
284
// CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR4]]")
285
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=false
217
286
287
+ // resign must happen as the _last thing_ after user-deinit completed
288
+ group. enter ( )
289
+ _ = { ( ) -> DA_state_nonisolated in
290
+ DA_state_nonisolated ( name: " Foo " , age: 37 , system: DefaultDistributedActorSystem ( group: group) )
291
+ } ( )
292
+ group. wait ( )
293
+ // CHECK: assign type:DA_state_nonisolated, address:[[ADDRESS:.*]]
294
+ // CHECK: ready actor:main.DA_state_nonisolated, address:ActorAddress(address: "[[ADDR5:addr-[0-9]]]")
295
+ // CHECK: Deinitializing ActorAddress(address: "[[ADDR5]]") name=Foo age=37 remote:false isolated:false
296
+ // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR5]]")
297
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=true
298
+
299
+ // resign must happen as the _last thing_ after user-deinit completed
300
+ group. enter ( )
301
+ _ = { ( ) -> DA_state_isolated in
302
+ DA_state_isolated ( name: " Bar " , age: 42 , system: DefaultDistributedActorSystem ( group: group) )
303
+ } ( )
304
+ group. wait ( )
305
+ // CHECK: assign type:DA_state_isolated, address:[[ADDRESS:.*]]
306
+ // CHECK: ready actor:main.DA_state_isolated, address:ActorAddress(address: "[[ADDR6:addr-[0-9]]]")
307
+ // CHECK: Deinitializing ActorAddress(address: "[[ADDR6]]") name=Bar age=42 remote:false isolated:true
308
+ // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR6]]")
309
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=false
310
+
311
+ // a remote actor should not resign it's address, it was never "assigned" it
312
+ group. enter ( )
313
+ _ = { ( ) -> DA_userDefined_nonisolated in
314
+ let address = ActorAddress ( parse: " remote-1 " )
315
+ return try ! DA_userDefined_nonisolated . resolve ( id: address, using: DefaultDistributedActorSystem ( group: group) )
316
+ } ( )
317
+ group. wait ( )
318
+ // CHECK-NEXT: resolve type:DA_userDefined_nonisolated, address:ActorAddress(address: "remote-1")
319
+ // MUST NOT run deinit body for a remote distributed actor
320
+ // CHECK-NOT: Deinitializing ActorAddress(address: "remote-1")
321
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=true
322
+
218
323
// a remote actor should not resign it's address, it was never "assigned" it
219
- let address = ActorAddress ( parse: " remote-1 " )
220
- _ = { ( ) -> DA_userDefined2 in
221
- try ! DA_userDefined2 . resolve ( id: address, using: system)
324
+ group. enter ( )
325
+ _ = { ( ) -> DA_userDefined_isolated in
326
+ let address = ActorAddress ( parse: " remote-2 " )
327
+ return try ! DA_userDefined_isolated . resolve ( id: address, using: DefaultDistributedActorSystem ( group: group) )
222
328
} ( )
223
- // CHECK-NEXT: resolve type:DA_userDefined2, address:ActorAddress(address: "[[ADDR5:remote-1]]")
329
+ group. wait ( )
330
+ // CHECK-NEXT: resolve type:DA_userDefined_isolated, address:ActorAddress(address: "remote-2")
224
331
// MUST NOT run deinit body for a remote distributed actor
225
- // CHECK-NOT: Deinitializing ActorAddress(address: "remote-1") remote:true
332
+ // CHECK-NOT: Deinitializing ActorAddress(address: "remote-2")
333
+ // TODO: Fix this. Remote proxies should not have isolated deinit.
334
+ // CHECK-NEXT: Deinit ActorSystem: mainThread=false
226
335
227
336
print ( " DONE " )
228
337
// CHECK-NEXT: DONE
0 commit comments