Add more tests for KRefSharedHolder and BackRefFromAssociatedObject (#3969)
Likely broken with #3267, fixed with #3966.
This commit is contained in:
committed by
GitHub
parent
04ada3d0ea
commit
4e9ea6803a
@@ -1109,6 +1109,13 @@ __attribute__((swift_name("SharedRefs.MutableData")))
|
||||
@property int32_t x __attribute__((swift_name("x")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("TestRememberNewObject")))
|
||||
@protocol KtTestRememberNewObject
|
||||
@required
|
||||
- (id)getObject __attribute__((swift_name("getObject()")));
|
||||
- (void)waitForCleanup __attribute__((swift_name("waitForCleanup()")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("ClassForTypeCheck")))
|
||||
@interface KtClassForTypeCheck : KtBase
|
||||
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||
@@ -1283,6 +1290,7 @@ __attribute__((swift_name("ValuesKt")))
|
||||
+ (void)error __attribute__((swift_name("error()"))) __attribute__((unavailable("error")));
|
||||
+ (void)warning __attribute__((swift_name("warning()"))) __attribute__((deprecated("warning")));
|
||||
+ (void)gc __attribute__((swift_name("gc()")));
|
||||
+ (void)testRememberNewObjectTest:(id<KtTestRememberNewObject>)test __attribute__((swift_name("testRememberNewObject(test:)")));
|
||||
+ (BOOL)testClassTypeCheckX:(id)x __attribute__((swift_name("testClassTypeCheck(x:)")));
|
||||
+ (BOOL)testInterfaceTypeCheckX:(id)x __attribute__((swift_name("testInterfaceTypeCheck(x:)")));
|
||||
+ (int32_t)testAbstractInterfaceCallX:(id<KtIAbstractInterface>)x __attribute__((swift_name("testAbstractInterfaceCall(x:)")));
|
||||
|
||||
@@ -885,6 +885,17 @@ class SharedRefs {
|
||||
private val mustBeRemoved = mutableListOf<WeakReference<*>>()
|
||||
}
|
||||
|
||||
interface TestRememberNewObject {
|
||||
fun getObject(): Any
|
||||
fun waitForCleanup()
|
||||
}
|
||||
|
||||
fun testRememberNewObject(test: TestRememberNewObject) {
|
||||
val obj = autoreleasepool { test.getObject() }
|
||||
test.waitForCleanup()
|
||||
assertNotEquals("", obj.toString()) // Likely crashes if object is removed.
|
||||
}
|
||||
|
||||
open class ClassForTypeCheck
|
||||
|
||||
fun testClassTypeCheck(x: Any) = x is ClassForTypeCheck
|
||||
|
||||
@@ -913,7 +913,7 @@ class TestSharedRefs {
|
||||
DispatchQueue.global().async(execute: getClosure())
|
||||
}
|
||||
|
||||
private static func runInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) {
|
||||
private static func launchInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) -> pthread_t {
|
||||
class Closure {
|
||||
static var currentBlock: (() -> Void)? = nil
|
||||
static var initializeKotlinRuntime: Bool = false
|
||||
@@ -934,11 +934,19 @@ class TestSharedRefs {
|
||||
return nil
|
||||
}, nil)
|
||||
try! assertEquals(actual: createCode, expected: 0)
|
||||
return thread!
|
||||
}
|
||||
|
||||
let joinCode = pthread_join(thread!, nil)
|
||||
private static func joinThread(thread: pthread_t) {
|
||||
let joinCode = pthread_join(thread, nil)
|
||||
try! assertEquals(actual: joinCode, expected: 0)
|
||||
}
|
||||
|
||||
private static func runInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) {
|
||||
let thread = launchInNewThread(initializeKotlinRuntime: initializeKotlinRuntime, block: block)
|
||||
joinThread(thread: thread)
|
||||
}
|
||||
|
||||
private func runInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) {
|
||||
return TestSharedRefs.runInNewThread(initializeKotlinRuntime: initializeKotlinRuntime, block: block)
|
||||
}
|
||||
@@ -1048,6 +1056,51 @@ class TestSharedRefs {
|
||||
try assertTrue(Deinit.weakVar2 === nil)
|
||||
}
|
||||
|
||||
func testRememberNewObject(createObject: @escaping (SharedRefs) -> AnyObject) throws {
|
||||
|
||||
class TestImpl : TestRememberNewObject {
|
||||
let cleanupFinishedSemaphore = DispatchSemaphore(value: 0)
|
||||
let threadWaitingForCleanupSemaphore = DispatchSemaphore(value: 0)
|
||||
|
||||
var obj: AnyObject? = nil
|
||||
|
||||
func getObject() -> Any {
|
||||
return obj!
|
||||
}
|
||||
|
||||
func waitForCleanup() {
|
||||
threadWaitingForCleanupSemaphore.signal()
|
||||
cleanupFinishedSemaphore.wait()
|
||||
}
|
||||
}
|
||||
|
||||
let test = TestImpl()
|
||||
|
||||
let refs = SharedRefs()
|
||||
try assertFalse(refs.hasAliveObjects())
|
||||
|
||||
autoreleasepool {
|
||||
test.obj = createObject(refs)
|
||||
}
|
||||
|
||||
try assertTrue(refs.hasAliveObjects())
|
||||
|
||||
let thread = TestSharedRefs.launchInNewThread(initializeKotlinRuntime: false) {
|
||||
ValuesKt.testRememberNewObject(test: test)
|
||||
}
|
||||
|
||||
test.threadWaitingForCleanupSemaphore.wait()
|
||||
test.obj = nil
|
||||
ValuesKt.gc()
|
||||
|
||||
try assertTrue(refs.hasAliveObjects())
|
||||
|
||||
test.cleanupFinishedSemaphore.signal()
|
||||
|
||||
TestSharedRefs.joinThread(thread: thread)
|
||||
try assertFalse(refs.hasAliveObjects())
|
||||
}
|
||||
|
||||
func test() throws {
|
||||
try testLambdaSimple()
|
||||
try testObjectPartialRelease()
|
||||
@@ -1064,6 +1117,9 @@ class TestSharedRefs {
|
||||
try testReferenceOutlivesThread(releaseWithKotlinRuntime: true)
|
||||
try testMoreWorkBeforeThreadExit()
|
||||
|
||||
try testRememberNewObject(createObject: { $0.createFrozenRegularObject() })
|
||||
try testRememberNewObject(createObject: { $0.createFrozenCollection() })
|
||||
|
||||
usleep(300 * 1000)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user