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
