Gabriel M. Beddingfield wrote:

> While true... it should only be an issue during start-up -- a time when we 
> shouldn't be in any real-time threads, anyway.

Assuming you're using the double-checking logic to avoid locking after
constructor ends, that's true. If you didn't, any Hydrogen::get_instance
in any place of the program would cause the mutex to be locked (for a
fraction of millisecond, but another thread may still bump into a locked
mutex and have to wait).

In any case, if audio thread doesn't call Hydrogen::get_instance during
its operation, then you're right :) (but at least the MIDI thread does,
don't know about audio).

> Yes, it is the MIDI thread -- but it *could be* anyone.

It could only be MIDI or audio thread (because the GUI thread is the one
that calls the initial get_instance() in first place).

For audio, the problem is diminished because of the fact that the engine
lock is held during initialization and released after everything is
prepared (but there's still a tiny time slot where the lock is released
and the object isn't considered fully constructed!). But you're right,
it can still happen.

The primary cause is still that worker threads are started from a
constructor of a singleton. Starting the audio code explicitly instead
of automatically would allow using your 2-line singleton pattern safely,
and also make it easier to implement changing audio/MIDI drivers without
a restart.

However, I understand that's a high-risk change and might end up as bug
reports like "no audio at all when initial song is loaded". Which is
worse than the original #37, I think.

> // Remove the Hydrogen::__instance class member and do:
> Hydrogen* get_hydrogen_instance(void)
> {
>       static Hydrogen h;
>       return &h;
> }

This is a nice pattern (I use it in calf), but it doesn't work when the
code called from constructor calls get_hydrogen_instance again (which is
what we're currently dealing with):

#include <stdio.h>

struct A {
  A() { printf("Ctor\n"); A::get(); }
  static A* get() { static A a; return &a; }
};

int main()
{
  A::get();
  return 0;
}

Basically, during the call to A::get() from constructor, the a variable
isn't considered constructed yet, so it might be constructed again, etc.

GCC/libstdc++ detects a such situations (probably by flagging the
variable as "construction in progress") and throws an exception:

Ctor
terminate called after throwing an instance of
'__gnu_cxx::recursive_init_error'
  what():  std::exception
Aborted

Krzysztof


------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Hydrogen-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hydrogen-devel

Reply via email to