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__)
#include "wx/msw/gsockmsw.h"
#else
GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
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 /* _WX_GSOCKET_H_ */
#endif
/* Definition of GSocket */
-class GSocket
+class GSocket : public GSocketBase
{
public:
GSocket();
GSocketError SetNonOriented();
int Read(char *buffer, int size);
int Write(const char *buffer, int size);
- GSocketEventFlags Select(GSocketEventFlags flags);
void SetNonBlocking(bool non_block);
void SetTimeout(unsigned long millis);
GSocketError WXDLLIMPEXP_NET GetError();
int Recv_Dgram(char *buffer, int size);
int Send_Stream(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 */
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;
};
class wxGSocketIOHandler;
-class GSocket
+class GSocket : public GSocketBase
{
public:
GSocket();
GSocketError SetNonOriented();
int Read(char *buffer, int size);
int Write(const char *buffer, int size);
- GSocketEventFlags Select(GSocketEventFlags flags);
void SetNonBlocking(bool non_block);
void SetTimeout(unsigned long millisec);
GSocketError WXDLLIMPEXP_NET GetError();
int Recv_Dgram(char *buffer, int size);
int Send_Stream(const char *buffer, int size);
int Send_Dgram(const char *buffer, int size);
- bool m_ok;
- int m_initialRecvBufferSize;
- int m_initialSendBufferSize;
public:
/* DFE: We can't protect these data member until the GUI code is updated */
/* protected: */
- int m_fd;
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
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
void *m_gui_dependent;
};
#ifndef _WX_UNIX_PRIVATE_H_
#define _WX_UNIX_PRIVATE_H_
-// 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 file is currently empty as its original contents was moved to
+// include/wx/gsocket.h but let's keep it for now in case we need it for
+// something again in the future
#endif // _WX_UNIX_PRIVATE_H_
// 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
// check for the specified combination of conditions, until one
// of these conditions become true, an error occurs, or the
if ( wxIsMainThread() )
{
eventLoop = wxEventLoop::GetActive();
-
-#ifdef __WXMSW__
- wxASSERT_MSG( eventLoop,
- "Sockets won't work without a running event loop" );
-#endif // __WXMSW__
}
else // in worker thread
{
if ( eventLoop )
{
- // Dispatch the events when we run in the main thread and have an
- // active event loop: without this sockets don't work at all under
- // MSW as socket flags are only updated when socket messages are
- // processed.
+ // This function is only called if wxSOCKET_BLOCK flag was not used
+ // and so we should dispatch the events if there is an event loop
+ // capable of doing it.
if ( eventLoop->Pending() )
eventLoop->Dispatch();
}
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 */
/* GSocket_SetNonBlocking:
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 */
/* GSocket_SetNonBlocking: