Based on this conversation in another thread: http://forum.dlang.org/thread/[email protected]?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

Reply via email to