Hi all,
Apologies for cross-posting - having some difficulty getting a
definitive answer on this one.
Trying to clarify the runtime behaviour of Cocoa-UI-based AU
bundles, in relation to module load & unload, and what the
correct behaviour should be.
Specifically:- since OS X 10.5, bundles (dynamic libraries)
implementing Objective-C code may be unloaded at run time (and, in
theory, reloaded), but ObjC classes cannot be unregistered / re
registered. The OS X documentation states that "the caller must
ensure that it does not refer to classes whose bundle has been
unloaded", or words to that effect. This, potentially, creates a
situation where (VST, AU) plug-ins can be UNloaded by a host, but
any attempt to REload them will cause a crash (when the plug-in
tries to access its classes, which are already registered with the
ObjC runtime at an old memory address).
What I'm wondering is this:- are plug-in bundles ever actually
unloaded by hosts or the OS in practice on 64-bit Mac OS X? It seems
that on a system with hundreds (thousands?) of plug-ins, it would
not be desirable to allow unwanted bundles to remain in memory (even
with a 64 bit virtual memory manager) - but unloading and reloading
would not appear to work, unless all plug-in bundles are coded so as
to synthesize unique ObjC class names every time they're loaded.
(FWIW, on 32-bit Mac OS X it was routine for plug-ins to be unloaded
and reloaded as needed by the host, but for the vast majority the
UIs were written in C++ to the Carbon/HIObject APIs so there was no
ObjC class registration going on).
I've done some testing with Logic Pro 9, Cubase 6 & Studio One
1.6, and so far have never observed my bundles being unloaded at
runtime, but I've not put the system under real stress & I can't
be absolutely sure that the reason they're not unloading is some
component of mine that's holding a retain on the bundle.
So, my questions are as follows:-
* Should hosts *ever* attempt to unload plug-in
bundles on 64-bit Mac OS X?
* If *YES*, does this imply that all ObjC classes in plug-ins MUST
be runtime synthesized with unique names per module-load? (to solve
potential reload-at-different-address class registration bugs)
* If *NO*, does this imply that plug-ins should be extremely frugal
with load-time "module lifetime scope" static initialization /
uninitialization (bearing in mind the modules will be kicking around
in memory much longer than any active instance of the plug-in)?
FWIW, we have until now used module lifetime scope to init/uninit a
bunch of stuff (mostly fairly lightweight objects like logs and
timers, but still), if plug-in bundles should be assumed to stay in
memory forever (which rather sounds like a memleak to me,
actually...) once loaded, we need to be much more frugal with that
stuff & not assume our unload-time uninitialization routines
will ever be called (at quit, Cocoa apps seem to like to terminate()
without a symmetric cleanup of the underlying C/C++ runtime). We
want to synthesize our Cocoa class names at compile time, not run
time, as building everything from scratch "C" code at runtime means
we lose a lot of the niceties of ObjC.
Thanks & best regards,
Angus.
|