do not require a running event loop, even under MSW, for the sockets to work: if the user code doesn't use events there is no reason for it to run the event loop, especially as it's not needed under the other platforms; instead use the same Select() implementation as under Unix under MSW too and, to avoid duplicating it, put it into the new GSocketBase class
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56923 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -154,6 +154,50 @@ private:
|
|||||||
static GSocketManager *ms_manager;
|
static GSocketManager *ms_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Base class providing functionality common to BSD and Winsock sockets.
|
||||||
|
|
||||||
|
TODO: merge this in wxSocket itself, there is no reason to maintain the
|
||||||
|
separation between wxSocket and GSocket.
|
||||||
|
*/
|
||||||
|
class GSocketBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GSocketEventFlags Select(GSocketEventFlags flags);
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
SOCKET m_fd;
|
||||||
|
#else
|
||||||
|
int m_fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool m_ok;
|
||||||
|
int m_initialRecvBufferSize;
|
||||||
|
int m_initialSendBufferSize;
|
||||||
|
|
||||||
|
GAddress *m_local;
|
||||||
|
GAddress *m_peer;
|
||||||
|
GSocketError m_error;
|
||||||
|
|
||||||
|
bool m_non_blocking;
|
||||||
|
bool m_server;
|
||||||
|
bool m_stream;
|
||||||
|
bool m_establishing;
|
||||||
|
bool m_reusable;
|
||||||
|
bool m_broadcast;
|
||||||
|
bool m_dobind;
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
struct timeval m_timeout;
|
||||||
|
#else
|
||||||
|
unsigned long m_timeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GSocketEventFlags m_detected;
|
||||||
|
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
|
||||||
|
char *m_data[GSOCK_MAX_EVENT];
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
#include "wx/msw/gsockmsw.h"
|
#include "wx/msw/gsockmsw.h"
|
||||||
#else
|
#else
|
||||||
@@ -246,6 +290,50 @@ GSocketError _GAddress_Init_UNIX(GAddress *address);
|
|||||||
GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
|
GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
|
||||||
GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
|
GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
|
||||||
|
|
||||||
|
// standard linux headers produce many warnings when used with icc
|
||||||
|
#if defined(__INTELC__) && defined(__LINUX__)
|
||||||
|
inline void wxFD_ZERO(fd_set *fds)
|
||||||
|
{
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:593)
|
||||||
|
FD_ZERO(fds);
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void wxFD_SET(int fd, fd_set *fds)
|
||||||
|
{
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#pragma warning(disable:1469)
|
||||||
|
FD_SET(fd, fds);
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool wxFD_ISSET(int fd, fd_set *fds)
|
||||||
|
{
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#pragma warning(disable:1469)
|
||||||
|
return FD_ISSET(fd, fds);
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
inline bool wxFD_CLR(int fd, fd_set *fds)
|
||||||
|
{
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#pragma warning(disable:1469)
|
||||||
|
return FD_CLR(fd, fds);
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
#else // !__INTELC__
|
||||||
|
#define wxFD_ZERO(fds) FD_ZERO(fds)
|
||||||
|
#define wxFD_SET(fd, fds) FD_SET(fd, fds)
|
||||||
|
#define wxFD_ISSET(fd, fds) FD_ISSET(fd, fds)
|
||||||
|
#define wxFD_CLR(fd, fds) FD_CLR(fd, fds)
|
||||||
|
#endif // __INTELC__/!__INTELC__
|
||||||
|
|
||||||
|
// this is for Windows where configure doesn't define this
|
||||||
|
#ifndef SOCKOPTLEN_T
|
||||||
|
#define SOCKOPTLEN_T int
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* wxUSE_SOCKETS */
|
#endif /* wxUSE_SOCKETS */
|
||||||
|
|
||||||
#endif /* _WX_GSOCKET_H_ */
|
#endif /* _WX_GSOCKET_H_ */
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Definition of GSocket */
|
/* Definition of GSocket */
|
||||||
class GSocket
|
class GSocket : public GSocketBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GSocket();
|
GSocket();
|
||||||
@@ -47,7 +47,6 @@ public:
|
|||||||
GSocketError SetNonOriented();
|
GSocketError SetNonOriented();
|
||||||
int Read(char *buffer, int size);
|
int Read(char *buffer, int size);
|
||||||
int Write(const char *buffer, int size);
|
int Write(const char *buffer, int size);
|
||||||
GSocketEventFlags Select(GSocketEventFlags flags);
|
|
||||||
void SetNonBlocking(bool non_block);
|
void SetNonBlocking(bool non_block);
|
||||||
void SetTimeout(unsigned long millis);
|
void SetTimeout(unsigned long millis);
|
||||||
GSocketError WXDLLIMPEXP_NET GetError();
|
GSocketError WXDLLIMPEXP_NET GetError();
|
||||||
@@ -73,31 +72,10 @@ protected:
|
|||||||
int Recv_Dgram(char *buffer, int size);
|
int Recv_Dgram(char *buffer, int size);
|
||||||
int Send_Stream(const char *buffer, int size);
|
int Send_Stream(const char *buffer, int size);
|
||||||
int Send_Dgram(const char *buffer, int size);
|
int Send_Dgram(const char *buffer, int size);
|
||||||
bool m_ok;
|
|
||||||
int m_initialRecvBufferSize;
|
|
||||||
int m_initialSendBufferSize;
|
|
||||||
|
|
||||||
/* TODO: Make these protected */
|
/* TODO: Make these protected */
|
||||||
public:
|
public:
|
||||||
SOCKET m_fd;
|
|
||||||
GAddress *m_local;
|
|
||||||
GAddress *m_peer;
|
|
||||||
GSocketError m_error;
|
|
||||||
|
|
||||||
/* Attributes */
|
|
||||||
bool m_non_blocking;
|
|
||||||
bool m_server;
|
|
||||||
bool m_stream;
|
|
||||||
bool m_establishing;
|
|
||||||
bool m_reusable;
|
|
||||||
bool m_broadcast;
|
|
||||||
bool m_dobind;
|
|
||||||
struct timeval m_timeout;
|
|
||||||
|
|
||||||
/* Callbacks */
|
|
||||||
GSocketEventFlags m_detected;
|
|
||||||
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
|
|
||||||
char *m_data[GSOCK_MAX_EVENT];
|
|
||||||
int m_msgnumber;
|
int m_msgnumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
class wxGSocketIOHandler;
|
class wxGSocketIOHandler;
|
||||||
|
|
||||||
class GSocket
|
class GSocket : public GSocketBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GSocket();
|
GSocket();
|
||||||
@@ -34,7 +34,6 @@ public:
|
|||||||
GSocketError SetNonOriented();
|
GSocketError SetNonOriented();
|
||||||
int Read(char *buffer, int size);
|
int Read(char *buffer, int size);
|
||||||
int Write(const char *buffer, int size);
|
int Write(const char *buffer, int size);
|
||||||
GSocketEventFlags Select(GSocketEventFlags flags);
|
|
||||||
void SetNonBlocking(bool non_block);
|
void SetNonBlocking(bool non_block);
|
||||||
void SetTimeout(unsigned long millisec);
|
void SetTimeout(unsigned long millisec);
|
||||||
GSocketError WXDLLIMPEXP_NET GetError();
|
GSocketError WXDLLIMPEXP_NET GetError();
|
||||||
@@ -66,35 +65,14 @@ protected:
|
|||||||
int Recv_Dgram(char *buffer, int size);
|
int Recv_Dgram(char *buffer, int size);
|
||||||
int Send_Stream(const char *buffer, int size);
|
int Send_Stream(const char *buffer, int size);
|
||||||
int Send_Dgram(const char *buffer, int size);
|
int Send_Dgram(const char *buffer, int size);
|
||||||
bool m_ok;
|
|
||||||
int m_initialRecvBufferSize;
|
|
||||||
int m_initialSendBufferSize;
|
|
||||||
public:
|
public:
|
||||||
/* DFE: We can't protect these data member until the GUI code is updated */
|
/* DFE: We can't protect these data member until the GUI code is updated */
|
||||||
/* protected: */
|
/* protected: */
|
||||||
int m_fd;
|
|
||||||
wxGSocketIOHandler *m_handler;
|
wxGSocketIOHandler *m_handler;
|
||||||
GAddress *m_local;
|
|
||||||
GAddress *m_peer;
|
|
||||||
GSocketError m_error;
|
|
||||||
|
|
||||||
bool m_non_blocking;
|
|
||||||
bool m_server;
|
|
||||||
bool m_stream;
|
|
||||||
bool m_establishing;
|
|
||||||
bool m_reusable;
|
|
||||||
bool m_broadcast;
|
|
||||||
bool m_dobind;
|
|
||||||
unsigned long m_timeout;
|
|
||||||
|
|
||||||
// true if socket should fire events
|
// true if socket should fire events
|
||||||
bool m_use_events;
|
bool m_use_events;
|
||||||
|
|
||||||
/* Callbacks */
|
|
||||||
GSocketEventFlags m_detected;
|
|
||||||
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
|
|
||||||
char *m_data[GSOCK_MAX_EVENT];
|
|
||||||
|
|
||||||
// pointer for storing extra (usually GUI-specific) data
|
// pointer for storing extra (usually GUI-specific) data
|
||||||
void *m_gui_dependent;
|
void *m_gui_dependent;
|
||||||
};
|
};
|
||||||
|
@@ -11,45 +11,9 @@
|
|||||||
#ifndef _WX_UNIX_PRIVATE_H_
|
#ifndef _WX_UNIX_PRIVATE_H_
|
||||||
#define _WX_UNIX_PRIVATE_H_
|
#define _WX_UNIX_PRIVATE_H_
|
||||||
|
|
||||||
// standard linux headers produce many warnings when used with icc
|
// this file is currently empty as its original contents was moved to
|
||||||
#if defined(__INTELC__) && defined(__LINUX__)
|
// include/wx/gsocket.h but let's keep it for now in case we need it for
|
||||||
inline void wxFD_ZERO(fd_set *fds)
|
// something again in the future
|
||||||
{
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:593)
|
|
||||||
FD_ZERO(fds);
|
|
||||||
#pragma warning(pop)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void wxFD_SET(int fd, fd_set *fds)
|
|
||||||
{
|
|
||||||
#pragma warning(push, 1)
|
|
||||||
#pragma warning(disable:1469)
|
|
||||||
FD_SET(fd, fds);
|
|
||||||
#pragma warning(pop)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool wxFD_ISSET(int fd, fd_set *fds)
|
|
||||||
{
|
|
||||||
#pragma warning(push, 1)
|
|
||||||
#pragma warning(disable:1469)
|
|
||||||
return FD_ISSET(fd, fds);
|
|
||||||
#pragma warning(pop)
|
|
||||||
}
|
|
||||||
inline bool wxFD_CLR(int fd, fd_set *fds)
|
|
||||||
{
|
|
||||||
#pragma warning(push, 1)
|
|
||||||
#pragma warning(disable:1469)
|
|
||||||
return FD_CLR(fd, fds);
|
|
||||||
#pragma warning(pop)
|
|
||||||
}
|
|
||||||
#else // !__INTELC__
|
|
||||||
#define wxFD_ZERO(fds) FD_ZERO(fds)
|
|
||||||
#define wxFD_SET(fd, fds) FD_SET(fd, fds)
|
|
||||||
#define wxFD_ISSET(fd, fds) FD_ISSET(fd, fds)
|
|
||||||
#define wxFD_CLR(fd, fds) FD_CLR(fd, fds)
|
|
||||||
#endif // __INTELC__/!__INTELC__
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _WX_UNIX_PRIVATE_H_
|
#endif // _WX_UNIX_PRIVATE_H_
|
||||||
|
|
||||||
|
@@ -720,6 +720,112 @@ wxSocketBase& wxSocketBase::Discard()
|
|||||||
// Wait functions
|
// Wait functions
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* GSocket_Select:
|
||||||
|
* Polls the socket to determine its status. This function will
|
||||||
|
* check for the events specified in the 'flags' parameter, and
|
||||||
|
* it will return a mask indicating which operations can be
|
||||||
|
* performed. This function won't block, regardless of the
|
||||||
|
* mode (blocking | nonblocking) of the socket.
|
||||||
|
*/
|
||||||
|
GSocketEventFlags GSocketBase::Select(GSocketEventFlags flags)
|
||||||
|
{
|
||||||
|
assert(this);
|
||||||
|
|
||||||
|
GSocketEventFlags result = 0;
|
||||||
|
fd_set readfds;
|
||||||
|
fd_set writefds;
|
||||||
|
fd_set exceptfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
if (m_fd == -1)
|
||||||
|
return (GSOCK_LOST_FLAG & flags);
|
||||||
|
|
||||||
|
/* Do not use a static struct, Linux can garble it */
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
wxFD_ZERO(&readfds);
|
||||||
|
wxFD_ZERO(&writefds);
|
||||||
|
wxFD_ZERO(&exceptfds);
|
||||||
|
wxFD_SET(m_fd, &readfds);
|
||||||
|
if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
|
||||||
|
wxFD_SET(m_fd, &writefds);
|
||||||
|
wxFD_SET(m_fd, &exceptfds);
|
||||||
|
|
||||||
|
/* Check 'sticky' CONNECTION flag first */
|
||||||
|
result |= GSOCK_CONNECTION_FLAG & m_detected;
|
||||||
|
|
||||||
|
/* If we have already detected a LOST event, then don't try
|
||||||
|
* to do any further processing.
|
||||||
|
*/
|
||||||
|
if ((m_detected & GSOCK_LOST_FLAG) != 0)
|
||||||
|
{
|
||||||
|
m_establishing = false;
|
||||||
|
return (GSOCK_LOST_FLAG & flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try select now */
|
||||||
|
if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
|
||||||
|
{
|
||||||
|
/* What to do here? */
|
||||||
|
return (result & flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for exceptions and errors */
|
||||||
|
if (wxFD_ISSET(m_fd, &exceptfds))
|
||||||
|
{
|
||||||
|
m_establishing = false;
|
||||||
|
m_detected = GSOCK_LOST_FLAG;
|
||||||
|
|
||||||
|
/* LOST event: Abort any further processing */
|
||||||
|
return (GSOCK_LOST_FLAG & flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for readability */
|
||||||
|
if (wxFD_ISSET(m_fd, &readfds))
|
||||||
|
{
|
||||||
|
result |= GSOCK_INPUT_FLAG;
|
||||||
|
|
||||||
|
if (m_server && m_stream)
|
||||||
|
{
|
||||||
|
/* This is a TCP server socket that detected a connection.
|
||||||
|
While the INPUT_FLAG is also set, it doesn't matter on
|
||||||
|
this kind of sockets, as we can only Accept() from them. */
|
||||||
|
m_detected |= GSOCK_CONNECTION_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for writability */
|
||||||
|
if (wxFD_ISSET(m_fd, &writefds))
|
||||||
|
{
|
||||||
|
if (m_establishing && !m_server)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
SOCKOPTLEN_T len = sizeof(error);
|
||||||
|
m_establishing = false;
|
||||||
|
getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
m_detected = GSOCK_LOST_FLAG;
|
||||||
|
|
||||||
|
/* LOST event: Abort any further processing */
|
||||||
|
return (GSOCK_LOST_FLAG & flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_detected |= GSOCK_CONNECTION_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result |= GSOCK_OUTPUT_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result | m_detected) & flags;
|
||||||
|
}
|
||||||
|
|
||||||
// All Wait functions poll the socket using GSocket_Select() to
|
// All Wait functions poll the socket using GSocket_Select() to
|
||||||
// check for the specified combination of conditions, until one
|
// check for the specified combination of conditions, until one
|
||||||
// of these conditions become true, an error occurs, or the
|
// of these conditions become true, an error occurs, or the
|
||||||
@@ -749,11 +855,6 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
|
|||||||
if ( wxIsMainThread() )
|
if ( wxIsMainThread() )
|
||||||
{
|
{
|
||||||
eventLoop = wxEventLoop::GetActive();
|
eventLoop = wxEventLoop::GetActive();
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
wxASSERT_MSG( eventLoop,
|
|
||||||
"Sockets won't work without a running event loop" );
|
|
||||||
#endif // __WXMSW__
|
|
||||||
}
|
}
|
||||||
else // in worker thread
|
else // in worker thread
|
||||||
{
|
{
|
||||||
@@ -808,10 +909,9 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
|
|||||||
|
|
||||||
if ( eventLoop )
|
if ( eventLoop )
|
||||||
{
|
{
|
||||||
// Dispatch the events when we run in the main thread and have an
|
// This function is only called if wxSOCKET_BLOCK flag was not used
|
||||||
// active event loop: without this sockets don't work at all under
|
// and so we should dispatch the events if there is an event loop
|
||||||
// MSW as socket flags are only updated when socket messages are
|
// capable of doing it.
|
||||||
// processed.
|
|
||||||
if ( eventLoop->Pending() )
|
if ( eventLoop->Pending() )
|
||||||
eventLoop->Dispatch();
|
eventLoop->Dispatch();
|
||||||
}
|
}
|
||||||
|
@@ -776,18 +776,6 @@ int GSocket::Write(const char *buffer, int size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GSocket_Select:
|
|
||||||
* Polls the socket to determine its status. This function will
|
|
||||||
* check for the events specified in the 'flags' parameter, and
|
|
||||||
* it will return a mask indicating which operations can be
|
|
||||||
* performed. This function won't block, regardless of the
|
|
||||||
* mode (blocking | nonblocking) of the socket.
|
|
||||||
*/
|
|
||||||
GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
|
|
||||||
{
|
|
||||||
return flags & m_detected;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Attributes */
|
/* Attributes */
|
||||||
|
|
||||||
/* GSocket_SetNonBlocking:
|
/* GSocket_SetNonBlocking:
|
||||||
|
@@ -1285,112 +1285,6 @@ int GSocket::Write(const char *buffer, int size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GSocket_Select:
|
|
||||||
* Polls the socket to determine its status. This function will
|
|
||||||
* check for the events specified in the 'flags' parameter, and
|
|
||||||
* it will return a mask indicating which operations can be
|
|
||||||
* performed. This function won't block, regardless of the
|
|
||||||
* mode (blocking | nonblocking) of the socket.
|
|
||||||
*/
|
|
||||||
GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
|
|
||||||
{
|
|
||||||
assert(this);
|
|
||||||
|
|
||||||
GSocketEventFlags result = 0;
|
|
||||||
fd_set readfds;
|
|
||||||
fd_set writefds;
|
|
||||||
fd_set exceptfds;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
if (m_fd == -1)
|
|
||||||
return (GSOCK_LOST_FLAG & flags);
|
|
||||||
|
|
||||||
/* Do not use a static struct, Linux can garble it */
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
wxFD_ZERO(&readfds);
|
|
||||||
wxFD_ZERO(&writefds);
|
|
||||||
wxFD_ZERO(&exceptfds);
|
|
||||||
wxFD_SET(m_fd, &readfds);
|
|
||||||
if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
|
|
||||||
wxFD_SET(m_fd, &writefds);
|
|
||||||
wxFD_SET(m_fd, &exceptfds);
|
|
||||||
|
|
||||||
/* Check 'sticky' CONNECTION flag first */
|
|
||||||
result |= GSOCK_CONNECTION_FLAG & m_detected;
|
|
||||||
|
|
||||||
/* If we have already detected a LOST event, then don't try
|
|
||||||
* to do any further processing.
|
|
||||||
*/
|
|
||||||
if ((m_detected & GSOCK_LOST_FLAG) != 0)
|
|
||||||
{
|
|
||||||
m_establishing = false;
|
|
||||||
return (GSOCK_LOST_FLAG & flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try select now */
|
|
||||||
if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
|
|
||||||
{
|
|
||||||
/* What to do here? */
|
|
||||||
return (result & flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for exceptions and errors */
|
|
||||||
if (wxFD_ISSET(m_fd, &exceptfds))
|
|
||||||
{
|
|
||||||
m_establishing = false;
|
|
||||||
m_detected = GSOCK_LOST_FLAG;
|
|
||||||
|
|
||||||
/* LOST event: Abort any further processing */
|
|
||||||
return (GSOCK_LOST_FLAG & flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for readability */
|
|
||||||
if (wxFD_ISSET(m_fd, &readfds))
|
|
||||||
{
|
|
||||||
result |= GSOCK_INPUT_FLAG;
|
|
||||||
|
|
||||||
if (m_server && m_stream)
|
|
||||||
{
|
|
||||||
/* This is a TCP server socket that detected a connection.
|
|
||||||
While the INPUT_FLAG is also set, it doesn't matter on
|
|
||||||
this kind of sockets, as we can only Accept() from them. */
|
|
||||||
m_detected |= GSOCK_CONNECTION_FLAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for writability */
|
|
||||||
if (wxFD_ISSET(m_fd, &writefds))
|
|
||||||
{
|
|
||||||
if (m_establishing && !m_server)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
SOCKOPTLEN_T len = sizeof(error);
|
|
||||||
m_establishing = false;
|
|
||||||
getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
m_detected = GSOCK_LOST_FLAG;
|
|
||||||
|
|
||||||
/* LOST event: Abort any further processing */
|
|
||||||
return (GSOCK_LOST_FLAG & flags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_detected |= GSOCK_CONNECTION_FLAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result |= GSOCK_OUTPUT_FLAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (result | m_detected) & flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
|
|
||||||
/* GSocket_SetNonBlocking:
|
/* GSocket_SetNonBlocking:
|
||||||
|
Reference in New Issue
Block a user