roxen.lists.pike.general

Subject Author Date
Re: MutexKeys, garbage collectors, destructors and optimisers Martin Stjernholm <mast[at]lysator[dot]liu[dot]se> 04-02-2009
"Stephen R. van den Berg" <<srb[at]cuci.nl>> wrote:

> Well, not quite that bad, I'd say.  As I stated before as well,
> there is a difference between garbage collection of dead space and
> explicit destructors actually causing side-effects other than merely
> deallocating used space.

Yes, there is a difference. Unfortunately it's still just as bad,
because to get destructors called immediately when a thing runs out of
refs you still have to do refcounting. The gain is to be had when you
can delay both destruct and free to a later time, when the gc can do
it efficiently.

> The "destruct even if there still are references" functionality can
> simply be obtained by doing an explicit destruct(obj); just before the
> end of the block, of course.

Yes, but to cover all cases it becomes fairly unwieldy:

  Sql.Sql sql_cache_get(...)
  {
    Thread.MutexKey key = roxenloader.sq_cache_lock();
    mixed err = catch {
      Sql.Sql res = roxenloader.sq_cache_get(db, sessiondbs, charset);
      if (res) {
        destruct (key);
        return res;
      }
      // Release the lock during the call to get_sql_handler(),
      // since it may take quite a bit of time...
      destruct(key);
      if (res = get_sql_handler(url)) {
        // Now we need the lock again...
        key = roxenloader.sq_cache_lock();
        res = roxenloader.sq_cache_set(db, res, sessiondbs, charset);
        destruct (key);
      }
      return res;
    };
    destruct (key);
    throw (err);
  }

The main complication here is to handle exceptions.

> So in order to make the language more robust (without sacrificing
> optimisation opportunities for the compiler) I'd still prefer the
> C++ destructor semantics (principle of least surprise for
> programmers already familiar with C/C++).

Your parallell to C++ is a bit flawed since you compare an object
allocated in the heap to one on the stack. By the nature of the Pike
language, the mutex is allocated on the heap, so the analogy in C++
would be to use operator new. And then - as every C++ programmer
quickly has to learn - nothing happens unless there also is an
explicit operator delete somewhere.