On 23.09.2010, at 01:01, Andy Fillebrown wrote:
> 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 ...

Thanks for clarification.

[stripped a lot of interesting stuff]

I'll comment only some specific facts and add questions.

> When Csound cleans up, it unloads all its plugins, which in turn unloads the 
> FLTK library.

okay, that's about that what I thought, but I didn't know that CSound
or its plugins are doing this. A quick look at the website didn't
show FLTK dependencies, but maybe it's somewhere...

> 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.

Yep, that's clear.

> 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.

Isn't it the other way around?


http://msdn.microsoft.com/en-us/library/ms690134%28VS.85%29.aspx

OleInitialize:

"Initializes the COM library on the current apartment, identifies
the concurrency model as single-thread apartment (STA), and enables
additional functionality described in the Remarks section below.
[...]
OleInitialize calls CoInitializeEx internally to initialize the
COM library on the current apartment. Because OLE operations are
not thread-safe, OleInitialize  specifies the concurrency model
as single-thread apartment."


http://msdn.microsoft.com/en-us/library/ms678543%28v=VS.85%29.aspx

CoInitialize:

"Initializes the COM library on the current thread and identifies
the concurrency model as single-thread apartment (STA)."

This made me think that we can (or should) always call
OleInitialize (but only *once*) and call OleUninitialize
at exit only if we called OleInitialize before. This should
work, shouldn't it?

(Note that I don't know anything about this OLE stuff other
than hearing about it and now reading the docs...).

> There are some threading implications, too.

As Ian wrote, FLTK doesn't use threads on its own purpose,
so we should be safe here.

> 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.

Yep, but if I'm reading the MS docs correctly (see above),
s/CoInitialize/OleInitialize/ etc.

> 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.

So we should be fine if we call both exactly once or
not at all.

Albrecht
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to