Lifetime of shared instance being tracked in C++ side as weak pointer #149
Replies: 3 comments
-
I'm not sure if you're asking for a new feature or an explanation of the existing lifetime behavior. I'm going to answer the latter as a baseline. That T* returned in the iOS code is an NSObject (called a proxy), with a lifetime managed via reference counting in the standard way (generally automatically) for Objective C code (or via indirection from Swift code). Inside of the generated glue code that NSObject holds on to a shared_ptr to the C++ object, so there is a safe, strongly-held lifetime, and no worry of dangling pointers. So if your C++ GetInstance method is called while the NSObject is still in use, the lock() call will return a valid pointer to the same underlying C++ object. As soon as the Objective-C Manager object becomes unreferenced (refcount == 0), the C++ Manager object will be deleted, and the next call to your GetInstance method will end up creating a new one. The proxy cache you mentioned is independent of this mechanism. It relies on a weak_ptr, but for a slightly different purpose. In your example, when a second call to GetInstance() returns the same C++ object, the proxy cache is involved in finding and returning the same NSObject which was created by the first call (so long as it's still alive and in use from Objective-C code). The main way you'll notice the proxy cache is working is if you call Manager::getInstance() twice from ObjC, you'll get back pointers to the same object, and can compare them directly with ptr1==ptr2. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the explanation. The use of weak_ptr makes sure that the proxy cache is not extending the lifetime of the instance in ios layer. Are there any guarantees in case of java layer? I guess, as GC is handling lifetime of the instance, it wouldn't be applicable to manage the lifetime of the instance and only keep weak_ptr in C++ layer (?). |
Beta Was this translation helpful? Give feedback.
-
The lifetime semantics in Java are identical, though the mechanism is different. But the Java proxy object will hold a strong shared_ptr to the C++ object and keep it alive until the Java object gets GCed (and finalized). That's the same semantics as ObjC, except that you don't have guarantees about how long it takes an object to be GCed and finalized. Note also that all the same semantics would also hold in reverse if you were dealing with a +o+j object. The intent of Djinni is to have the same semantics on all platforms, tweaked only to fit into the native patterns. Platforms beyond the core 2 (ObjC + Java) should follow that too, but may have their own limitations or quirks. E.g. the last time I worked on the Python implementation (not sure what's changed since) it didn't yet include a proxy cache, so you wouldn't be guaranteed that the same object passed through the language boundary twice would result in the same proxy object. Still at the time Python did have the standard ownership/lifetime semantics. |
Beta Was this translation helpful? Give feedback.
-
Based on current implementation of Djinni, there is no lifetime specification of instances being declared in C++ with weak pointer(aka std::weak_ptr) and returned to platform(e.g. ios side), as the djinni auto-generator returns just 'T*' to ios level w/o any additional lifetime specifications. The only platform side holder is 'proxy-cache' which however has no specification of lifetime of the instance.
Below is an example of such case:
--- In djinni we have:
IT1 = interface +c {}
Manager = interface +c {
get_instance(): IT1
}
--- In C++ we have
std::weak_ptr instance;
std::shared_ptr Manager::GetInstance() {
std::shared_ptr res{instance.lock()};
if (nullptr == res) {
res = std::make_shared();
instance = res;
}
return res; // return to ios/android level w/o any save in C++ side (i.e. just weak pointer)
}
---- ios level
let ist1 = Manager::getInstance();
///. save the pointer and work in ios level only. can pointer became dangling/invalid as there is no life-time guarentees/holders in C++ layer?
-------- END
Are there any plans to provide additional constraints on top of lifetime for such object instances.
Beta Was this translation helpful? Give feedback.
All reactions