Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Why isn't the DLL dialog modal by default ?

0 views
Skip to first unread message

Jsmart

unread,
Apr 28, 2006, 5:57:49 PM4/28/06
to
Thanks for screwing up my dialup access. Aaaaagh. DO NOT SEND ATTACHMENTS TO
THIS LIST!


________________________________________________
Message sent using UebiMiau 2.7.2


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-u...@lists.wxwidgets.org
For additional commands, e-mail: wx-use...@lists.wxwidgets.org

Iulian-Nicu Serbanoiu

unread,
Apr 30, 2006, 11:07:08 AM4/30/06
to
In wx 2.6.3 src/comon/utilscmn.cpp

the class is wxWindowDisabler.

In the constructor (wxWindowDisabler::wxWindowDisabler) it is clearly shown
that windows that are disabled are *only* from the list of the current
instance. So
when ShowModal is called, a wxWindowDisabler is initialized to disable
the parent
window in order to make things look modal (yes !! ShowModal it is not
using the native
win32 functions to display a modal dialog ) But if the parent is in the
application
instance while the dialog displayed is in the DLL instance the parent
will not apear
as one of the windows in instance containing the dialog therefore will
not be disabled.

This is the explanation for wxMSW.

In wxGTK I haven't been able to make this thing work ( I mean I _did_
manage to
show a dialog from a shared object but when calling the wxUninitialize
function the program
just remained stucked. Also not calling wxUninitialize would have the
same result
at program exit )

running the program with strace showed that it stucked in a fmutex call
( futex(0x811ea18, FUTEX_WAIT, 2, NULL --- is the last line of the trace )

Further testing of mine showed that wxModule::CleanupModules function is
responsible for this "dead lock".

My guess is that in windows the DLL instance is somehow separate from the
WinMain instance and this is why it works but in linux could it be that
some objects
are shared between the main instance and the shared object instance ? [
it is just a guess ]

Is this intended to make work ( making wx forms libraries ) ?
[not necessary in the 2.6 branch.]

Is anyone else interested in this matter ?

Thanks,

Iulian

Vadim Zeitlin

unread,
May 2, 2006, 7:47:39 PM5/2/06
to
On Sun, 30 Apr 2006 18:07:08 +0300 Iulian-Nicu Serbanoiu <under...@gmail.com> wrote:

INS> In the constructor (wxWindowDisabler::wxWindowDisabler) it is clearly shown
INS> that windows that are disabled are only from the list of the current
INS> instance. So when ShowModal is called, a wxWindowDisabler is
INS> initialized to disable the parent window in order to make things look
INS> modal (yes !! ShowModal it is not using the native win32 functions to
INS> display a modal dialog )

Because they only work with dialog templates and creating one on the fly
is too much trouble.

INS> running the program with strace showed that it stucked in a fmutex call
INS> ( futex(0x811ea18, FUTEX_WAIT, 2, NULL --- is the last line of the trace )

What are the previous ones?

INS> Further testing of mine showed that wxModule::CleanupModules function is
INS> responsible for this "dead lock".

For a dead lock to happen there must be another mutex, which one is it?

INS> My guess is that in windows the DLL instance is somehow separate from
INS> the WinMain instance and this is why it works but in linux could it be
INS> that some objects are shared between the main instance and the shared
INS> object instance ? [ it is just a guess ]

I can't confirm nor deny it because I don't understand it at all
unfortunately.

INS> Is this intended to make work ( making wx forms libraries ) ?

Yes, this should work.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Iulian-Nicu Serbanoiu

unread,
May 3, 2006, 1:38:13 AM5/3/06
to
Vadim Zeitlin wrote:
> On Sun, 30 Apr 2006 18:07:08 +0300 Iulian-Nicu Serbanoiu <under...@gmail.com> wrote:
>
> INS> In the constructor (wxWindowDisabler::wxWindowDisabler) it is clearly shown
> INS> that windows that are disabled are only from the list of the current
> INS> instance. So when ShowModal is called, a wxWindowDisabler is
> INS> initialized to disable the parent window in order to make things look
> INS> modal (yes !! ShowModal it is not using the native win32 functions to
> INS> display a modal dialog )
>
> Because they only work with dialog templates and creating one on the fly
> is too much trouble.
>
I think the disabler class *should* add a wxWindow in the disable list
even if it is
*not* in the list of the current instance ( this way keeping a modal
behaviour between
the main instance - WinMain, and a DLL instance for example - thing not
done in case
of wxMSW )
{ Talking about calling the native methods in case of ShowModal ... it makes
no importance to me for the moment ... it was just a thing I've noticed )

> INS> running the program with strace showed that it stucked in a fmutex call
> INS> ( futex(0x811ea18, FUTEX_WAIT, 2, NULL --- is the last line of the trace )
>
> What are the previous ones?
>
many ( many !) read calls and before them many ioctl write and poll calls
interlaced

> INS> Further testing of mine showed that wxModule::CleanupModules function is
> INS> responsible for this "dead lock".
>
> For a dead lock to happen there must be another mutex, which one is it?
>
haven't got the time for the moment to find out. just called the function
as it was called by the wxUninitialize method and saw it was blocking
{ when I saw it was blocking I began studying the wxUninitialize calls
in order
to split it for identifying the place were the dead lock appears - this
is what
I have done to find out that wxModule::CleanupModules is the one blocking
on application exit }

> INS> My guess is that in windows the DLL instance is somehow separate from
> INS> the WinMain instance and this is why it works but in linux could it be
> INS> that some objects are shared between the main instance and the shared
> INS> object instance ? [ it is just a guess ]
>
> I can't confirm nor deny it because I don't understand it at all
> unfortunately.
>
>
to put it in another way. is there a possibility that some global variables
and functions ( not declared static !? ) could interfere between the main
instance and the shared object instance (unix) ? ( for example calling a
method
declared with extern in the main thread from the loaded shared object, could
return something from the main instance ... maybe a mutex that could cause
some dead locks ? - i repeat this is just a guess ... haven't got the
time to
test how things work with shared libraries in unix - I just know how to use
them in an usual way ... yet )

> INS> Is this intended to make work ( making wx forms libraries ) ?
>
> Yes, this should work.
>
That's very good news. But considering that there is no linux/unix example
on how to do it ( only a wxMSW example exists - google for wxDLL.zip )
don't you
find it a little odd ? Of course if someone could show me some example
that has
this functionality implemented ( without the deadlock ) I would be very
glad.
> Regards,
> VZ
>

One thought though: wouldn't it be better to group all global variables
around a single
one ( for example the wxApp based class ) and still keep some macros to
access the
previous global members ? {This is the way that flex 2.5.33 has made the
lexical
analizer reentrant "flex '-R' option" - it is very easy to check out the
resulted source }

Thanks,

Iulian

Iulian-Nicu Serbanoiu

unread,
May 4, 2006, 1:43:23 AM5/4/06
to
Vadim Zeitlin wrote:
> INS> Further testing of mine showed that wxModule::CleanupModules function is
> INS> responsible for this "dead lock".
>
> For a dead lock to happen there must be another mutex, which one is it?
>
>
This deadlock happens after this line is printed
( i thing is one of the global mutexes but haven't got the time
to test this very much --- I will come up with info )

"wxThreadModule->CleanupModules()"

I've added some printfs in wxModule::CleanupModules()

// now it looks like this [ src/common/module.cpp ]

void wxModule::CleanUpModules()
{
// Cleanup user-defined modules
wxModuleList::compatibility_iterator node;
for ( node = m_modules.GetFirst(); node; node = node->GetNext() )
{

******************

printf("%s->CleanupModules()\n",node->GetData()->GetClassInfo()->GetClassName());
*******************
fflush(stdout);
node->GetData()->Exit();
}

WX_CLEAR_LIST(wxModuleList, m_modules);
}


Also another bad thing is the wxTheApp macro. When calling wxTheApp
macro from the
shared object I get the wxApp from the main instance. Don't know why but
this is not good ....

how do I know that ? because if I call wxTheApp->CallOnInit() another
main window apears:

here is some code:

class wxDLLApp : public wxApp
{
bool OnInit();
};

IMPLEMENT_APP_NO_MAIN(wxDLLApp)

bool wxDLLApp::OnInit()
{
printf("Just returned true\n");
return true;
}

// THIS FUNCTION IS CALLED AT LIBRARY LOAD ... SEE BELOW
int wx_initialize(void)
{
if( !wxInitialize() )
{
return 1;
}

// wxTheApp is the pointer to the application class

/**********************************************
If I uncomment the call to CallOnInit ... the main window will apear
again ....
this proves that the object returned by wxTheApp is the one from the
main instance.
***************************************************/
if ( !wxTheApp /*|| !wxTheApp->CallOnInit()*/ )
{
printf("Failure\n");
wxUninitialize();
return 1;
}
printf("I initialized the stuff\n");
return 0;
}

void wx_uninitialize(void)
{
//wxTheApp->OnExit();
wxUninitialize();
printf("I uninitialized the stuff\n");
}


#ifdef __cplusplus
extern "C" {
#endif

void __attribute__((constructor)) init_lib(void)
{
printf("------- LIB: init\n");
wx_initialize();
printf("LIB: init -------\n");
}

void __attribute__((destructor)) uninit_lib(void)
{
printf("------- LIB: uninit\n");
wx_uninitialize();
printf("LIB: uninit -------\n");
}

#ifdef __cplusplus
}
#endif


So this proves that somehow the unix(linux) shared object instance is
somehow more
attached to the instance that loads it ?! ( in my opinion it does )

I will do further testing and come up with more results.

* if you need extra info please let me know and I'll test it when I have
the time *

1. Is this a bug ? ( wxTheApp is not returning the wxApp based class
created in the shared object, but the one in the loader of the shared
object{main instance} )

2. If it is a bug, how is possible to repair this bug ? workarounds,
tricks are welcomed !

3. About the deadlock presented first in this mail. I will try to be
more specific

4. If someone else will test my code it will be good to know if this is
hapening on other
(unix-like) platforms too.


Thanks,

Iulian

Iulian-Nicu Serbanoiu

unread,
May 4, 2006, 5:24:33 PM5/4/06
to
Vadim Zeitlin wrote:
> INS> Further testing of mine showed that wxModule::CleanupModules function is
> INS> responsible for this "dead lock".
>
> For a dead lock to happen there must be another mutex, which one is it?
>
This is the modified source [src/unix/threadpsx.cpp]

void wxThreadModule::OnExit()
{
wxASSERT_MSG( wxThread::IsMain(), wxT("only main thread can be here") );
//printf("Hello !!! I'm wxThreadModule::OnExit\n");fflush(stdout);
// are there any threads left which are being deleted right now?
size_t nThreadsBeingDeleted;

{
printf("1 - Hello !!! I'm wxThreadModule::OnExit\n"); *********
printf("Pointer value:
%d\n",gs_mutexDeleteThread);fflush(stdout); **********
wxMutexLocker lock( *gs_mutexDeleteThread );

printf("2 - Hello !!! I'm
wxThreadModule::OnExit\n");fflush(stdout); ***********
nThreadsBeingDeleted = gs_nThreadsBeingDeleted;

........................
And the output when unloading the library after showing the dialog. It
is very
confusing ( it is called somehow twice for each module ):

------- LIB: uninit
wxHelpProviderModule->CleanupModules()
wxPrintFactoryModule->CleanupModules()
wxWinModule->CleanupModules()
wxPluginLibraryModule->CleanupModules()
wxFileIconsTableModule->CleanupModules()
wxImageModule->CleanupModules()
wxGenericRendererModule->CleanupModules()
wxArtGtkModule->CleanupModules()
wxLocaleModule->CleanupModules()
wxThreadModule->CleanupModules()
1 - Hello !!! I'm wxThreadModule::OnExit
Pointer value: 135240176
2 - Hello !!! I'm wxThreadModule::OnExit
wxDateTimeHolidaysModule->CleanupModules()
wxClipboardModule->CleanupModules()
wxBitmapBaseModule->CleanupModules()
wxFontMapperModule->CleanupModules()
wxFileSystemModule->CleanupModules()
wxPrintPaperModule->CleanupModules()
wxMimeTypeCmnModule->CleanupModules()
wxDCModule->CleanupModules()
wxArtProviderModule->CleanupModules()

wxHelpProviderModule->CleanupModules()
wxPrintFactoryModule->CleanupModules()
wxWinModule->CleanupModules()
wxPluginLibraryModule->CleanupModules()
wxFileIconsTableModule->CleanupModules()
wxImageModule->CleanupModules()
wxGenericRendererModule->CleanupModules()
wxArtGtkModule->CleanupModules()
wxLocaleModule->CleanupModules()
wxThreadModule->CleanupModules()
1 - Hello !!! I'm wxThreadModule::OnExit
Pointer value: 135240176
( !!! HERE IS WHERE IT HANGS - it is the same pointer value ... !!! )


I don't know really know how to explain this.
Why is the cleanup procedure called twice ?
Why does the pointer have the same value.

At cleanup the only procedure called is:
.................

void wx_uninitialize(void)
{
//wxTheApp->OnExit();
wxUninitialize();
printf("I uninitialized the stuff\n");
}

.................

void __attribute__((destructor)) uninit_lib(void)
{
printf("------- LIB: uninit\n");
wx_uninitialize();
printf("LIB: uninit -------\n");
}

Any explanation would be good ... in order to see if there is any point
going on.

I remember you I'm using wxGTK 2.6.3 ( default configuration [just
./configure] )

Thanks,

Iulian

0 new messages