* Committing new wxSocket core (socket.cpp sckint.cpp). It has to be improved ...
* Adding sckint.cpp to various makefiles. * Fixes in threadpsx.cpp (Pause/Resume) * Fixes in threaded event dispatching * Added Clone() to wxObject * Implemented Clone() in wxEvent and wxSocketEvent * wxSocket sample save the data got from the URL in test.url (this will change) * As I only tested wxSocket on Linux Redhat 5.2 I disabled it by default on Windows, Mac and Unix platforms. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2289 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -855,7 +855,7 @@ DEFAULT_wxUSE_TIMEDATE=1
|
|||||||
DEFAULT_wxUSE_INTL=1
|
DEFAULT_wxUSE_INTL=1
|
||||||
DEFAULT_wxUSE_CONFIG=1
|
DEFAULT_wxUSE_CONFIG=1
|
||||||
DEFAULT_wxUSE_STREAMS=1
|
DEFAULT_wxUSE_STREAMS=1
|
||||||
DEFAULT_wxUSE_SOCKETS=1
|
DEFAULT_wxUSE_SOCKETS=0
|
||||||
DEFAULT_wxUSE_SERIAL=1
|
DEFAULT_wxUSE_SERIAL=1
|
||||||
DEFAULT_wxUSE_DYNLIB_CLASS=1
|
DEFAULT_wxUSE_DYNLIB_CLASS=1
|
||||||
|
|
||||||
|
@@ -290,6 +290,8 @@ public:
|
|||||||
// exists only for optimization purposes
|
// exists only for optimization purposes
|
||||||
bool IsCommandEvent() const { return m_isCommandEvent; }
|
bool IsCommandEvent() const { return m_isCommandEvent; }
|
||||||
|
|
||||||
|
wxObject *Clone() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool m_skipped;
|
bool m_skipped;
|
||||||
wxObject* m_eventObject;
|
wxObject* m_eventObject;
|
||||||
|
@@ -167,7 +167,7 @@
|
|||||||
#define wxUSE_TOOLTIPS 1
|
#define wxUSE_TOOLTIPS 1
|
||||||
// Define to use wxToolTip class and
|
// Define to use wxToolTip class and
|
||||||
// wxWindow::SetToolTip() method
|
// wxWindow::SetToolTip() method
|
||||||
#define wxUSE_SOCKETS 1
|
#define wxUSE_SOCKETS 0
|
||||||
// Set to 1 to use socket classes
|
// Set to 1 to use socket classes
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -192,6 +192,7 @@ class WXDLLEXPORT wxObject
|
|||||||
virtual ~wxObject(void);
|
virtual ~wxObject(void);
|
||||||
|
|
||||||
virtual wxClassInfo *GetClassInfo(void) const { return &sm_classwxObject; }
|
virtual wxClassInfo *GetClassInfo(void) const { return &sm_classwxObject; }
|
||||||
|
virtual wxObject *Clone(void) const;
|
||||||
|
|
||||||
bool IsKindOf(wxClassInfo *info) const;
|
bool IsKindOf(wxClassInfo *info) const;
|
||||||
|
|
||||||
|
144
include/wx/sckint.h
Normal file
144
include/wx/sckint.h
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: sckint.h
|
||||||
|
// Purpose: Socket internal classes
|
||||||
|
// Author: Guilhem Lavaux
|
||||||
|
// Modified by:
|
||||||
|
// Created: April 1999
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Guilhem Lavaux
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef _WX_NETWORK_SOCKET_INT_H
|
||||||
|
#define _WX_NETWORK_SOCKET_INT_H
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma interface
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_SOCKETS
|
||||||
|
|
||||||
|
#include <wx/object.h>
|
||||||
|
#include <wx/list.h>
|
||||||
|
#include <wx/socket.h>
|
||||||
|
#include <wx/thread.h>
|
||||||
|
|
||||||
|
// Socket state
|
||||||
|
class SocketState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// TRUE if the background notifyier is on.
|
||||||
|
bool notify_state;
|
||||||
|
// Specifies which events we want to be notified.
|
||||||
|
wxSocketBase::wxRequestNotify evt_notify_state;
|
||||||
|
// Socket flags.
|
||||||
|
wxSocketBase::wxSockFlags socket_flags;
|
||||||
|
// Pointer to the C callback function.
|
||||||
|
wxSocketBase::wxSockCbk c_callback;
|
||||||
|
char *c_callback_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Socket request
|
||||||
|
class SockRequest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Buffer where to get/put data.
|
||||||
|
char *buffer;
|
||||||
|
// Size of the buffer.
|
||||||
|
size_t size;
|
||||||
|
// Number of bytes really read/written.
|
||||||
|
size_t io_nbytes;
|
||||||
|
// Error.
|
||||||
|
unsigned int error;
|
||||||
|
// Type of the request.
|
||||||
|
wxSocketBase::wxRequestNotify type;
|
||||||
|
// Timeout (in milliseconds).
|
||||||
|
unsigned int timeout;
|
||||||
|
// TRUE if the buffer has been processed.
|
||||||
|
bool done;
|
||||||
|
// TRUE if we must wait for the request completion, in the other case an
|
||||||
|
// event will be sent to the main thread when the request is finished.
|
||||||
|
bool wait;
|
||||||
|
};
|
||||||
|
|
||||||
|
class wxSocketInternal;
|
||||||
|
class SocketWaiter: public wxThread {
|
||||||
|
public:
|
||||||
|
SocketWaiter(wxSocketBase *socket, wxSocketInternal *internal);
|
||||||
|
~SocketWaiter();
|
||||||
|
|
||||||
|
// Thread Entry point
|
||||||
|
// ---
|
||||||
|
virtual void *Entry();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ProcessReadEvent();
|
||||||
|
void ProcessWriteEvent();
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxSocketBase *m_socket;
|
||||||
|
wxSocketInternal *m_internal;
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SocketRequester: public wxThread {
|
||||||
|
public:
|
||||||
|
SocketRequester(wxSocketBase *socket, wxSocketInternal *internal);
|
||||||
|
~SocketRequester();
|
||||||
|
|
||||||
|
void ProcessWaitEvent(SockRequest *req);
|
||||||
|
void ProcessReadEvent(SockRequest *req);
|
||||||
|
void ProcessWriteEvent(SockRequest *req);
|
||||||
|
|
||||||
|
bool WaitFor(wxSocketBase::wxRequestNotify req, int millisec);
|
||||||
|
|
||||||
|
// Thread Entry point
|
||||||
|
// ---
|
||||||
|
virtual void *Entry();
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxSocketBase *m_socket;
|
||||||
|
wxSocketInternal *m_internal;
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
class wxSocketInternal {
|
||||||
|
public:
|
||||||
|
wxSocketInternal(wxSocketBase *socket);
|
||||||
|
~wxSocketInternal();
|
||||||
|
|
||||||
|
// wxSocket thread manager
|
||||||
|
// -----------------------
|
||||||
|
void AcquireData();
|
||||||
|
void ReleaseData();
|
||||||
|
void AcquireFD();
|
||||||
|
void ReleaseFD();
|
||||||
|
|
||||||
|
int GetFD() { return m_fd; }
|
||||||
|
|
||||||
|
void InitializeSocket();
|
||||||
|
void FinalizeSocket();
|
||||||
|
void PauseSocket();
|
||||||
|
void ResumeSocket();
|
||||||
|
void EnableWaiter();
|
||||||
|
void DisableWaiter();
|
||||||
|
|
||||||
|
void QueueRequest(SockRequest *request, bool async);
|
||||||
|
void WaitForEnd(SockRequest *request);
|
||||||
|
|
||||||
|
SockRequest *WaitForReq();
|
||||||
|
void EndRequest(SockRequest *req);
|
||||||
|
public:
|
||||||
|
wxMutex m_socket_locker, m_fd_locker, m_request_locker;
|
||||||
|
wxCondition m_socket_cond;
|
||||||
|
wxSocketBase *m_socket;
|
||||||
|
SocketWaiter *m_thread_waiter;
|
||||||
|
SocketRequester *m_thread_requester;
|
||||||
|
wxList m_requests;
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// wxUSE_SOCKETS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// _WX_NETWORK_SOCKET_INT_H
|
@@ -22,15 +22,6 @@
|
|||||||
#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
|
#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#include <wx/msw/private.h>
|
#include <wx/msw/private.h>
|
||||||
|
|
||||||
struct wxSockInternal {
|
|
||||||
UINT my_msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wxSockHandlerInternal {
|
|
||||||
HWND sockWin;
|
|
||||||
UINT firstAvailableMsg;
|
|
||||||
};
|
|
||||||
#endif // defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
|
#endif // defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -40,29 +31,6 @@ struct wxSockHandlerInternal {
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Athena specific
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
#if defined(__WXXT__) || defined(__WXMOTIF__)
|
|
||||||
#include <X11/Intrinsic.h>
|
|
||||||
|
|
||||||
struct wxSockInternal {
|
|
||||||
XtInputId sock_inputid, sock_outputid, sock_exceptid;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// GTK specific
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
#if defined(__WXGTK__)
|
|
||||||
#include <gdk/gdk.h>
|
|
||||||
|
|
||||||
struct wxSockInternal {
|
|
||||||
gint sock_inputid, sock_outputid, sock_exceptid;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // defined(__UNIX__) && defined(WXSOCK_INTERNAL)
|
#endif // defined(__UNIX__) && defined(WXSOCK_INTERNAL)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -77,69 +45,45 @@ struct wxSockInternal {
|
|||||||
|
|
||||||
class WXDLLEXPORT wxSocketEvent;
|
class WXDLLEXPORT wxSocketEvent;
|
||||||
class WXDLLEXPORT wxSocketHandler;
|
class WXDLLEXPORT wxSocketHandler;
|
||||||
|
class wxSocketInternal;
|
||||||
class WXDLLEXPORT wxSocketBase : public wxEvtHandler
|
class WXDLLEXPORT wxSocketBase : public wxEvtHandler
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(wxSocketBase)
|
DECLARE_CLASS(wxSocketBase)
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
friend void wxMacSocketOnRequestProc(void *refcon , short event) ;
|
friend void wxMacSocketOnRequestProc(void *refcon , short event) ;
|
||||||
#endif
|
#endif
|
||||||
#if defined(__WXGTK__) && defined(WXSOCK_INTERNAL)
|
|
||||||
friend void wxPrereadSocket(wxSocketBase *sock);
|
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum wxSockFlags { NONE=0, NOWAIT=1, WAITALL=2, SPEED=4 };
|
enum wxSockFlags { NONE=0, NOWAIT=1, WAITALL=2, SPEED=4 };
|
||||||
// Type of request
|
// Type of request
|
||||||
enum { REQ_READ=0x1, REQ_PEEK=0x2, REQ_WRITE=0x4, REQ_LOST=0x8,
|
enum { REQ_READ=0x1, REQ_PEEK=0x2, REQ_WRITE=0x4, REQ_LOST=0x8,
|
||||||
REQ_ACCEPT=0x10, REQ_CONNECT=0x20};
|
REQ_ACCEPT=0x10, REQ_CONNECT=0x20, REQ_WAIT=0x40};
|
||||||
enum { EVT_READ=0, EVT_PEEK=1, EVT_WRITE=2, EVT_LOST=3, EVT_ACCEPT=4,
|
enum { EVT_READ=0, EVT_PEEK=1, EVT_WRITE=2, EVT_LOST=3, EVT_ACCEPT=4,
|
||||||
EVT_CONNECT=5 };
|
EVT_CONNECT=5 };
|
||||||
|
|
||||||
typedef int wxRequestNotify;
|
typedef int wxRequestNotify;
|
||||||
typedef int wxRequestEvent;
|
typedef int wxRequestEvent;
|
||||||
|
enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT };
|
||||||
typedef void (*wxSockCbk)(wxSocketBase& sock,wxRequestEvent evt,char *cdata);
|
typedef void (*wxSockCbk)(wxSocketBase& sock,wxRequestEvent evt,char *cdata);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxList req_list[EVT_WRITE+1];
|
|
||||||
|
|
||||||
// Internal use for SaveState() and RestoreState()
|
|
||||||
class wxSockState : public wxObject {
|
|
||||||
public:
|
|
||||||
bool cbk_on;
|
|
||||||
wxSockCbk cbk;
|
|
||||||
char *cdata;
|
|
||||||
bool notif;
|
|
||||||
wxRequestNotify cbk_set;
|
|
||||||
wxSockFlags flags;
|
|
||||||
};
|
|
||||||
typedef struct {
|
|
||||||
char sig[4];
|
|
||||||
char len[4];
|
|
||||||
} SockMsg;
|
|
||||||
enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT };
|
|
||||||
|
|
||||||
wxSockFlags m_flags;
|
wxSockFlags m_flags;
|
||||||
wxSockType m_type; // wxSocket type
|
wxSockType m_type; // wxSocket type
|
||||||
bool m_connected, m_connecting; // State of the socket
|
bool m_connected, m_connecting; // State of the socket
|
||||||
int m_fd; // Socket file descriptors
|
int m_fd; // Socket file descriptors
|
||||||
int m_waitflags; // Wait flags
|
|
||||||
wxList m_states; // States list
|
wxList m_states; // States list
|
||||||
wxSockCbk m_cbk; // C callback
|
|
||||||
char *m_cdata; // C callback data
|
|
||||||
int m_id; // Socket id (for event handler)
|
int m_id; // Socket id (for event handler)
|
||||||
wxSocketHandler *m_handler; // the current socket handler
|
wxSocketHandler *m_handler; // the current socket handler
|
||||||
wxRequestNotify m_neededreq; // Specify which requet signals we need
|
wxRequestNotify m_neededreq; // Specify which requet signals we need
|
||||||
bool m_cbkon;
|
|
||||||
char *m_unread; // The unread buf
|
|
||||||
size_t m_unrd_size; // The size of the unread buf
|
|
||||||
bool m_processing; // To prevent some endless loop
|
|
||||||
unsigned long m_timeout;
|
unsigned long m_timeout;
|
||||||
int m_wantbuf;
|
|
||||||
size_t m_lcount; // Last IO request size
|
size_t m_lcount; // Last IO request size
|
||||||
int m_error; // Last IO error
|
int m_error; // Last IO error
|
||||||
bool m_notifyme;
|
wxSocketInternal *m_internal;
|
||||||
|
char *m_unread; // Pushback buffer
|
||||||
struct wxSockInternal *m_internal; // System specific variables
|
size_t m_unrd_size; // Pushback buffer size
|
||||||
|
wxSockCbk m_cbk;
|
||||||
|
char *m_cdata;
|
||||||
|
bool m_notify_state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxSocketBase();
|
wxSocketBase();
|
||||||
@@ -150,8 +94,6 @@ public:
|
|||||||
wxSocketBase& Peek(char* buffer, size_t nbytes);
|
wxSocketBase& Peek(char* buffer, size_t nbytes);
|
||||||
wxSocketBase& Read(char* buffer, size_t nbytes);
|
wxSocketBase& Read(char* buffer, size_t nbytes);
|
||||||
wxSocketBase& Write(const char *buffer, size_t nbytes);
|
wxSocketBase& Write(const char *buffer, size_t nbytes);
|
||||||
wxSocketBase& WriteMsg(const char *buffer, size_t nbytes);
|
|
||||||
wxSocketBase& ReadMsg(char* buffer, size_t nbytes);
|
|
||||||
wxSocketBase& Unread(const char *buffer, size_t nbytes);
|
wxSocketBase& Unread(const char *buffer, size_t nbytes);
|
||||||
void Discard();
|
void Discard();
|
||||||
|
|
||||||
@@ -168,8 +110,10 @@ public:
|
|||||||
bool IsData() const;
|
bool IsData() const;
|
||||||
inline size_t LastCount() const { return m_lcount; }
|
inline size_t LastCount() const { return m_lcount; }
|
||||||
inline int LastError() const { return m_error; }
|
inline int LastError() const { return m_error; }
|
||||||
|
inline wxSockType GetType() const { return m_type; }
|
||||||
|
|
||||||
void SetFlags(wxSockFlags _flags);
|
void SetFlags(wxSockFlags _flags);
|
||||||
|
wxSockFlags GetFlags() const;
|
||||||
inline void SetTimeout(unsigned long sec) { m_timeout = sec; }
|
inline void SetTimeout(unsigned long sec) { m_timeout = sec; }
|
||||||
|
|
||||||
// seconds = -1 means infinite wait
|
// seconds = -1 means infinite wait
|
||||||
@@ -213,6 +157,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
friend class wxSocketServer;
|
friend class wxSocketServer;
|
||||||
friend class wxSocketHandler;
|
friend class wxSocketHandler;
|
||||||
|
friend class wxSocketInternal;
|
||||||
|
|
||||||
#ifdef __SALFORDC__
|
#ifdef __SALFORDC__
|
||||||
public:
|
public:
|
||||||
@@ -230,10 +175,6 @@ protected:
|
|||||||
inline virtual void SetHandler(wxSocketHandler *handler)
|
inline virtual void SetHandler(wxSocketHandler *handler)
|
||||||
{ m_handler = handler; }
|
{ m_handler = handler; }
|
||||||
|
|
||||||
// Activate or disactivate callback
|
|
||||||
void SetupCallbacks();
|
|
||||||
void DestroyCallbacks();
|
|
||||||
|
|
||||||
// Pushback library
|
// Pushback library
|
||||||
size_t GetPushback(char *buffer, size_t size, bool peek);
|
size_t GetPushback(char *buffer, size_t size, bool peek);
|
||||||
|
|
||||||
@@ -241,8 +182,6 @@ protected:
|
|||||||
// ==> cause strange things :-)
|
// ==> cause strange things :-)
|
||||||
void WantSpeedBuffer(char *buffer, size_t size, wxRequestEvent req);
|
void WantSpeedBuffer(char *buffer, size_t size, wxRequestEvent req);
|
||||||
void WantBuffer(char *buffer, size_t size, wxRequestEvent req);
|
void WantBuffer(char *buffer, size_t size, wxRequestEvent req);
|
||||||
|
|
||||||
virtual bool DoRequests(wxRequestEvent req);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -258,7 +197,6 @@ public:
|
|||||||
|
|
||||||
wxSocketBase* Accept();
|
wxSocketBase* Accept();
|
||||||
bool AcceptWith(wxSocketBase& sock);
|
bool AcceptWith(wxSocketBase& sock);
|
||||||
virtual void OnRequest(wxRequestEvent flags);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -284,10 +222,6 @@ class WXDLLEXPORT wxSocketHandler : public wxObject
|
|||||||
{
|
{
|
||||||
DECLARE_CLASS(wxSocketHandler)
|
DECLARE_CLASS(wxSocketHandler)
|
||||||
protected:
|
protected:
|
||||||
#if defined(__WINDOWS__)
|
|
||||||
wxList *smsg_list;
|
|
||||||
struct wxSockHandlerInternal *internal;
|
|
||||||
#endif
|
|
||||||
wxList *socks;
|
wxList *socks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -337,15 +271,17 @@ public:
|
|||||||
wxSocketEvent(int id = 0);
|
wxSocketEvent(int id = 0);
|
||||||
|
|
||||||
wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; }
|
wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; }
|
||||||
|
wxSocketBase *Socket() const { return m_socket; }
|
||||||
|
|
||||||
|
wxObject *Clone() const;
|
||||||
public:
|
public:
|
||||||
wxSocketBase::wxRequestEvent m_skevt;
|
wxSocketBase::wxRequestEvent m_skevt;
|
||||||
|
wxSocketBase *m_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (wxEvtHandler::*wxSocketEventFunction)(wxSocketEvent&);
|
typedef void (wxEvtHandler::*wxSocketEventFunction)(wxSocketEvent&);
|
||||||
|
|
||||||
#define wxEVT_SOCKET wxEVT_FIRST+301
|
#define EVT_SOCKET(id, func) { wxEVT_SOCKET, id, -1, \
|
||||||
|
|
||||||
#define EVT_SOCKET(id, func) { wxEVT_SOCKET, id, 0, \
|
|
||||||
(wxObjectEventFunction) (wxEventFunction) (wxSocketEventFunction) & func, \
|
(wxObjectEventFunction) (wxEventFunction) (wxSocketEventFunction) & func, \
|
||||||
(wxObject *) NULL },
|
(wxObject *) NULL },
|
||||||
|
|
||||||
|
@@ -301,7 +301,7 @@ public:
|
|||||||
// Returns true if the thread is running (not paused, not killed).
|
// Returns true if the thread is running (not paused, not killed).
|
||||||
bool IsRunning() const;
|
bool IsRunning() const;
|
||||||
// Returns true if the thread is suspended
|
// Returns true if the thread is suspended
|
||||||
bool IsPaused() const { return IsAlive() && !IsRunning(); }
|
bool IsPaused() const;
|
||||||
|
|
||||||
// called when the thread exits - in the context of this thread
|
// called when the thread exits - in the context of this thread
|
||||||
//
|
//
|
||||||
|
@@ -53,8 +53,8 @@ class wxFileOutputStream: public wxOutputStream {
|
|||||||
virtual ~wxFileOutputStream();
|
virtual ~wxFileOutputStream();
|
||||||
|
|
||||||
// To solve an ambiguity on GCC
|
// To solve an ambiguity on GCC
|
||||||
inline wxOutputStream& Write(const void *buffer, size_t size)
|
// inline wxOutputStream& Write(const void *buffer, size_t size)
|
||||||
{ return wxOutputStream::Write(buffer, size); }
|
// { return wxOutputStream::Write(buffer, size); }
|
||||||
|
|
||||||
void Sync();
|
void Sync();
|
||||||
size_t StreamSize() const;
|
size_t StreamSize() const;
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "wx/wx.h"
|
#include "wx/wx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/wfstream.h"
|
||||||
#include "wx/socket.h"
|
#include "wx/socket.h"
|
||||||
#include "wx/url.h"
|
#include "wx/url.h"
|
||||||
#include "wx/protocol/http.h"
|
#include "wx/protocol/http.h"
|
||||||
@@ -204,12 +205,12 @@ void MyFrame::UpdateStatus()
|
|||||||
SetStatusText("", 1);
|
SetStatusText("", 1);
|
||||||
} else {
|
} else {
|
||||||
wxIPV4address addr;
|
wxIPV4address addr;
|
||||||
char s[100];
|
wxChar s[100];
|
||||||
|
|
||||||
sock->GetPeer(addr);
|
sock->GetPeer(addr);
|
||||||
sprintf(s, "Connected to %s", (const char *)addr.Hostname());
|
wxSprintf(s, _T("Connected to %s"), WXSTRINGCAST addr.Hostname());
|
||||||
SetStatusText(s, 0);
|
SetStatusText(s, 0);
|
||||||
sprintf(s, "Service: %d", addr.Service());
|
wxSprintf(s, _T("Service: %d"), addr.Service());
|
||||||
SetStatusText(s, 1);
|
SetStatusText(s, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +226,7 @@ void MyFrame::OnExecTest1(wxCommandEvent& WXUNUSED(evt))
|
|||||||
wxTE_MULTILINE);
|
wxTE_MULTILINE);
|
||||||
(void)new wxButton(dlgbox, ID_TEST_CLOSE, "Close",
|
(void)new wxButton(dlgbox, ID_TEST_CLOSE, "Close",
|
||||||
wxPoint(100, 210), wxSize(100, -1));
|
wxPoint(100, 210), wxSize(100, -1));
|
||||||
char *buf, *buf2;
|
wxChar *buf, *buf2;
|
||||||
|
|
||||||
dlgbox->Layout();
|
dlgbox->Layout();
|
||||||
dlgbox->Show(TRUE);
|
dlgbox->Show(TRUE);
|
||||||
@@ -235,21 +236,25 @@ void MyFrame::OnExecTest1(wxCommandEvent& WXUNUSED(evt))
|
|||||||
wxYield();
|
wxYield();
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
buf = copystring("Hi ! Hi ! Hi !\n");
|
buf = copystring(_T("Hi ! Hi ! Hi !\n"));
|
||||||
buf2 = new char[strlen(buf)+1];
|
buf2 = new wxChar[wxStrlen(buf)+1];
|
||||||
char c = 0xbe;
|
char c = 0xbe;
|
||||||
sock->WriteMsg(&c, 1);
|
sock->Write(&c, 1);
|
||||||
|
|
||||||
/* No 1 */
|
/* No 1 */
|
||||||
text_win->WriteText("Sending some byte to the server ...");
|
text_win->WriteText("Sending some byte to the server ...");
|
||||||
sock->Write(buf, strlen(buf)+1);
|
wxYield();
|
||||||
|
sock->Write((char *)buf, wxStrlen(buf)+1);
|
||||||
text_win->WriteText("done\n");
|
text_win->WriteText("done\n");
|
||||||
|
wxYield();
|
||||||
text_win->WriteText("Receiving some byte from the server ...");
|
text_win->WriteText("Receiving some byte from the server ...");
|
||||||
sock->Read(buf2, strlen(buf)+1);
|
wxYield();
|
||||||
|
sock->Read((char *)buf2, wxStrlen(buf)+1);
|
||||||
text_win->WriteText("done\n");
|
text_win->WriteText("done\n");
|
||||||
|
wxYield();
|
||||||
|
|
||||||
text_win->WriteText("Comparing the two buffers ...");
|
text_win->WriteText("Comparing the two buffers ...");
|
||||||
if (memcmp(buf, buf2, strlen(buf)+1) != 0) {
|
if (memcmp(buf, buf2, wxStrlen(buf)+1) != 0) {
|
||||||
text_win->WriteText("Fail\n");
|
text_win->WriteText("Fail\n");
|
||||||
sock->Close();
|
sock->Close();
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
@@ -276,7 +281,11 @@ void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
|
|||||||
if (!datas)
|
if (!datas)
|
||||||
wxMessageBox("Error in getting data from the URL.", "Alert !");
|
wxMessageBox("Error in getting data from the URL.", "Alert !");
|
||||||
else {
|
else {
|
||||||
|
wxFileOutputStream *str_out = new wxFileOutputStream("test.url");
|
||||||
|
str_out->Write(*datas);
|
||||||
|
|
||||||
wxMessageBox("Success !! Click on OK to see the text.", "OK");
|
wxMessageBox("Success !! Click on OK to see the text.", "OK");
|
||||||
delete datas;
|
delete datas;
|
||||||
|
delete str_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,37 +42,28 @@ class MyFrame: public wxFrame
|
|||||||
{
|
{
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
public:
|
public:
|
||||||
MyServer *sock;
|
wxSocketServer *sock;
|
||||||
int nb_clients;
|
int nb_clients;
|
||||||
|
|
||||||
MyFrame(wxFrame *frame);
|
MyFrame(wxFrame *frame);
|
||||||
virtual ~MyFrame();
|
virtual ~MyFrame();
|
||||||
void Menu_Exit(wxCommandEvent& evt);
|
void Menu_Exit(wxCommandEvent& evt);
|
||||||
|
void OnSockRequest(wxSocketEvent& evt);
|
||||||
|
void OnSockRequestServer(wxSocketEvent& evt);
|
||||||
void ExecTest1(wxSocketBase *sock_o);
|
void ExecTest1(wxSocketBase *sock_o);
|
||||||
void UpdateStatus(int incr);
|
void UpdateStatus(int incr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SKDEMO_QUIT 101
|
#define SKDEMO_QUIT 101
|
||||||
|
#define SKDEMO_SOCKET_SERV 102
|
||||||
|
#define SKDEMO_SOCKET 103
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
EVT_MENU(SKDEMO_QUIT, MyFrame::Menu_Exit)
|
EVT_MENU(SKDEMO_QUIT, MyFrame::Menu_Exit)
|
||||||
|
EVT_SOCKET(SKDEMO_SOCKET_SERV, MyFrame::OnSockRequestServer)
|
||||||
|
EVT_SOCKET(SKDEMO_SOCKET, MyFrame::OnSockRequest)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
class MySock: public wxSocketBase {
|
|
||||||
public:
|
|
||||||
MyFrame *frame;
|
|
||||||
|
|
||||||
void OldOnNotify(wxRequestEvent flags);
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyServer: public wxSocketServer {
|
|
||||||
public:
|
|
||||||
MyFrame *frame;
|
|
||||||
|
|
||||||
MyServer(wxSockAddress& addr) : wxSocketServer(addr) { }
|
|
||||||
void OldOnNotify(wxRequestEvent flags);
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_APP(MyApp)
|
IMPLEMENT_APP(MyApp)
|
||||||
|
|
||||||
// `Main program' equivalent, creating windows and returning main app frame
|
// `Main program' equivalent, creating windows and returning main app frame
|
||||||
@@ -102,40 +93,50 @@ bool MyApp::OnInit(void)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MySock::OldOnNotify(wxRequestEvent flags)
|
extern wxList wxPendingDelete;
|
||||||
{
|
|
||||||
extern wxList WXDLLEXPORT wxPendingDelete;
|
|
||||||
|
|
||||||
switch (flags) {
|
void MyFrame::OnSockRequest(wxSocketEvent& evt)
|
||||||
case EVT_READ:
|
{
|
||||||
|
wxSocketBase *sock = evt.Socket();
|
||||||
|
|
||||||
|
printf("OnSockRequest OK\n");
|
||||||
|
printf("OnSockRequest (event = %d)\n",evt.SocketEvent());
|
||||||
|
switch (evt.SocketEvent()) {
|
||||||
|
case wxSocketBase::EVT_READ:
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
ReadMsg((char *)&c, 1);
|
sock->Read((char *)&c, 1);
|
||||||
if (c == 0xbe)
|
if (c == 0xbe)
|
||||||
frame->ExecTest1(this);
|
ExecTest1(sock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EVT_LOST:
|
case wxSocketBase::EVT_LOST:
|
||||||
frame->UpdateStatus(-1);
|
UpdateStatus(-1);
|
||||||
wxPendingDelete.Append(this);
|
printf("Destroying socket\n");
|
||||||
|
wxPendingDelete.Append(sock);
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
printf("OnSockRequest Exiting\n");
|
||||||
|
sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyServer::OldOnNotify(wxRequestEvent WXUNUSED(flags))
|
void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
|
||||||
{
|
{
|
||||||
MySock *sock2 = new MySock();
|
wxSocketBase *sock2;
|
||||||
|
wxSocketServer *server = (wxSocketServer *) evt.Socket();
|
||||||
|
|
||||||
if (!AcceptWith(*sock2))
|
printf("OnSockRequestServer OK\n");
|
||||||
|
|
||||||
|
sock2 = server->Accept();
|
||||||
|
if (sock2 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_handler->Register(sock2);
|
sock2->SetFlags(wxSocketBase::NONE);
|
||||||
|
|
||||||
sock2->SetFlags(NONE);
|
|
||||||
sock2->frame = frame;
|
|
||||||
sock2->SetNotify(REQ_READ | REQ_LOST);
|
|
||||||
sock2->Notify(TRUE);
|
sock2->Notify(TRUE);
|
||||||
frame->UpdateStatus(1);
|
sock2->SetEventHandler(*this, SKDEMO_SOCKET);
|
||||||
|
server->SetNotify(wxSocketBase::REQ_ACCEPT);
|
||||||
|
UpdateStatus(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// My frame Constructor
|
// My frame Constructor
|
||||||
@@ -149,10 +150,10 @@ MyFrame::MyFrame(wxFrame *frame):
|
|||||||
// Init all
|
// Init all
|
||||||
wxSocketHandler::Master();
|
wxSocketHandler::Master();
|
||||||
|
|
||||||
sock = new MyServer(addr);
|
sock = new wxSocketServer(addr);
|
||||||
wxSocketHandler::Master().Register(sock);
|
wxSocketHandler::Master().Register(sock);
|
||||||
sock->frame = this;
|
|
||||||
sock->SetNotify(wxSocketBase::REQ_ACCEPT);
|
sock->SetNotify(wxSocketBase::REQ_ACCEPT);
|
||||||
|
sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
|
||||||
sock->Notify(TRUE);
|
sock->Notify(TRUE);
|
||||||
nb_clients = 0;
|
nb_clients = 0;
|
||||||
|
|
||||||
|
@@ -105,6 +105,22 @@ wxEvent::wxEvent(int theId)
|
|||||||
m_isCommandEvent = FALSE;
|
m_isCommandEvent = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxObject *wxEvent::Clone() const
|
||||||
|
{
|
||||||
|
wxEvent *event = (wxEvent *)wxObject::Clone();
|
||||||
|
|
||||||
|
event->m_eventType = m_eventType;
|
||||||
|
event->m_eventObject = m_eventObject;
|
||||||
|
event->m_eventHandle = m_eventHandle;
|
||||||
|
event->m_timeStamp = m_timeStamp;
|
||||||
|
event->m_id = m_id;
|
||||||
|
event->m_skipped = m_skipped;
|
||||||
|
event->m_callbackUserData = m_callbackUserData;
|
||||||
|
event->m_isCommandEvent = m_isCommandEvent;
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command events
|
* Command events
|
||||||
*
|
*
|
||||||
@@ -317,10 +333,10 @@ wxEvtHandler::~wxEvtHandler()
|
|||||||
delete m_dynamicEvents;
|
delete m_dynamicEvents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if wxUSE_THREADS
|
||||||
if (m_pendingEvents)
|
if (m_pendingEvents)
|
||||||
delete m_pendingEvents;
|
delete m_pendingEvents;
|
||||||
|
|
||||||
#if wxUSE_THREADS
|
|
||||||
delete m_eventsLocker;
|
delete m_eventsLocker;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -337,8 +353,7 @@ bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
|
|||||||
if (m_pendingEvents == NULL)
|
if (m_pendingEvents == NULL)
|
||||||
m_pendingEvents = new wxList();
|
m_pendingEvents = new wxList();
|
||||||
|
|
||||||
event_main = (wxEvent *)event.GetClassInfo()->CreateObject();
|
event_main = (wxEvent *)event.Clone();
|
||||||
*event_main = event;
|
|
||||||
|
|
||||||
m_pendingEvents->Append(event_main);
|
m_pendingEvents->Append(event_main);
|
||||||
|
|
||||||
|
@@ -60,16 +60,13 @@ IMPLEMENT_PROTOCOL(wxFTP, _T("ftp"), _T("ftp"), TRUE)
|
|||||||
wxFTP::wxFTP()
|
wxFTP::wxFTP()
|
||||||
: wxProtocol()
|
: wxProtocol()
|
||||||
{
|
{
|
||||||
wxChar tmp[256];
|
|
||||||
|
|
||||||
m_lastError = wxPROTO_NOERR;
|
m_lastError = wxPROTO_NOERR;
|
||||||
m_streaming = FALSE;
|
m_streaming = FALSE;
|
||||||
|
|
||||||
m_user = _T("anonymous");
|
m_user = _T("anonymous");
|
||||||
wxGetUserName(tmp, 256);
|
m_passwd = wxGetUserId();
|
||||||
m_passwd.sprintf(_T("%s@"),tmp);
|
m_passwd += '@';
|
||||||
wxGetHostName(tmp, 256);
|
m_passwd += wxGetHostName();
|
||||||
m_passwd += tmp;
|
|
||||||
|
|
||||||
SetNotify(0);
|
SetNotify(0);
|
||||||
}
|
}
|
||||||
@@ -404,9 +401,12 @@ wxList *wxFTP::GetList(const wxString& wildcard)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ininterresting ?!
|
||||||
|
/*
|
||||||
sock->SetEventHandler(*GetNextHandler(), m_id);
|
sock->SetEventHandler(*GetNextHandler(), m_id);
|
||||||
sock->Notify(m_notifyme);
|
sock->Notify(m_notifyme);
|
||||||
sock->SetNotify(m_neededreq);
|
sock->SetNotify(m_neededreq);
|
||||||
|
*/
|
||||||
|
|
||||||
return file_list;
|
return file_list;
|
||||||
}
|
}
|
||||||
|
@@ -116,6 +116,7 @@ void wxHTTP::SendHeaders()
|
|||||||
bool wxHTTP::ParseHeaders()
|
bool wxHTTP::ParseHeaders()
|
||||||
{
|
{
|
||||||
wxString line;
|
wxString line;
|
||||||
|
wxStringTokenizer tokenzr;
|
||||||
|
|
||||||
m_headers.Clear();
|
m_headers.Clear();
|
||||||
m_read = TRUE;
|
m_read = TRUE;
|
||||||
@@ -128,17 +129,13 @@ bool wxHTTP::ParseHeaders()
|
|||||||
if (line.Length() == 0)
|
if (line.Length() == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
wxPrintf(_T("Header: %s\n"), WXSTRINGCAST line);
|
printf("Header: %s\n", WXSTRINGCAST line);
|
||||||
int pos = line.Find(':');
|
tokenzr.SetString(line, " :\t\n\r");
|
||||||
if (pos == -1)
|
if (!tokenzr.HasMoreToken())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
wxString left_str = line(0, pos);
|
wxString left_str = tokenzr.GetNextToken();
|
||||||
wxString right_str = line(pos+1, line.Length());
|
wxString *str = new wxString(tokenzr.GetNextToken());
|
||||||
|
|
||||||
right_str = right_str.Strip(wxString::leading);
|
|
||||||
|
|
||||||
wxString *str = new wxString(right_str);
|
|
||||||
|
|
||||||
m_headers.Append(left_str, (wxObject *) str);
|
m_headers.Append(left_str, (wxObject *) str);
|
||||||
}
|
}
|
||||||
|
@@ -87,6 +87,11 @@ bool wxObject::IsKindOf(wxClassInfo *info) const
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxObject *wxObject::Clone() const
|
||||||
|
{
|
||||||
|
return GetClassInfo()->CreateObject();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT
|
#if defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT
|
||||||
void wxObject::Dump(ostream& str)
|
void wxObject::Dump(ostream& str)
|
||||||
{
|
{
|
||||||
|
504
src/common/sckint.cpp
Normal file
504
src/common/sckint.cpp
Normal file
@@ -0,0 +1,504 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: socket.cpp
|
||||||
|
// Purpose: Socket handler classes
|
||||||
|
// Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
|
||||||
|
// Davidson(1995) in wxWeb)
|
||||||
|
// Created: April 1997
|
||||||
|
// Updated: April 1999
|
||||||
|
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
|
||||||
|
// RCS_ID: $Id$
|
||||||
|
// License: see wxWindows license
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation "sckint.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_SOCKETS
|
||||||
|
|
||||||
|
#define WXSOCK_INTERNAL
|
||||||
|
#include <wx/object.h>
|
||||||
|
#include <wx/list.h>
|
||||||
|
#include <wx/socket.h>
|
||||||
|
#include <wx/thread.h>
|
||||||
|
#include <wx/sckint.h>
|
||||||
|
|
||||||
|
#ifndef __WXSTUBS__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
// System specific headers
|
||||||
|
// -----------------------
|
||||||
|
|
||||||
|
#ifdef __WXMAC__
|
||||||
|
// in order to avoid problems with our c library and double definitions
|
||||||
|
#define close closesocket
|
||||||
|
#define ioctl ioctlsocket
|
||||||
|
|
||||||
|
#include <wx/mac/macsock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__WINDOWS__)
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif // __WINDOWS__
|
||||||
|
|
||||||
|
#if defined(__UNIX__)
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
#include <socket.h>
|
||||||
|
#else
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef sun
|
||||||
|
#include <sys/filio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __UNIX__
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define READ_MASK wxSocketBase::REQ_READ | wxSocketBase::REQ_ACCEPT | wxSocketBase::REQ_LOST
|
||||||
|
#define WRITE_MASK wxSocketBase::REQ_WRITE | wxSocketBase::REQ_CONNECT
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// --------- SocketWaiter ---------------------------------------
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
SocketWaiter::SocketWaiter(wxSocketBase *socket,
|
||||||
|
wxSocketInternal *internal)
|
||||||
|
: m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketWaiter::~SocketWaiter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketWaiter::ProcessReadEvent()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
ret = recv(m_fd, &c, 1, MSG_PEEK);
|
||||||
|
|
||||||
|
// We are a server => emit a EVT_ACCEPT event.
|
||||||
|
if (ret == -1 && m_socket->GetType() == wxSocketBase::SOCK_SERVER) {
|
||||||
|
m_socket->OnRequest(wxSocketBase::EVT_ACCEPT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else, no error => there is something to be read else
|
||||||
|
// we've lost the connection.
|
||||||
|
if (ret > 0)
|
||||||
|
m_socket->OnRequest(wxSocketBase::EVT_READ);
|
||||||
|
else {
|
||||||
|
m_socket->OnRequest(wxSocketBase::EVT_LOST);
|
||||||
|
Exit(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketWaiter::ProcessWriteEvent()
|
||||||
|
{
|
||||||
|
if (m_socket->IsConnected())
|
||||||
|
m_socket->OnRequest(wxSocketBase::EVT_CONNECT);
|
||||||
|
else
|
||||||
|
m_socket->OnRequest(wxSocketBase::EVT_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *SocketWaiter::Entry()
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set sockrd_set, sockwr_set;
|
||||||
|
wxSocketEvent event;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// We won't wait.
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&sockrd_set);
|
||||||
|
FD_ZERO(&sockwr_set);
|
||||||
|
|
||||||
|
if ((m_socket->NeededReq() & READ_MASK) != 0)
|
||||||
|
FD_SET(m_fd, &sockrd_set);
|
||||||
|
if ((m_socket->NeededReq() & WRITE_MASK) != 0)
|
||||||
|
FD_SET(m_fd, &sockwr_set);
|
||||||
|
|
||||||
|
m_internal->AcquireFD();
|
||||||
|
ret = select(FD_SETSIZE, &sockrd_set, &sockwr_set, NULL, &tv);
|
||||||
|
m_internal->ReleaseFD();
|
||||||
|
|
||||||
|
if (FD_ISSET(m_fd, &sockrd_set))
|
||||||
|
ProcessReadEvent();
|
||||||
|
|
||||||
|
if (FD_ISSET(m_fd, &sockwr_set))
|
||||||
|
ProcessWriteEvent();
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
// If nothing happened, we wait for 100 ms.
|
||||||
|
wxThread::Sleep(10);
|
||||||
|
else
|
||||||
|
wxThread::Yield();
|
||||||
|
|
||||||
|
// Check whether we should exit.
|
||||||
|
if (TestDestroy())
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// --------- SocketRequester ------------------------------------
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
SocketRequester::SocketRequester(wxSocketBase *socket,
|
||||||
|
wxSocketInternal *internal)
|
||||||
|
: m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketRequester::~SocketRequester()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketRequester::WaitFor(wxSocketBase::wxRequestNotify req, int millisec)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set sockrd_set, sockwr_set;
|
||||||
|
|
||||||
|
// We won't wait.
|
||||||
|
tv.tv_sec = millisec / 1000;
|
||||||
|
tv.tv_usec = (millisec % 1000) * 1000;
|
||||||
|
|
||||||
|
if ((req & READ_MASK) != 0)
|
||||||
|
FD_ZERO(&sockrd_set);
|
||||||
|
FD_ZERO(&sockwr_set);
|
||||||
|
|
||||||
|
FD_SET(m_fd, &sockrd_set);
|
||||||
|
FD_SET(m_fd, &sockwr_set);
|
||||||
|
|
||||||
|
m_internal->AcquireFD();
|
||||||
|
ret = select(FD_SETSIZE, &sockrd_set, &sockwr_set, NULL, &tv);
|
||||||
|
m_internal->ReleaseFD();
|
||||||
|
|
||||||
|
return (ret != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketRequester::ProcessReadEvent(SockRequest *req)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
// We'll wait for the first byte, in case a "timeout event" occurs it returns // immediately
|
||||||
|
if (!WaitFor(wxSocketBase::REQ_READ, req->timeout)) {
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_internal->AcquireFD();
|
||||||
|
ret = recv(m_fd, req->buffer, req->size,
|
||||||
|
(req->type == wxSocketBase::REQ_PEEK) ? MSG_PEEK : 0);
|
||||||
|
m_internal->ReleaseFD();
|
||||||
|
|
||||||
|
// An error occured, we exit.
|
||||||
|
if (ret < 0) {
|
||||||
|
req->error = errno;
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
len = ret;
|
||||||
|
|
||||||
|
// If the buffer isn't full (and we want it to be full), we don't unqueue it.
|
||||||
|
if ((len < req->size) && (m_socket->GetFlags() & wxSocketBase::WAITALL)) {
|
||||||
|
req->size -= len;
|
||||||
|
req->io_nbytes += len;
|
||||||
|
req->buffer += len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// The End.
|
||||||
|
req->io_nbytes += len;
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketRequester::ProcessWriteEvent(SockRequest *req)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
m_internal->AcquireFD();
|
||||||
|
ret = send(m_fd, req->buffer, req->size, 0);
|
||||||
|
m_internal->ReleaseFD();
|
||||||
|
if (ret < 0) {
|
||||||
|
req->error = errno;
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
len = ret;
|
||||||
|
if ((len < req->size) && ((m_socket->GetFlags() & wxSocketBase::WAITALL) != 0)) {
|
||||||
|
req->size -= len;
|
||||||
|
req->io_nbytes += len;
|
||||||
|
req->buffer += len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
req->io_nbytes += len;
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketRequester::ProcessWaitEvent(SockRequest *req)
|
||||||
|
{
|
||||||
|
if (WaitFor(req->type, req->timeout))
|
||||||
|
req->io_nbytes = 1; // We put 1 in the counter to tell the requester
|
||||||
|
// there is no timeout.
|
||||||
|
else
|
||||||
|
req->io_nbytes = 0;
|
||||||
|
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *SocketRequester::Entry()
|
||||||
|
{
|
||||||
|
SockRequest *req;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Wait for a new request or a destroy message.
|
||||||
|
req = m_internal->WaitForReq();
|
||||||
|
if (TestDestroy() || req == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((req->type & wxSocketBase::REQ_WAIT) != 0) {
|
||||||
|
ProcessWaitEvent(req);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (req->type) {
|
||||||
|
case wxSocketBase::REQ_READ:
|
||||||
|
case wxSocketBase::REQ_PEEK:
|
||||||
|
ProcessReadEvent(req);
|
||||||
|
break;
|
||||||
|
case wxSocketBase::REQ_WRITE:
|
||||||
|
ProcessWriteEvent(req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// --------- wxSocketInternal -----------------------------------
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
wxSocketInternal::wxSocketInternal(wxSocketBase *socket)
|
||||||
|
{
|
||||||
|
m_socket = socket;
|
||||||
|
m_thread_waiter = new SocketWaiter(socket, this);
|
||||||
|
m_thread_requester = new SocketRequester(socket, this);
|
||||||
|
m_request_locker.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxSocketInternal::~wxSocketInternal()
|
||||||
|
{
|
||||||
|
wxASSERT(!m_finalized);
|
||||||
|
m_request_locker.Unlock();
|
||||||
|
delete m_thread_waiter;
|
||||||
|
delete m_thread_requester;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// WaitForReq: it is called by SocketRequester and should return the next
|
||||||
|
// socket request if available
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
SockRequest *wxSocketInternal::WaitForReq()
|
||||||
|
{
|
||||||
|
wxNode *node;
|
||||||
|
|
||||||
|
node = m_requests.First();
|
||||||
|
if (node == NULL) {
|
||||||
|
m_socket_cond.Wait(m_request_locker);
|
||||||
|
|
||||||
|
node = m_requests.First();
|
||||||
|
if (node == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SockRequest *)node->Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// EndRequest: Should be called to finalize a request
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void wxSocketInternal::EndRequest(SockRequest *req)
|
||||||
|
{
|
||||||
|
wxNode *node = NULL;
|
||||||
|
|
||||||
|
req->done = TRUE;
|
||||||
|
|
||||||
|
node = m_requests.Member((wxObject *)req);
|
||||||
|
if (node != NULL)
|
||||||
|
delete node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::AcquireFD()
|
||||||
|
{
|
||||||
|
m_fd_locker.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::ReleaseFD()
|
||||||
|
{
|
||||||
|
m_fd_locker.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// InitializeSocket: called by wxSocketBase to initialize the daemons with
|
||||||
|
// a new file descriptor and to create them
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void wxSocketInternal::InitializeSocket()
|
||||||
|
{
|
||||||
|
wxASSERT( ((m_thread_waiter->IsAlive() && !m_thread_waiter->IsPaused()) ||
|
||||||
|
(m_thread_requester->IsAlive() && !m_thread_requester->IsPaused())));
|
||||||
|
|
||||||
|
m_thread_waiter->m_fd = m_socket->m_fd;
|
||||||
|
m_thread_requester->m_fd = m_socket->m_fd;
|
||||||
|
|
||||||
|
if (m_thread_waiter->IsPaused())
|
||||||
|
ResumeSocket();
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (m_thread_waiter->Create() != wxTHREAD_NO_ERROR) {
|
||||||
|
// Something should be done here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_thread_requester->Create() != wxTHREAD_NO_ERROR) {
|
||||||
|
// Something should be done here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_thread_waiter->Run();
|
||||||
|
m_thread_requester->Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// InitializeSocket: called by wxSocketBase to destroy daemons
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void wxSocketInternal::FinalizeSocket()
|
||||||
|
{
|
||||||
|
wxASSERT( (!m_thread_waiter->IsAlive() && !m_thread_requester->IsAlive()) );
|
||||||
|
|
||||||
|
ResumeSocket();
|
||||||
|
|
||||||
|
m_thread_waiter->Delete();
|
||||||
|
m_socket_locker.Lock();
|
||||||
|
if (m_requests.Number() == 0)
|
||||||
|
m_socket_cond.Signal();
|
||||||
|
m_socket_locker.Unlock();
|
||||||
|
|
||||||
|
m_thread_requester->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::PauseSocket()
|
||||||
|
{
|
||||||
|
if (m_thread_waiter != NULL && !m_thread_waiter->IsPaused())
|
||||||
|
m_thread_waiter->Pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::ResumeSocket()
|
||||||
|
{
|
||||||
|
if (m_thread_waiter != NULL && m_thread_waiter->IsPaused())
|
||||||
|
m_thread_waiter->Resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::EnableWaiter()
|
||||||
|
{
|
||||||
|
if (m_thread_waiter != NULL && m_thread_waiter->IsPaused())
|
||||||
|
m_thread_waiter->Resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::DisableWaiter()
|
||||||
|
{
|
||||||
|
if (m_thread_waiter != NULL && !m_thread_waiter->IsPaused())
|
||||||
|
m_thread_waiter->Pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// QueueRequest:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
|
||||||
|
{
|
||||||
|
if (async) {
|
||||||
|
m_request_locker.Lock();
|
||||||
|
request->done = FALSE;
|
||||||
|
m_requests.Append((wxObject *)request);
|
||||||
|
m_request_locker.Unlock();
|
||||||
|
|
||||||
|
// Wake up
|
||||||
|
m_socket_cond.Signal();
|
||||||
|
|
||||||
|
if (request->wait) {
|
||||||
|
if (wxThread::IsMain())
|
||||||
|
while (!request->done) {
|
||||||
|
wxYield();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (!request->done) {
|
||||||
|
wxThread::Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
m_request_locker.Lock();
|
||||||
|
|
||||||
|
if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
|
||||||
|
m_thread_requester->ProcessWaitEvent(request);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
request->done = FALSE;
|
||||||
|
|
||||||
|
switch (request->type) {
|
||||||
|
case wxSocketBase::REQ_PEEK:
|
||||||
|
case wxSocketBase::REQ_READ:
|
||||||
|
m_thread_requester->ProcessReadEvent(request);
|
||||||
|
break;
|
||||||
|
case wxSocketBase::REQ_WRITE:
|
||||||
|
m_thread_requester->ProcessWriteEvent(request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request->done = TRUE;
|
||||||
|
m_request_locker.Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSocketInternal::WaitForEnd(SockRequest *request)
|
||||||
|
{
|
||||||
|
// TODOTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// __WXSTUBS__
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// wxUSE_SOCKETS
|
File diff suppressed because it is too large
Load Diff
@@ -63,6 +63,7 @@ LIB_CPP_SRC=\
|
|||||||
common/valtext.cpp \
|
common/valtext.cpp \
|
||||||
common/variant.cpp \
|
common/variant.cpp \
|
||||||
common/socket.cpp \
|
common/socket.cpp \
|
||||||
|
common/sckint.cpp \
|
||||||
common/sckaddr.cpp \
|
common/sckaddr.cpp \
|
||||||
common/sckipc.cpp \
|
common/sckipc.cpp \
|
||||||
common/protocol.cpp \
|
common/protocol.cpp \
|
||||||
|
@@ -62,6 +62,7 @@ LIB_CPP_SRC=\
|
|||||||
../common/variant.cpp \
|
../common/variant.cpp \
|
||||||
../common/wxexpr.cpp \
|
../common/wxexpr.cpp \
|
||||||
../common/socket.cpp \
|
../common/socket.cpp \
|
||||||
|
../common/sckint.cpp \
|
||||||
../common/sckaddr.cpp \
|
../common/sckaddr.cpp \
|
||||||
../common/sckipc.cpp \
|
../common/sckipc.cpp \
|
||||||
../common/protocol.cpp \
|
../common/protocol.cpp \
|
||||||
|
@@ -62,6 +62,7 @@ LIB_CPP_SRC=\
|
|||||||
../common/variant.cpp \
|
../common/variant.cpp \
|
||||||
../common/wxexpr.cpp \
|
../common/wxexpr.cpp \
|
||||||
../common/socket.cpp \
|
../common/socket.cpp \
|
||||||
|
../common/sckint.cpp \
|
||||||
../common/sckaddr.cpp \
|
../common/sckaddr.cpp \
|
||||||
../common/sckipc.cpp \
|
../common/sckipc.cpp \
|
||||||
../common/protocol.cpp \
|
../common/protocol.cpp \
|
||||||
|
@@ -151,6 +151,7 @@ COMMONOBJS = \
|
|||||||
$(MSWDIR)\dynlib.obj \
|
$(MSWDIR)\dynlib.obj \
|
||||||
$(MSWDIR)\tokenzr.obj \
|
$(MSWDIR)\tokenzr.obj \
|
||||||
$(MSWDIR)\socket.obj \
|
$(MSWDIR)\socket.obj \
|
||||||
|
$(MSWDIR)\sckint.obj \
|
||||||
$(MSWDIR)\sckaddr.obj \
|
$(MSWDIR)\sckaddr.obj \
|
||||||
$(MSWDIR)\protocol.obj \
|
$(MSWDIR)\protocol.obj \
|
||||||
$(MSWDIR)\url.obj \
|
$(MSWDIR)\url.obj \
|
||||||
|
@@ -77,6 +77,7 @@ COMMONOBJS = cmndata.obj \
|
|||||||
paper.obj \
|
paper.obj \
|
||||||
string.obj \
|
string.obj \
|
||||||
socket.obj \
|
socket.obj \
|
||||||
|
sckint.obj \
|
||||||
sckaddr.obj \
|
sckaddr.obj \
|
||||||
sckfile.obj \
|
sckfile.obj \
|
||||||
sckipc.obj \
|
sckipc.obj \
|
||||||
@@ -628,6 +629,9 @@ string.obj: $(COMMDIR)\string.cpp
|
|||||||
socket.obj: $(COMMDIR)\socket.cpp
|
socket.obj: $(COMMDIR)\socket.cpp
|
||||||
$(CCC) $(CPPFLAGS) $(IFLAGS) $(COMMDIR)\socket.cpp /BINARY socket.obj
|
$(CCC) $(CPPFLAGS) $(IFLAGS) $(COMMDIR)\socket.cpp /BINARY socket.obj
|
||||||
|
|
||||||
|
sckint.obj: $(COMMDIR)\sckint.cpp
|
||||||
|
$(CCC) $(CPPFLAGS) $(IFLAGS) $(COMMDIR)\sckint.cpp /BINARY sckint.obj
|
||||||
|
|
||||||
sckaddr.obj: $(COMMDIR)\sckaddr.cpp
|
sckaddr.obj: $(COMMDIR)\sckaddr.cpp
|
||||||
$(CCC) $(CPPFLAGS) $(IFLAGS) $(COMMDIR)\sckaddr.cpp /BINARY sckaddr.obj
|
$(CCC) $(CPPFLAGS) $(IFLAGS) $(COMMDIR)\sckaddr.cpp /BINARY sckaddr.obj
|
||||||
|
|
||||||
|
@@ -141,6 +141,7 @@ COMMONOBJS = \
|
|||||||
..\common\$D\paper.obj \
|
..\common\$D\paper.obj \
|
||||||
..\common\$D\string.obj \
|
..\common\$D\string.obj \
|
||||||
..\common\$D\socket.obj \
|
..\common\$D\socket.obj \
|
||||||
|
..\common\$D\socket.obj \
|
||||||
..\common\$D\sckaddr.obj \
|
..\common\$D\sckaddr.obj \
|
||||||
..\common\$D\sckfile.obj \
|
..\common\$D\sckfile.obj \
|
||||||
..\common\$D\sckipc.obj \
|
..\common\$D\sckipc.obj \
|
||||||
|
@@ -664,6 +664,13 @@ bool wxThread::IsAlive() const
|
|||||||
(p_internal->GetState() == STATE_PAUSED);
|
(p_internal->GetState() == STATE_PAUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxThread::IsPaused() const
|
||||||
|
{
|
||||||
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
||||||
|
|
||||||
|
return (p_internal->GetState() == STATE_PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
bool wxThread::TestDestroy()
|
bool wxThread::TestDestroy()
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
||||||
|
@@ -325,7 +325,8 @@ wxThreadInternal::wxThreadInternal()
|
|||||||
|
|
||||||
wxThreadInternal::~wxThreadInternal()
|
wxThreadInternal::~wxThreadInternal()
|
||||||
{
|
{
|
||||||
m_mutexSuspend.Unlock();
|
// GL: moved to SignalExit
|
||||||
|
// m_mutexSuspend.Unlock();
|
||||||
|
|
||||||
// note that m_mutex will be unlocked by the thread which waits for our
|
// note that m_mutex will be unlocked by the thread which waits for our
|
||||||
// termination
|
// termination
|
||||||
@@ -375,6 +376,9 @@ void wxThreadInternal::Wait()
|
|||||||
|
|
||||||
void wxThreadInternal::SignalExit()
|
void wxThreadInternal::SignalExit()
|
||||||
{
|
{
|
||||||
|
// GL: Unlock mutexSuspend here.
|
||||||
|
m_mutexSuspend.Unlock();
|
||||||
|
|
||||||
// as mutex is currently locked, this will block until some other thread
|
// as mutex is currently locked, this will block until some other thread
|
||||||
// (normally the same which created this one) unlocks it by entering Wait()
|
// (normally the same which created this one) unlocks it by entering Wait()
|
||||||
m_mutex.Lock();
|
m_mutex.Lock();
|
||||||
@@ -453,9 +457,7 @@ wxThread::wxThread()
|
|||||||
|
|
||||||
wxThreadError wxThread::Create()
|
wxThreadError wxThread::Create()
|
||||||
{
|
{
|
||||||
// Maybe we could think about recreate the thread once it has exited.
|
if (p_internal->GetState() != STATE_NEW)
|
||||||
if (p_internal->GetState() != STATE_NEW &&
|
|
||||||
p_internal->GetState() != STATE_EXITED)
|
|
||||||
return wxTHREAD_RUNNING;
|
return wxTHREAD_RUNNING;
|
||||||
|
|
||||||
// set up the thread attribute: right now, we only set thread priority
|
// set up the thread attribute: right now, we only set thread priority
|
||||||
@@ -590,7 +592,9 @@ wxThreadError wxThread::Resume()
|
|||||||
|
|
||||||
if ( p_internal->GetState() == STATE_PAUSED )
|
if ( p_internal->GetState() == STATE_PAUSED )
|
||||||
{
|
{
|
||||||
|
m_critsect.Leave();
|
||||||
p_internal->Resume();
|
p_internal->Resume();
|
||||||
|
m_critsect.Enter();
|
||||||
|
|
||||||
return wxTHREAD_NO_ERROR;
|
return wxTHREAD_NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -727,6 +731,13 @@ bool wxThread::IsAlive() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxThread::IsPaused() const
|
||||||
|
{
|
||||||
|
wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect);
|
||||||
|
|
||||||
|
return (p_internal->GetState() == STATE_PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// wxThreadModule
|
// wxThreadModule
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user