Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 12, 2014 How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Based on this conversation in another thread: http://forum.dlang.org/thread/wdddgiowaidcojbrklsg@forum.dlang.org?page=5#post-yjmrqgesjtadecutvkye:40forum.dlang.org I've realised i may have a nasty bug lurking in the code. Now i want to completely understand what is happening. Take the following code: struct Args { Element element; string uniqueData; Callback callback; } class Element { void foo(Callback callback, string uniqueData = null) { auto handler = function(ClientData data) { // Use data. }; auto cleanup = function(ClientData data) { free(data); }; Args* args = cast(Args*)malloc(Args.sizeof); (*args) = Args.init; (*args).element = this; (*args).uniqueData = uniqueData; (*args).callback = callback; c_function(handler, args, cleanup); } } I want to make sure that `callback` and `uniqueData` are never cleaned up by the GC until i wish to allow them to be freed. A comment was made that in the above scenario `callback` and `uniqueData` allow the potential of being cleaned up and that a call to `GC.addRoot` might fix this problem. Would it be as simple to just add: GC.addRoot(cast(void*)args); GC.setAttr(cast(void*)args, GC.BlkAttr.NO_MOVE); to the above example? Would this not allow collection until a call to GC.removeRoot(). Or do i have to handle `callback` and `uniqueData` individually? If so how do you stop a delegate and string from being cleaned up by the GC? Any help or explanations are very much appreciated. This is the actual production code: https://github.com/nomad-software/tkd/blob/master/source/tkd/element/element.d#L172 |
May 12, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | AFAIK, addRoot is for memory allocated in GC heap, and addRange is for other types of memory, so you can't add non-gc memory as root (just a guess, see docs). I would allocate whole Args in GC heap and add is as root, yes, it would prevent collection until the root is removed. A better way would be to store Args in a linked list in the widget, this way it will be fully managed, and Args will live as long as the widget class instance references them without additional tinkering with GC. |
May 12, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Monday, 12 May 2014 at 19:13:28 UTC, Kagamin wrote:
> AFAIK, addRoot is for memory allocated in GC heap, and addRange is for other types of memory, so you can't add non-gc memory as root (just a guess, see docs). I would allocate whole Args in GC heap and add is as root, yes, it would prevent collection until the root is removed. A better way would be to store Args in a linked list in the widget, this way it will be fully managed, and Args will live as long as the widget class instance references them without additional tinkering with GC.
Ah yeah, i never thought, i could allocate Args on the GC heap.
I have to allocate it on the fly and not store it in the widget because there could be many. I'll have a fiddle.
|
May 12, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | Why many? I'd say, you typically have 0 subscriptions (label, textbox) per widget, seldom - 1 (button, combobox, checkbox). |
May 12, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | combobox and checkbox usually don't require a subscription either. Only button requires a reaction from your code, everything else usually works on its own. |
May 12, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Monday, 12 May 2014 at 20:03:46 UTC, Kagamin wrote: > Why many? I'd say, you typically have 0 subscriptions (label, textbox) per widget, seldom - 1 (button, combobox, checkbox). There are many events that can be bound to on any widget. https://github.com/nomad-software/tkd/blob/master/source/tkd/element/uielement.d#L328 |
May 13, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | Do you always bind all of them? |
May 13, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | Another option is to allocate from pool. |
May 13, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Tuesday, 13 May 2014 at 06:27:14 UTC, Kagamin wrote: > Do you always bind all of them? They are not bound automatically but may be bound later. You can bind to events such as mouse-enter, mouse-click, keypresses, etc. In fact this is how keyboard shortcuts are handled. I've added a potential fix to remove the allocation from the unmanaged heap and let the GC handle it. See what you think: https://github.com/nomad-software/tkd/commit/d77ff8603e26e7645c60b2613b996f1b21e751fc |
May 14, 2014 Re: How to make sure GC allocated resources stay around when used in C functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | It must be scanned, so you shouldn't specify NO_SCAN attribute, it's for memory blocks, which are guaranteed to not hold pointers to GC memory, like ubyte[] buffers for i/o, so managed blocks can be safely collected without looking at content of NO_SCAN blocks. |
Copyright © 1999-2021 by the D Language Foundation