I've got a dll that uses some features of wxWidgets. For example
threads. Inside the dll no need to use any GUI functions, so I simply
use wxInitialize/Uninitialize, in order to be able of starting threads.
Under Linux everything works, both if I link the dll(.so) against a
wxWidgets GUI application and a generic application.
Under Windows, if I link the dll against a GUI application not based on
wxWidgets (for example a MFC one) threads
remain on an infinite loop inside the wxThread::Wait()..
I've inspected the code (wx 2.6.3 and 2.7.2, the following parts are
exactly the same in both version).
first, the wxInitialize creates an application object of class
wxConsoleApp
the wxThread::Wait() executes the following peace of code
do
{ [...]
result = ::MsgWaitForMultipleObjects
(
1, // number of objects to wait for
&m_hThread, // the objects
false, // don't wait for all objects
INFINITE, // no timeout
QS_ALLINPUT|QS_ALLPOSTMESSAGE // return as soon as
there are any events
);
switch ( result )
{
case 0xFFFFFFFF:
// error [...]
case WAIT_OBJECT_0:
// thread we're waiting for terminated
break;
case WAIT_OBJECT_0 + 1:
// [...]
if ( wxThread::IsMain() )
{
// it looks that sometimes WAIT_OBJECT_0 + 1 is
// returned but there are no messages in the thread
// queue -- prevent DoMessageFromThreadWait() from
// blocking inside ::GetMessage() forever in this
case
::PostMessage(NULL, WM_NULL, 0, 0);
wxAppTraits *traits = wxTheApp ?
wxTheApp->GetTraits()
: NULL;
if ( traits && !traits->DoMessageFromThreadWait() )
{
// WM_QUIT received: kill the thread
Kill();
return wxTHREAD_KILLED;
}
}
break;
default:
wxFAIL_MSG(wxT("unexpected result of
MsgWaitForMultipleObject"));
}
} while ( result != WAIT_OBJECT_0 );
The problem is that, in the case of a wxConsoleApp, the
DoMessageFromThreadWait() DOES NOTHING, so the thread
continues to return from the MsgWaitForMultipleObjects with code
WAIT_OBJECT_0 + 1 (because the application that links with my dll is a
GUI one that receives messages, but DoMessageFromThreadWait does not
process them)
Any suggestions?? Maybe there's a better way to Initialize/Uninitialize
wxWidgets inside a dll that solves it (remember that under Linux
everything works)... but, apart from this, I don't think it's very
sensible to wait for messages that will not be processed, so, for
example I would modify the wx code as follow
test if it is a wxConsoleApp;
if it is
result = ::MsgWaitForMultipleObjects
(
1, // number of objects to wait for
&m_hThread, // the objects
false, // don't wait for all objects
INFINITE, // no timeout
0;
);
else
result = ::MsgWaitForMultipleObjects
(
1, // number of objects to wait for
&m_hThread, // the objects
false, // don't wait for all objects
INFINITE, // no timeout
QS_ALLINPUT|QS_ALLPOSTMESSAGE // return as soon as
there are any events
);
Comments???? Thanks.
MARCO GUBERNATI
http://www.erxa.it
------------------------------------------------------------------------
-------
|E______| ERXA srl ISO 9001 certified
|__R____| C.so Svizzera, 185 - 10149 TORINO - ITALY
|____X__| Tel.: +39 - 011 741 27 49
|______A| Fax: +39 - 011 741 20 44
========================================================================
==
Questa mail e gli eventuali attachments possono contenere informazioni
confidenziali e riservate e non soggette a divulgazione ai sensi di
legge e sono da considerarsi dirette esclusivamente ai destinatari
indicati. E' fatto divieto a chiunque altro di leggere, copiare,
diffondere o utilizzare in qualsivoglia maniera tali informazioni. Se
avete ricevuto questo messaggio per errore, siete pregati di cancellarlo
e di avvisarne il mittente.
========================================================================
===
This message and its attachments (if any) may contain confidential,
proprietary or legally privileged information and is intended only for
the use of the addressee named above. No confidentially or privilege is
waived or lost by any mistranmission.
If you are not the intended recipient of this message you are hereby
notified that you must noy use, disseminate, copy it in any form or take
any action in reliance on it. If you have received this message in error
please delete it and any copies of it and kindly inform the sender of
this e-mail by replying or go to www.erxa.it "contact us".
---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-u...@lists.wxwidgets.org
For additional commands, e-mail: wx-use...@lists.wxwidgets.org
I've written a simple class which simulates joinable threads using
detached threads and wxCondition. See
http://filezilla-project.org/codesquid/threadex.tar.bz2
Tim
tim....@gmx.de (Tim Kosse) wrote in news:elgl66$59s$1...@sea.gmane.org:
> I encountered the same problem, though in a GUI application. From a
> function called Wait, I expected true waiting semantics, while
> wxThread::Wait can do other stuff like processing the message loop.
>
> I've written a simple class which simulates joinable threads using
> detached threads and wxCondition. See
> http://filezilla-project.org/codesquid/threadex.tar.bz2
You don't acquire the mutex for the condition variable until you Wait() for
the thread. That means you can miss signals if the thread exits before you
Wait(). You need to acquire the mutex before the thread is started. This
insures that the signal won't be sent until the launching thread is ready
to receive it.
----- Original Message -----From: Iulian-Nicu SerbanoiuSent: Tuesday, January 16, 2007 8:49 AMSubject: Re: Problems with wxThread::Wait in a dll under windows
Kenneth Porter <shiva.b...@sewingwitch.com> wrote in
news:Xns98B99B612F3FCs...@216.196.97.142:
tim....@gmx.de (Tim Kosse) wrote:
> I don't see any problem with my code. If the thread finishes before
> wxThreadEx::Wait() gets called, m_finished gets set to true.
> If wxThreadEx::Wait() gets called then, it doesn't wait on the condition.
Ah, I stand corrected. You use the m_finished member as a saved signal and
it's protected by the condition's mutex.