Hi Albrecht,
Yes, FLTK's call to OleUninitialize is happens during dll unloading. See
Fl.cxx @ line 493 and 498.
Csound does use FLTK windows, but only if the user tells it to.
I'll try and clarify ...
---
Csound has several plugins that get loaded when it compiles an input file. Two
of those plugins are implicitly linked to mgwfltknox-1.1.dll. When those two
plugins are loaded, the fltk library is loaded, too.
Whether Csound actually creates an FLTK window is up to the input file that is
compiled. There may be an FLTK window created, or there may not. Either way,
Csound will always load all of its plugins, including the two that load the
FLTK library.
When Csound cleans up, it unloads all its plugins, which in turn unloads the
FLTK library.
---
When the compiled input file tells Csound to create an FLTK window, everything
is fine. OleInitialize (or CoInitialize) gets called when the window is
created, and the corresponding OleUninitialize call doesn't cause any problems.
When the compiled input file doesn't tell Csound to create an FLTK window, the
OleUnitialize call causes problems since OleInitialize and CoInitialize were
never called by the FLTK library.
This is not a problem when using Csound on the command-line since nothing is
going on that requires OLE or COM. The OleUnitialize call fails quietly and
everything proceeds normally.
For applications that use Csound internally, though, the unbalanced
OleUnitialize call is a show-stopper if the app has called OleInitialize for
its own use. This is the case in both our Qt-based apps, but it could also
happen in any app that uses OLE/COM.
---
Here's the order of operations in our app...
1) Our app loads Qt's GUI library.
2) Qt's GUI library calls CoInitialize.
<user interacts with our app>
3) Our app uses Csound to compile an input file.
4) Csound loads its plugins.
5) FLTK library loads when Csound plugins load.
<user interacts with our app>
6) Our app tells Csound to cleanup.
7) Csound unloads its plugins.
8) The FLTK library unloads and calls OleUninitialize.
9) Our app becomes unstable.
Since no FLTK window was created, the FLTK library's call to OleUninitialize in
step #8 gets paired with Qt's call to CoInitialize in step #2.
---
CoInitialize and OleInitialize are not the same. CoInitialize calls
OleInitialize internally and does some extra COM stuff. Calls to CoInitialize
should be balanced with calls to CoUninitialize, and calls to OleInitialize
should be balanced with calls to OleUninitialize. Pairing CoInitialize with
OleUninitialize is not disastrous, but it leaves cleanup incomplete.
There are some threading implications, too. CoInitialize/CoUninitialize must
be called on each thread that uses COM. I would assume the same with
OleInitialize/OleUninitialize, but I don't know for sure.
I don't know a lot about FLTK, but if it creates threads that use OLE/COM, then
the COM or OLE init/uninit calls should be balanced within those individual
threads, not in the main thread. The FLTK library is definitely being loaded
and unloaded in our app's main thread, though. That much I do know =)
If FLTK is not using COM or OLE in separate threads then the fix is easy, like
you say. Call CoInitialize in the Fl_Win32_At_Exit constructor and set a flag
if initialization succeeded, then call CoUninitialize in the destructor instead
of OleUninitialize. Something like ...
#ifdef WIN32
class Fl_Win32_At_Exit {
public:
Fl_Win32_At_Exit() {
coinit_succeeded = SUCCEEDED(CoInitialize());
}
~Fl_Win32_At_Exit() {
fl_free_fonts(); // do some WIN32 cleanup
fl_cleanup_pens();
fl_brush_action(1);
fl_cleanup_dc_list();
if (coinit_succeeded) {
CoUninitialize();
}
}
BOOL coinit_succeeded;
};
static Fl_Win32_At_Exit win32_at_exit;
#endif
.. then remove all the other Ole/CoInitialize calls so you don't have to worry
about the flag being set incorrectly.
Also, be aware that Windows keeps a reference count on the number of
Ole/CoInitialize calls made in each thread. Each call should be balanced with
a call to Ole/CoUnitialize to run the reference count down to zero.
---
Do you know if FLTK is using OLE/COM in separate threads?
Cheers,
~ andy.f
> On 21.09.2010, at 14:25, Andy Fillebrown wrote:
>
> > In the 1.3 branch's Fl.cxx @ line 493 there is a call to OleUninitialize
> > that is causing problems in Qt based apps that use Csound.
> >
> > In the process of loading and compiling Csound input files, the dynamic
> > FLTK libraries are sometimes loaded and unloaded without any FLTK windows
> > being created, so OleInitialize (or CoInitialize) never gets called. This
> > does not stop FLTK from calling OleUninitialize in the Fl_Win32_At_Exit
> > destructor, though, which means the OleUninitialize call gets paired to
> > Qt's OleInitialize call instead of FLTK's. The immediate result is that
> > the Qt app can no longer set data on the system clipboard after running
> > Csound. The app also becomes unstable and crashes when alt-tabbing back
> > and forth to another window.
> >
> > Is there a way to work around this issue? Should I post a bug report?
>
> Hmm, I think I understood the problem, and it's probably
> possible to fix it - but that needs some more investigation
> (there's a flag that should show the initialization state,
> but there's also at least one place in the code that doesn't
> set the flag...).
>
> That said, I'm curious to understand completely what you're
> saying about the environment where this happens:
>
> - there's a Qt based app
> - that uses Csound
> - and loads the dynamic FLTK libraries
> - w/o opening any (FLTK) window.
>
> What does it do with the FLTK libraries? Does it only use
> some functions?
>
> Is this specific to *your* app, or does Csound (or Qt ???)
> use FLTK's library? I'm puzzled...
>
> And, BTW, what's the difference between OleInitialize and
> CoInitialize? Can they be interchanged? FLTK code uses
> both, and I'm wondering why... Should we maybe replace
> CoInitialize with OleInitialize - setting the flag to
> know about initialization properly and using this to call
> OleUninitialize in the mentioned d'tor (if I understand
> it correctly, this would be called at dll unloading,
> right?).
>
> Albrecht
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev