kevin.cianfarini
03/13/2020, 2:13 PMArtyom Degtyarev [JB]
03/13/2020, 2:29 PMkevin.cianfarini
03/13/2020, 2:30 PMkevin.cianfarini
03/13/2020, 2:32 PMuse
-like functions.Arkadii Ivanov
03/14/2020, 3:32 PMsvyatoslav.scherbina
03/14/2020, 4:30 PMArkadii Ivanov
03/14/2020, 4:35 PMthis
from the deinit block. E.g. show warning same was as it does when leaking this
from init block. Or even error.Arkadii Ivanov
03/14/2020, 4:43 PMsvyatoslav.scherbina
03/14/2020, 4:57 PMBut this is just a workaround that pollutes the code and the API.How does it pollute the API? Also this approach clearly demonstrates that your statement above is not entirely correct:
You can’t dispose the lock because you never know how many threads are still using your object. And a deinit function is the only way to safely dispose the lock,The example shows how to know exactly how many threads are still using the lock, and how to safely dispose the lock without
deinit
function.
You also can properly encapsulate this to a lock class, thus making usages of the lock clean.Arkadii Ivanov
03/14/2020, 5:25 PMput
method it may crash. So you have to expose ref counting methods as API and call increment
before transferring the object.Arkadii Ivanov
03/14/2020, 5:26 PMdeinit
block with forbidden this
leaking.svyatoslav.scherbina
03/14/2020, 5:34 PMSince the object holding the lock may be destroyed while being transferred to an another thread.Could you clarify? What exactly do you mean by “transferred to an another thread”? What do you mean by “object … may be destroyed”? What is “object holding the lock”?
And when another thread will call theWhat exactly may crash inmethod it may crash.put
put
and how?Arkadii Ivanov
03/14/2020, 6:46 PMArkadii Ivanov
03/14/2020, 6:56 PMput
method when MyRepository is already destroyed. Let say you have a view controller (or a screen) that has onDestroy method. You will create MyRepository in view controller's constructor and call MyRepository.destroy() in view controller's onDestroy method. This call is unsafe since the instance of MyRepository may be used by a background thread. This thread will crash on next call of MyRepository.put(). You can change the implementation of the MyRepository so it won't crash. Then you probably will do nothing. This is as bad as crashing.svyatoslav.scherbina
03/14/2020, 7:10 PMArkadii Ivanov
03/15/2020, 11:31 AMkevin.cianfarini
03/15/2020, 3:40 PMdeinit
block, as finalizers are evil. They've been removed from Java for a reason. If for whatever reason an Exception is thrown in them, you're SOL.
I'm just wondering how this explicit choice is going to persist into things that are fairly standard for a language. Eg. IOsvyatoslav.scherbina
03/17/2020, 8:37 AMArkadii Ivanov
03/17/2020, 8:46 AMIan Stewart
04/29/2020, 8:30 PMIan Stewart
05/04/2020, 9:27 PMlib_symbols()->associateMetaData(NativePtr *pinned, void *data, void (*dispose)(void*))
function, that would call dispose(data) when pinned is garbage collected? This would give the same flexibility as objective C and I believe would be enough for me to manually handle lambdas without resorting to adding addref/release’s in the Kotlin code.svyatoslav.scherbina
05/07/2020, 3:15 PMWhy can’t there be a similar hook in the C interop? It seems this one language is crippled for a reason that somehow was not enforced with Objective-C.Objective-C interop doesn’t provide any particular memory management hook by itself.
would there be a way to have a
lib_symbols()->associateMetaData(NativePtr *pinned, void *data, void (*dispose)(void*))
functionThis approach doesn’t seem to be implementable efficiently. I understand your demand for “finalizers” to simplify using C libraries. However, according to our experience, any similar machinery in language should be carefully designed first. Also consider all issues mentioned in previous discussions.
Ian Stewart
05/08/2020, 3:39 AMsvyatoslav.scherbina
05/08/2020, 12:44 PMI was hoping it would be as simple as adding a C equivalent to Kotlin_ObjCExport_releaseAssociatedObject in Memory.cpp.This approach is not scalable efficiently. Also there is a huge difference between design and implementation. Controversial complicated features like finalizers shouldn’t be derived from the implementation.
How does Objective-C know it can garbage-collect lambdas?Do you mean Objective-C blocks or Kotlin lambdas?
Note I am not trying to use C libraries. I am trying to use a Kotlin library, within C++.Then why exactly do you need to hook Kotlin object deallocation? What is your case, what exactly are you trying to bind to Kotlin object lifetime?
Ian Stewart
05/08/2020, 1:27 PMIan Stewart
05/08/2020, 1:54 PMKotlin_ObjCExport_releaseAssociatedObject
being called by the Kotlin/Native garbage collector. This means that Kotlin libraries can be written using Kotlin idioms, and used cleanly in Swift etc..
Yes, I understand that it opens a door - we now essentially have finalizers when using it in ObjectiveC (I can associate an object in ObjectiveC to a Kotlin-wrapped object, and do whatever I want in the ‘dispose’ callback).
However, as the ObjectiveC implementation also shows, you have very little choice if you want to avoid forcing error-prone, manual reference-counting patterns into the Kotlin code.svyatoslav.scherbina
05/11/2020, 3:22 PMa continuation for an async operation.In this case you can call your deallocation code from the continuation itself. Do you have other cases that can’t be handled with this approach?
we now essentially have finalizers when using it in ObjectiveC (I can associate an object in ObjectiveC to a Kotlin-wrapped object, and do whatever I want in the ‘dispose’ callback).Not exactly. E.g. this doesn’t give you access to a Kotlin object which is being/going to be reclaimed, unlike finalizers/destructors/etc.
Ian Stewart
05/11/2020, 3:25 PMIn this case you can call your deallocation code from the continuation itself. Do you have other cases that can’t be handled with this approach?This assumes the continuation is called.
Not exactly. E.g. this doesn’t give you access to a Kotlin object which is being/going to be reclaimed, unlike finalizers/destructors/etc.Good point, although this is fine with me; I would not expect to have access to this. I’m not trying to add a Kotlin finalizer, I’m trying to gc my related structures.
svyatoslav.scherbina
05/12/2020, 8:21 AMThis assumes the continuation is called.Exactly. That’s why I’m asking “Do you have other cases that can’t be handled with this approach?”
Ian Stewart
05/12/2020, 10:33 AMsvyatoslav.scherbina
05/12/2020, 2:34 PMIan Stewart
05/12/2020, 4:58 PMsvyatoslav.scherbina
05/13/2020, 10:46 AMwhy is it different for Objective-C?Because Objective-C has automated memory management, while C doesn’t.
Ian Stewart
05/13/2020, 1:55 PMBecause Objective-C has automated memory management, while C doesn’t.How does Objective-C automatically dispose of memory associated with Kotlin without Kotlin’s help? e.g., if a lambda is passed into Kotlin, how does Objective-C know it is safe to dispose it? Is this a pattern I can apply as a user of the K/N C library? Is the Objective-C integration written relative to the C library? True, C does not have automated memory management, but without this hook, it seems to me it is very difficult for library users to put this automation in for higher-level programming languages/applications.
svyatoslav.scherbina
05/13/2020, 5:14 PMHow does Objective-C automatically dispose of memory associated with Kotlin without Kotlin’s help? e.g., if a lambda is passed into Kotlin, how does Objective-C know it is safe to dispose it?Because Kotlin `retain`s the lambda when gets it, creates Kotlin wrapper for it, and `release`s the lambda it when the wrapper is reclaimed.
Is this a pattern I can apply as a user of the K/N C library?No.
Is the Objective-C integration written relative to the C library?Could you clarify?
but without this hook, it seems to me it is very difficult for library users to put this automation in for higher-level programming languages/applications.I get it. This doesn’t make me implement it immediately though.