On 2009-04-18 23:22:21 +0200, Leandro Lucarella <llu...@gmail.com> said:

Leandro Lucarella, el 18 de abril a las 18:03 me escribiste:
Fawzi Mohamed, el 18 de abril a las 22:48 me escribiste:
On 2009-04-18 22:25:32 +0200, Don <nos...@nospam.com> said:

Leandro Lucarella wrote:
Robert Jacques, el 18 de abril a las 11:56 me escribiste:
On Sat, 18 Apr 2009 11:24:14 -0400, Leandro Lucarella <llu...@gmail.com> wrote:
I've just found out[1] this[2]:
        The garbage collector is not guaranteed to run the destructor for
        all unreferenced objects.
Is there any reason why D can't guarantee that all finalizers will be
called, at least when the program ends?

when the main thread ends other threads might be running, and removing
memory they are using is not necessarily a good idea.

Then I guess gc_term() should be invoked when all threads have terminated.
Is there any technical difficulty to do that?

Exceptions might delay things indefinitely and allocate more memory.

Then I guess gc_term() should be invoked when all exceptions were
processed. Is there any technical difficulty to do that?

I really didn't take a look at the compiler runtime stuff, so I don't
really know how all that works.

Ok, this is the code that handle the D main (Tango runtime
compiler/ldc/rt/dmain2.d, main() function, around line 260):

    void runMain()
    {
        debug(PRINTF) printf("main runMain\n");
        result = main(args);
    }

    void runAll()
    {
        debug(PRINTF) printf("main runAll\n");
        gc_init();
        _moduleCtor();
        if (runModuleUnitTests())
            tryExec(&runMain);
        thread_joinAll();
        _d_isHalting = true;
        _moduleDtor();
        gc_term();
    }

    tryExec(&runAll);

    debug(PRINTF) printf("main dtor\n");
    _STD_critical_term();
    _STD_monitor_staticdtor();

    return result;

If thread_joinAll() is called before gc_term(), I can't see how a thread
could be still running when gc_term() is called. So, in terms of threads,
I don't see a problem here.

daemon theads are not joined

About exceptions, I think it could be solved too. One option is to require
gc_term() to be "nonthrow" (I mean, for D1 and D2). I think the specs
doesn't say anything about destructors throwing exceptions. I think they
shouldn't but let's suppose they could. Since there is no way the use can
catch a destructor exception thrown in the GC (well, not in an useful way,
one could try/catch the new call or something but that doesn't work for
concurrent collectors that can sweep in a separate thread anyway, so
I think it's a bad idea), I guess it would be acceptable to:
a) Ignore the exception
b) Let the user provide a callback to handle that kind of exceptions

finalizer should not throw already now, if they do an exception is raised.

Then, gc_term() ca be moved outside the tryExec(&runAll) call and
gc_term() can safely call all the live objects finalizers and provide
guaranteed finalization.


PS: I have not read all the runtime, just this small part, so maybe I'm
    missing the big picture =)


Reply via email to