Skip to content

Commit 5ddded8

Browse files
Adds one more test case for deadlock fix.
The cache for temporary service is not immediately released after the outermost eDO invocation. Instead, it is released when autorelease pool ends, such as the end of dispatch_sync/async. So adding a test case to imply that. At the same time, fix an issue that will fail the new test case, and cause retain cycle of host service -> handler -> host service. PiperOrigin-RevId: 361217991
1 parent 1e3afec commit 5ddded8

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

Service/Sources/EDOHostService.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,8 @@ - (void)startReceivingRequestsForChannel:(id<EDOChannel>)channel {
394394
EDOHostService *strongSelf = weakSelf;
395395
NSException *exception;
396396
// TODO(haowoo): Add the proper error handler.
397-
NSAssert(error == nil, @"Failed to receive the data (%d) for %@.",
398-
strongSelf.port.hostPort.port, error);
397+
NSCAssert(error == nil, @"Failed to receive the data (%d) for %@.",
398+
strongSelf.port.hostPort.port, error);
399399
if (data == nil) {
400400
// the client socket is closed.
401401
NSLog(@"The channel (%p) with port %d is closed", targetChannel,

Service/Tests/UnitTests/EDOServiceTest.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,28 @@ - (void)testTemporaryServiceResolvesLocalObject {
255255
XCTAssertEqual(anObject, rountTripObject);
256256
}
257257

258+
/** Verifies the temporary host keeps being reused until the end of an external autorelease pool. */
259+
- (void)testTemporaryServiceIsReleasedLazily {
260+
dispatch_queue_t testQueue = dispatch_queue_create("com.google.edotest", DISPATCH_QUEUE_SERIAL);
261+
EDOTestDummy *dummyOnBackground = self.rootObjectOnBackground;
262+
XCTestExpectation *expectation =
263+
[self expectationWithDescription:@"temporary service retain count check"];
264+
265+
dispatch_async(testQueue, ^{
266+
__weak EDOHostService *temporaryHostService = nil;
267+
@autoreleasepool {
268+
temporaryHostService = [EDOHostService temporaryServiceForCurrentThread];
269+
[dummyOnBackground voidWithBlock:^{
270+
}];
271+
XCTAssertNotNil(temporaryHostService);
272+
}
273+
XCTAssertNil(temporaryHostService);
274+
[expectation fulfill];
275+
});
276+
277+
[self waitForExpectations:@[ expectation ] timeout:1.0];
278+
}
279+
258280
- (void)testClassMethodsAndInit {
259281
Class remoteClass = EDO_REMOTE_CLASS(EDOTestDummy, self.serviceOnBackground.port.hostPort.port);
260282

0 commit comments

Comments
 (0)