// (C) 1999-2000, Guillermo Rodriguez Garcia
// (C) 2008 Vadim Zeitlin
// RCS_ID: $Id$
-// License: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/private/socket.h"
#include "wx/msw/private.h" // for wxGetInstance()
+#include "wx/private/fd.h"
#include "wx/apptrait.h"
#include "wx/thread.h"
#include "wx/dynlib.h"
+#include "wx/link.h"
#ifdef __WXWINCE__
/*
# pragma warning(default:4115) /* named type definition in parentheses */
#endif
-#define CLASSNAME TEXT("_wxSocket_Internal_Window_Class")
+#include "wx/msw/private/hiddenwin.h"
-/* implemented in utils.cpp */
-extern "C" WXDLLIMPEXP_BASE HWND
-wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
+#define CLASSNAME TEXT("_wxSocket_Internal_Window_Class")
/* Maximum number of different wxSocket objects at a given time.
* This value can be modified at will, but it CANNOT be greater
#ifdef __WXWINCE__
/* This thread handles socket events on WinCE using WSAEventSelect() as
* WSAAsyncSelect is not supported. When an event occurs for the socket, it is
- * checked what kind of event happend and the correct message gets posted so
+ * checked what kind of event happened and the correct message gets posted so
* that the hidden window can handle it as it would in other MSW builds.
*/
DWORD WINAPI SocketThread(LPVOID data)
{
return new wxSocketImplMSW(wxsocket);
}
- virtual void Install_Callback(wxSocketImpl *socket, wxSocketNotify event);
- virtual void Uninstall_Callback(wxSocketImpl *socket, wxSocketNotify event);
+ virtual void Install_Callback(wxSocketImpl *socket,
+ wxSocketNotify event = wxSOCKET_LOST);
+ virtual void Uninstall_Callback(wxSocketImpl *socket,
+ wxSocketNotify event = wxSOCKET_LOST);
private:
static wxDynamicLibrary gs_wsock32dll;
// dependencies on it for all the application using wx even if they don't use
// sockets
#ifdef __WXWINCE__
- #define WINSOCK_DLL_NAME _T("ws2.dll")
+ #define WINSOCK_DLL_NAME wxT("ws2.dll")
#else
- #define WINSOCK_DLL_NAME _T("wsock32.dll")
+ #define WINSOCK_DLL_NAME wxT("wsock32.dll")
#endif
gs_wsock32dll.Load(WINSOCK_DLL_NAME, wxDL_VERBATIM | wxDL_QUIET);
if ( !socket )
return 0;
+ // the socket may be already closed but we could still receive
+ // notifications for it sent (asynchronously) before it got closed
+ if ( socket->m_fd == INVALID_SOCKET )
+ return 0;
+
wxASSERT_MSG( socket->m_fd == (SOCKET)wParam,
"mismatch between message and socket?" );
- switch WSAGETSELECTEVENT(lParam)
+ switch ( WSAGETSELECTEVENT(lParam) )
{
case FD_READ:
+ // We may get a FD_READ notification even when there is no data
+ // to read on the socket, in particular this happens on socket
+ // creation when we seem to always get FD_CONNECT, FD_WRITE and
+ // FD_READ notifications all at once (but it doesn't happen
+ // only then). Ignore such dummy notifications.
+ {
+ fd_set fds;
+ timeval tv = { 0, 0 };
+
+ wxFD_ZERO(&fds);
+ wxFD_SET(socket->m_fd, &fds);
+
+ if ( select(socket->m_fd + 1, &fds, NULL, NULL, &tv) != 1 )
+ return 0;
+ }
+
event = wxSOCKET_INPUT;
break;
* Disable event notifications (used when shutting down the socket)
*/
void wxSocketMSWManager::Uninstall_Callback(wxSocketImpl *socket_,
- wxSocketNotify WXUNUSED(event))
+ wxSocketNotify WXUNUSED(event))
{
wxSocketImplMSW * const socket = static_cast<wxSocketImplMSW *>(socket_);
}
} gs_managerSetter;
+// see the relative linker macro in socket.cpp
+wxFORCE_LINK_THIS_MODULE( mswsocket );
+
// ============================================================================
// wxSocketImpl implementation
// ============================================================================
-/* static */
-wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
-{
- return new wxSocketImplMSW(wxsocket);
-}
-
void wxSocketImplMSW::DoClose()
{
- wxSocketManager::Get()->
- Uninstall_Callback(this, wxSOCKET_MAX_EVENT /* unused anyhow */);
+ wxSocketManager::Get()->Uninstall_Callback(this);
closesocket(m_fd);
}