#pragma hdrstop
#endif
-// these functions require Win32
-#if defined(__WIN16__) && wxUSE_DIALUP_MANAGER
- #undef wxUSE_DIALUP_MANAGER
- #define wxUSE_DIALUP_MANAGER 0
-#endif // wxUSE_DIALUP_MANAGER && Win16
-
#if wxUSE_DIALUP_MANAGER
#ifndef WX_PRECOMP
#if (!defined(__BORLANDC__) || (__BORLANDC__>=0x550)) && \
(!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION(0, 5)) && \
!defined(__GNUWIN32_OLD__) && \
- !defined(__WATCOMC__) && \
!defined(__WINE__) && \
(!defined(__VISUALC__) || (__VISUALC__ >= 1020))
wxRasThreadData()
{
hWnd = 0;
- hEventRas = hEventQuit = INVALID_HANDLE_VALUE;
+ hEventRas =
+ hEventQuit = 0;
dialUpManager = NULL;
}
+ ~wxRasThreadData()
+ {
+ if ( hWnd )
+ DestroyWindow(hWnd);
+
+ if ( hEventQuit )
+ CloseHandle(hEventQuit);
+
+ if ( hEventRas )
+ CloseHandle(hEventRas);
+ }
+
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
};
// 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;
// initialize our data
m_autoCheckLevel = 0;
m_hThread = 0;
+ m_data = new wxRasThreadData;
if ( !m_dllRas.IsLoaded() )
{
{
if ( m_hThread )
{
- if ( !SetEvent(m_data.hEventQuit) )
+ if ( !SetEvent(m_data->hEventQuit) )
{
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;
}
- if ( m_data.hWnd )
+ if ( m_data )
{
- 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
- m_data.hEventRas = CreateEvent
- (
+ m_data->hEventRas = CreateEvent
+ (
NULL, // security attribute (default)
- FALSE, // manual reset (not)
+ FALSE, // manual reset (no, it is automatic)
FALSE, // initial state (not signaled)
NULL // name (no)
- );
- if ( !m_data.hEventRas )
+ );
+ if ( !m_data->hEventRas )
{
wxLogLastError(wxT("CreateEvent(RasStatus)"));
if ( ok )
{
- // 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)"));
wxSetWindowProc(ms_hwndRas, wxRasStatusWindowProc);
}
- m_data.hWnd = ms_hwndRas;
+ m_data->hWnd = ms_hwndRas;
if ( ok )
{
// start the secondary thread
- m_data.dialUpManager = this;
+ m_data->dialUpManager = this;
DWORD tid;
m_hThread = CreateThread
NULL,
0,
(LPTHREAD_START_ROUTINE)wxRasMonitorThread,
- (void *)&m_data,
+ (void *)m_data,
0,
&tid
);
DWORD dwRet = ms_pfnRasConnectionNotification
(
(HRASCONN)INVALID_HANDLE_VALUE,
- m_data.hEventRas,
+ m_data->hEventRas,
3 /* RASCN_Connection | RASCN_Disconnection */
);
cont = FALSE;
break;
+ default:
+ wxFAIL_MSG( _T("unexpected return of WaitForMultipleObjects()") );
+ // fall through
+
case WAIT_FAILED:
- 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;
+
return 0;
}