// Declarations
// ==========================================================================
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "socket.h"
#endif
#include "wx/sckaddr.h"
#include "wx/socket.h"
+// DLL options compatibility check:
+#include "wx/build.h"
+WX_CHECK_BUILD_OPTIONS("wxNet")
+
// --------------------------------------------------------------------------
// macros and constants
// --------------------------------------------------------------------------
// what to do within waits: we have 2 cases: from the main thread itself we
// have to call wxYield() to let the events (including the GUI events and the
-// low-level (not wxWindows) events from GSocket) be processed. From another
+// low-level (not wxWidgets) events from GSocket) be processed. From another
// thread it is enough to just call wxThread::Yield() which will give away the
// rest of our time slice: the explanation is that the events will be processed
// by the main thread anyhow, without calling wxYield(), but we don't want to
wxSocketEventFlags m_eventmask;
bool m_notify;
void *m_clientData;
-#if WXWIN_COMPATIBILITY
- wxSocketBase::wxSockCbk m_cbk;
- char *m_cdata;
-#endif // WXWIN_COMPATIBILITY
public:
wxSocketState() : wxObject() {}
{
if ( !m_countInit++ )
{
+#ifdef __WXMSW__
+ /*
+ The following asserting might be neccessary for linux as well,
+ but I cannot verify this.
+ */
+ wxASSERT(wxThread::IsMain(),
+ wxT("To use sockets in a secondary thread, ")
+ wxT("call wxSocketBase::Initialize() from the main thread."));
+ /*
+ Details: Initialize() creates a hidden window as a sink for socket
+ events, such as 'read completed'. wxMSW has only one message loop
+ for the main thread. If Initialize is called in a secondary thread,
+ the socket window will be created for the secondary thread, but
+ since there is no message loop on this thread, it will never
+ receive events and all socket operations will time out.
+ BTW, the main thread must not be stopped using sleep or block
+ on a semaphore (a bad idea in any case) or socket operations
+ will time out.
+ */
+#endif
+ wxAppTraits *traits = wxAppConsole::GetInstance() ?
+ wxAppConsole::GetInstance()->GetTraits() : NULL;
+ GSocketGUIFunctionsTable *functions =
+ traits ? traits->GetSocketGUIFunctionsTable() : NULL;
+ GSocket_SetGUIFunctions(functions);
+
if ( !GSocket_Init() )
{
m_countInit--;
m_clientData = NULL;
m_notify = FALSE;
m_eventmask = 0;
-#if WXWIN_COMPATIBILITY
- m_cbk = NULL;
- m_cdata = NULL;
-#endif // WXWIN_COMPATIBILITY
if ( !IsInitialized() )
{
wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
{
int total;
- int ret = 1;
// Try the pushback buffer first
total = GetPushback(buffer, nbytes, FALSE);
// wxSOCKET_BLOCK
// wxSOCKET_NONE
//
+ int ret;
if (m_flags & wxSOCKET_NOWAIT)
{
GSocket_SetNonBlocking(m_socket, 1);
wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
{
wxUint32 total = 0;
- int ret = 1;
// If the socket is invalid or parameters are ill, return immediately
if (!m_socket || !buffer || !nbytes)
// wxSOCKET_BLOCK
// wxSOCKET_NONE
//
+ int ret;
if (m_flags & wxSOCKET_NOWAIT)
{
GSocket_SetNonBlocking(m_socket, 1);
{
wxUint32 total;
bool error;
- int old_flags;
struct
{
unsigned char sig[4];
error = TRUE;
total = 0;
- old_flags = m_flags;
SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
msg.sig[0] = (unsigned char) 0xad;
wxSocketBase& wxSocketBase::Discard()
{
- int old_flags;
char *buffer = new char[MAX_DISCARD_SIZE];
wxUint32 ret;
wxUint32 total = 0;
// Mask read events
m_reading = TRUE;
- old_flags = m_flags;
SetFlags(wxSOCKET_NOWAIT);
do
else
timeout = m_timeout * 1000;
+#if !defined(wxUSE_GUI) || !wxUSE_GUI
+ GSocket_SetTimeout(m_socket, timeout);
+#endif
+
// Wait in an active polling loop.
//
// NOTE: We duplicate some of the code in OnRequest, but this doesn't
GSOCK_LOST_FLAG);
}
+
bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
{
return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
state->m_notify = m_notify;
state->m_eventmask = m_eventmask;
state->m_clientData = m_clientData;
-#if WXWIN_COMPATIBILITY
- state->m_cbk = m_cbk;
- state->m_cdata = m_cdata;
-#endif // WXWIN_COMPATIBILITY
m_states.Append(state);
}
void wxSocketBase::RestoreState()
{
- wxNode *node;
+ wxList::compatibility_iterator node;
wxSocketState *state;
node = m_states.GetLast();
m_notify = state->m_notify;
m_eventmask = state->m_eventmask;
m_clientData = state->m_clientData;
-#if WXWIN_COMPATIBILITY
- m_cbk = state->m_cbk;
- m_cdata = state->m_cdata;
-#endif // WXWIN_COMPATIBILITY
-
- delete node;
+
+ m_states.Erase(node);
delete state;
}
}
-// --------------------------------------------------------------------------
-// Callbacks (now obsolete - use events instead)
-// --------------------------------------------------------------------------
-
-#if WXWIN_COMPATIBILITY
-
-wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
-{
- wxSockCbk old_cbk = cbk_;
-
- m_cbk = cbk_;
- return old_cbk;
-}
-
-char *wxSocketBase::CallbackData(char *data)
-{
- char *old_data = m_cdata;
-
- m_cdata = data;
- return old_data;
-}
-
-#endif // WXWIN_COMPATIBILITY
-
// --------------------------------------------------------------------------
// Event handling
// --------------------------------------------------------------------------
// Schedule the event
wxSocketEventFlags flag = 0;
+ wxUnusedVar(flag);
switch (notification)
{
case GSOCK_INPUT: flag = GSOCK_INPUT_FLAG; break;
m_handler->AddPendingEvent(event);
}
-
-#if WXWIN_COMPATIBILITY
- if (m_cbk)
- m_cbk(*this, notification, m_cdata);
-#endif // WXWIN_COMPATIBILITY
}
}
return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
}
+bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
+{
+ if (GSocket_GetSockOpt(m_socket, level, optname, optval, optlen)
+ != GSOCK_NOERROR)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool wxSocketBase::SetOption(int level, int optname, const void *optval,
+ int optlen)
+{
+ if (GSocket_SetSockOpt(m_socket, level, optname, optval, optlen)
+ != GSOCK_NOERROR)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
// ==========================================================================
// wxSocketClient
// ==========================================================================
m_socket = GSocket_new();
if(!m_socket)
+ {
+ wxASSERT_MSG( 0, _T("datagram socket not new'd") );
return;
-
+ }
// Setup the socket as non connection oriented
+ GSocket_Unstreamed(m_socket);
GSocket_SetLocal(m_socket, addr.GetAddress());
if( GSocket_SetNonOriented(m_socket) != GSOCK_NOERROR )
{
// wxSocketModule
// ==========================================================================
-class WXDLLEXPORT wxSocketModule : public wxModule
+class wxSocketModule : public wxModule
{
public:
virtual bool OnInit()