Skip to content

Commit 0d086de

Browse files
Adjust the dispatch queue of EDO reference release.
Make EDOHostService's references of local objects be released on its execution queue (if exists). Before this change, EDOHostService always releases its underlying objects in background queue, which may break user-side assumption that some objects should always be released on main thread. In this case, user usually sends those objects to remote process through main thread's EDOHostService. So the host service should release the references on main thread as well. PiperOrigin-RevId: 277129572
1 parent 372b62f commit 0d086de

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

Service/Sources/EDOHostService.m

+12-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,11 @@ - (BOOL)isObjectAlive:(EDOObject *)object {
334334

335335
- (BOOL)removeObjectWithAddress:(EDOPointerType)remoteAddress {
336336
NSNumber *edoKey = [NSNumber numberWithLongLong:remoteAddress];
337+
__block NSObject *object NS_VALID_UNTIL_END_OF_SCOPE;
337338
dispatch_sync(_localObjectsSyncQueue, ^{
339+
// Transfer the ownership of local object to the outer queue, where the object should be
340+
// released.
341+
object = self.localObjects[edoKey];
338342
[self.localObjects removeObjectForKey:edoKey];
339343
});
340344
return YES;
@@ -413,7 +417,14 @@ - (void)startReceivingRequestsForChannel:(id<EDOChannel>)channel {
413417
// needed for this request. The request handler will process this request
414418
// properly in its own queue.
415419
if ([request class] == [EDOObjectReleaseRequest class]) {
416-
[EDOObjectReleaseRequest requestHandler](request, strongSelf);
420+
dispatch_queue_t executionQueue = strongSelf.executionQueue;
421+
if (executionQueue) {
422+
dispatch_async(executionQueue, ^{
423+
[EDOObjectReleaseRequest requestHandler](request, weakSelf);
424+
});
425+
} else {
426+
[EDOObjectReleaseRequest requestHandler](request, strongSelf);
427+
}
417428
} else {
418429
// Health check for the channel.
419430
[targetChannel sendData:EDOClientService.pingMessageData withCompletionHandler:nil];

Service/Tests/FunctionalTests/EDOServiceUITest.m

+29
Original file line numberDiff line numberDiff line change
@@ -388,4 +388,33 @@ - (void)testPassByValueWithLocalObject {
388388
XCTAssertEqualObjects(localClassName, @"EDOObject");
389389
}
390390

391+
/** Tests local object is released on the execution queue if it is released by EDOHostService. */
392+
- (void)testLocalObjectReleaseOnHostExecutionQueue {
393+
[self launchApplicationWithPort:EDOTEST_APP_SERVICE_PORT initValue:5];
394+
EDOHostService *service =
395+
[EDOHostService serviceWithPort:2234
396+
rootObject:[[EDOTestDummyInTest alloc] initWithValue:9]
397+
queue:dispatch_get_main_queue()];
398+
__block EDOTestDummyInTest *dummy = [[EDOTestDummyInTest alloc] init];
399+
__weak EDOTestDummyInTest *weakDummy = dummy;
400+
EDOTestDummy *remoteDummy = [EDOClientService rootObjectWithPort:EDOTEST_APP_SERVICE_PORT];
401+
402+
XCTestExpectation *expectation = [self expectationWithDescription:@"dummy is released on main."];
403+
dummy.deallocHandlerBlock = ^{
404+
XCTAssertTrue([NSThread isMainThread]);
405+
[expectation fulfill];
406+
};
407+
dummy.block = ^{
408+
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
409+
dummy = nil;
410+
});
411+
};
412+
413+
[remoteDummy returnPlus10AndAsyncExecuteBlock:dummy];
414+
[self waitForExpectations:@[ expectation ] timeout:2.0f];
415+
XCTAssertNil(weakDummy);
416+
417+
[service invalidate];
418+
}
419+
391420
@end

Service/Tests/FunctionalTests/EDOTestDummyInTest.h

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
@property NSNumber *value;
2626
@property EDOTestDummyInTest *dummyInTest;
2727
@property void (^block)(void);
28+
@property(nullable) void (^deallocHandlerBlock)(void);
2829

2930
- (instancetype)initWithValue:(int)value;
3031

Service/Tests/FunctionalTests/EDOTestDummyInTest.m

+7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ - (instancetype)initWithValue:(int)value {
3939
return self;
4040
}
4141

42+
- (void)dealloc {
43+
if (_deallocHandlerBlock) {
44+
_deallocHandlerBlock();
45+
}
46+
}
47+
4248
- (int)callTestDummy:(EDOTestDummy *)dummy {
4349
return self.value.intValue + [dummy returnIdWithInt:10].value + 3;
4450
}
@@ -59,4 +65,5 @@ - (void)invokeBlock {
5965
self.block();
6066
}
6167
}
68+
6269
@end

0 commit comments

Comments
 (0)