git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26184
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
wxRasThreadData()
{
hWnd = 0;
wxRasThreadData()
{
hWnd = 0;
- hEventRas = hEventQuit = INVALID_HANDLE_VALUE;
+ hEventRas =
+ hEventQuit = 0;
+ ~wxRasThreadData()
+ {
+ if ( hWnd )
+ DestroyWindow(hWnd);
+
+ if ( hEventQuit )
+ CloseHandle(hEventQuit);
+
+ if ( hEventRas )
+ CloseHandle(hEventRas);
+ }
+
HWND hWnd; // window to send notifications to
HWND hWnd; // window to send notifications to
- HANDLE hEventRas, // event which RAS signals when status changes
- hEventQuit; // event which we signal when we terminate
+ HANDLE hEventRas, // automatic event which RAS signals when status changes
+ hEventQuit; // manual event which we signal when we terminate
class WXDLLEXPORT wxDialUpManagerMSW *dialUpManager; // the owner
};
class WXDLLEXPORT wxDialUpManagerMSW *dialUpManager; // the owner
};
// data used by this thread and our hidden window to send messages between
// each other
// data used by this thread and our hidden window to send messages between
// each other
- wxRasThreadData m_data;
+ wxRasThreadData *m_data;
// the handle of rasapi32.dll when it's loaded
wxDynamicLibrary m_dllRas;
// the handle of rasapi32.dll when it's loaded
wxDynamicLibrary m_dllRas;
// initialize our data
m_autoCheckLevel = 0;
m_hThread = 0;
// initialize our data
m_autoCheckLevel = 0;
m_hThread = 0;
+ m_data = new wxRasThreadData;
if ( !m_dllRas.IsLoaded() )
{
if ( !m_dllRas.IsLoaded() )
{
- if ( !SetEvent(m_data.hEventQuit) )
+ if ( !SetEvent(m_data->hEventQuit) )
{
wxLogLastError(_T("SetEvent(RasThreadQuit)"));
}
{
wxLogLastError(_T("SetEvent(RasThreadQuit)"));
}
+ else // sent quit request to the background thread
+ {
+ // the thread still needs m_data so we can't free it here, rather
+ // let the thread do it itself
+ m_data = NULL;
+ }
CloseHandle(m_hThread);
m_hThread = 0;
}
CloseHandle(m_hThread);
m_hThread = 0;
}
- if ( m_data.hWnd )
- {
- DestroyWindow(m_data.hWnd);
-
- m_data.hWnd = 0;
- }
-
- if ( m_data.hEventQuit )
- {
- CloseHandle(m_data.hEventQuit);
-
- m_data.hEventQuit = 0;
- }
-
- if ( m_data.hEventRas )
- CloseHandle(m_data.hEventRas);
-
- m_data.hEventRas = 0;
+ delete m_data;
+ m_data = NULL;
if ( ok )
{
// first create an event to wait on
if ( ok )
{
// first create an event to wait on
- m_data.hEventRas = CreateEvent
- (
+ m_data->hEventRas = CreateEvent
+ (
NULL, // security attribute (default)
NULL, // security attribute (default)
- FALSE, // manual reset (not)
+ FALSE, // manual reset (no, it is automatic)
FALSE, // initial state (not signaled)
NULL // name (no)
FALSE, // initial state (not signaled)
NULL // name (no)
- );
- if ( !m_data.hEventRas )
+ );
+ if ( !m_data->hEventRas )
{
wxLogLastError(wxT("CreateEvent(RasStatus)"));
{
wxLogLastError(wxT("CreateEvent(RasStatus)"));
- // create the event we use to quit the thread
- m_data.hEventQuit = CreateEvent(NULL, FALSE, FALSE, NULL);
- if ( !m_data.hEventQuit )
+ // create the event we use to quit the thread: using a manual event
+ // here avoids problems with missing the event if wxDialUpManagerMSW
+ // is created and destroyed immediately, before wxRasStatusWindowProc
+ // starts waiting on the event
+ m_data->hEventQuit = CreateEvent
+ (
+ NULL, // default security
+ TRUE, // manual event
+ FALSE, // initially non signalled
+ NULL // nameless
+ );
+ if ( !m_data->hEventQuit )
{
wxLogLastError(wxT("CreateEvent(RasThreadQuit)"));
{
wxLogLastError(wxT("CreateEvent(RasThreadQuit)"));
wxSetWindowProc(ms_hwndRas, wxRasStatusWindowProc);
}
wxSetWindowProc(ms_hwndRas, wxRasStatusWindowProc);
}
- m_data.hWnd = ms_hwndRas;
+ m_data->hWnd = ms_hwndRas;
if ( ok )
{
// start the secondary thread
if ( ok )
{
// start the secondary thread
- m_data.dialUpManager = this;
+ m_data->dialUpManager = this;
DWORD tid;
m_hThread = CreateThread
DWORD tid;
m_hThread = CreateThread
NULL,
0,
(LPTHREAD_START_ROUTINE)wxRasMonitorThread,
NULL,
0,
(LPTHREAD_START_ROUTINE)wxRasMonitorThread,
DWORD dwRet = ms_pfnRasConnectionNotification
(
(HRASCONN)INVALID_HANDLE_VALUE,
DWORD dwRet = ms_pfnRasConnectionNotification
(
(HRASCONN)INVALID_HANDLE_VALUE,
3 /* RASCN_Connection | RASCN_Disconnection */
);
3 /* RASCN_Connection | RASCN_Disconnection */
);
+ default:
+ wxFAIL_MSG( _T("unexpected return of WaitForMultipleObjects()") );
+ // fall through
+
- wxLogLastError(wxT("WaitForMultipleObjects(RasMonitor)"));
- break;
+#ifdef __WXDEBUG__
+ // using wxLogLastError() from here is dangerous: we risk to
+ // deadlock the main thread if wxLog sends output to GUI
+ DWORD err = GetLastError();
+ wxMessageOutputDebug().Printf
+ (
+ wxT("WaitForMultipleObjects(RasMonitor) failed: 0x%08lx (%s)"),
+ err,
+ wxSysErrorMsg(err)
+ );
+#endif // __WXDEBUG__
+
+ // no sense in continuing, who knows if the handles we're
+ // waiting for even exist yet...
+ return (DWORD)-1;
+ // we don't need it any more now and if this thread ran, it is our
+ // responsability to free the data
+ delete data;
+