Renamed GSocket_SetBlocking to GSocket_SetNonBlocking and *Fallback to *Callback
Added GSocket_SetTimeout Added timeout support in wxSocket (as it was in previous releases) Updated documentation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3215 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -128,32 +128,62 @@ bool wxSocketBase::Close()
|
||||
// --------------------------------------------------------------
|
||||
// wxSocketBase base IO function
|
||||
// --------------------------------------------------------------
|
||||
class _wxSocketInternalTimer: public wxTimer {
|
||||
public:
|
||||
int *m_state;
|
||||
int m_new_val;
|
||||
|
||||
void Notify()
|
||||
{
|
||||
*m_state = m_new_val; // Change the value
|
||||
}
|
||||
};
|
||||
|
||||
int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
|
||||
{
|
||||
GSocketEventFlags old_event_flags;
|
||||
bool old_notify_state;
|
||||
// Timer for timeout
|
||||
_wxSocketInternalTimer timer;
|
||||
|
||||
wxASSERT(m_defering == NO_DEFER);
|
||||
|
||||
// Set the defering mode to READ.
|
||||
m_defering = DEFER_READ;
|
||||
|
||||
// Save the old state.
|
||||
old_event_flags = NeededReq();
|
||||
old_notify_state = m_notify_state;
|
||||
|
||||
// Set the new async flag.
|
||||
SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
|
||||
Notify(TRUE);
|
||||
|
||||
// Set the current buffer.
|
||||
m_defer_buffer = buffer;
|
||||
m_defer_nbytes = nbytes;
|
||||
m_defer_timer = &timer;
|
||||
|
||||
timer.m_state = (int *)&m_defer_buffer;
|
||||
timer.m_new_val = (int)NULL;
|
||||
|
||||
timer.Start(m_timeout * 1000, FALSE);
|
||||
|
||||
// Wait for buffer completion.
|
||||
while (m_defer_buffer != NULL)
|
||||
wxYield();
|
||||
|
||||
timer.Stop();
|
||||
|
||||
// Restore the old state.
|
||||
Notify(old_notify_state);
|
||||
SetNotify(old_event_flags);
|
||||
|
||||
// Disable defering mode.
|
||||
m_defering = NO_DEFER;
|
||||
m_defer_timer = NULL;
|
||||
|
||||
// Return the number of bytes read from the socket.
|
||||
return nbytes-m_defer_nbytes;
|
||||
}
|
||||
|
||||
@@ -272,22 +302,39 @@ int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
|
||||
{
|
||||
GSocketEventFlags old_event_flags;
|
||||
bool old_notify_state;
|
||||
// Timer for timeout
|
||||
_wxSocketInternalTimer timer;
|
||||
|
||||
wxASSERT(m_defering == NO_DEFER);
|
||||
|
||||
m_defering = DEFER_WRITE;
|
||||
|
||||
// Save the old state
|
||||
old_event_flags = NeededReq();
|
||||
old_notify_state = m_notify_state;
|
||||
|
||||
SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
|
||||
Notify(TRUE);
|
||||
|
||||
// Set the current buffer
|
||||
m_defer_buffer = (char *)buffer;
|
||||
m_defer_nbytes = nbytes;
|
||||
|
||||
// Start timer
|
||||
timer.m_state = (int *)&m_defer_buffer;
|
||||
timer.m_new_val = (int)NULL;
|
||||
|
||||
m_defer_timer = &timer;
|
||||
timer.Start(m_timeout * 1000, FALSE);
|
||||
|
||||
while (m_defer_buffer != NULL)
|
||||
wxYield();
|
||||
|
||||
// Stop timer
|
||||
m_defer_timer = NULL;
|
||||
timer.Stop();
|
||||
|
||||
// Restore the old state
|
||||
Notify(old_notify_state);
|
||||
SetNotify(old_event_flags);
|
||||
|
||||
@@ -396,11 +443,15 @@ void wxSocketBase::DoDefer(GSocketEvent req_evt)
|
||||
if (ret < 0)
|
||||
m_defer_nbytes++;
|
||||
|
||||
// If we are waiting for all bytes to be acquired, keep the defering modei
|
||||
// enabled.
|
||||
if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) {
|
||||
m_defer_buffer = NULL;
|
||||
Notify(FALSE);
|
||||
} else
|
||||
} else {
|
||||
m_defer_buffer += ret;
|
||||
m_defer_timer->Start(m_timeout * 1000, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@@ -522,16 +573,6 @@ char *wxSocketBase::CallbackData(char *data)
|
||||
// --------- wxSocketBase wait functions ------------------------
|
||||
// --------------------------------------------------------------
|
||||
|
||||
class _wxSocketInternalTimer: public wxTimer {
|
||||
public:
|
||||
int *m_state;
|
||||
|
||||
void Notify()
|
||||
{
|
||||
*m_state = GSOCK_MAX_EVENT; // Just to say it's a timeout.
|
||||
}
|
||||
};
|
||||
|
||||
static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
|
||||
{
|
||||
int *state = (int *)cdata;
|
||||
@@ -542,25 +583,30 @@ static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
|
||||
bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
|
||||
{
|
||||
bool old_notify_state = m_notify_state;
|
||||
int state = 0;
|
||||
int state = -1;
|
||||
_wxSocketInternalTimer timer;
|
||||
|
||||
if (!m_connected || !m_socket)
|
||||
return FALSE;
|
||||
|
||||
// Set the variable to change
|
||||
timer.m_state = &state;
|
||||
timer.m_new_val = GSOCK_MAX_EVENT;
|
||||
|
||||
// Disable the previous handler
|
||||
Notify(FALSE);
|
||||
|
||||
// Set the timeout
|
||||
timer.Start(seconds * 1000 + milliseconds, TRUE);
|
||||
GSocket_SetFallback(m_socket, type, wx_socket_wait, (char *)&state);
|
||||
GSocket_SetCallback(m_socket, type, wx_socket_wait, (char *)&state);
|
||||
|
||||
while (state == 0)
|
||||
while (state == -1)
|
||||
wxYield();
|
||||
|
||||
GSocket_UnsetFallback(m_socket, type);
|
||||
GSocket_UnsetCallback(m_socket, type);
|
||||
timer.Stop();
|
||||
|
||||
// Notify will restore automatically the old GSocket flags
|
||||
Notify(old_notify_state);
|
||||
|
||||
return (state != GSOCK_MAX_EVENT);
|
||||
@@ -649,12 +695,12 @@ void wxSocketBase::Notify(bool notify)
|
||||
if (!m_socket)
|
||||
return;
|
||||
|
||||
GSocket_UnsetFallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
|
||||
GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
|
||||
GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
|
||||
if (!notify)
|
||||
return;
|
||||
|
||||
GSocket_SetFallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
|
||||
GSocket_SetCallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
|
||||
}
|
||||
|
||||
void wxSocketBase::OnRequest(GSocketEvent req_evt)
|
||||
|
@@ -53,7 +53,7 @@ void _GSocket_GUI_Destroy(GSocket *socket)
|
||||
free(socket->m_gui_dependent);
|
||||
}
|
||||
|
||||
void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
GdkInputCondition flag;
|
||||
int c;
|
||||
@@ -76,7 +76,7 @@ void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
_GSocket_GDK_Input, (gpointer)socket);
|
||||
}
|
||||
|
||||
void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
int c;
|
||||
gint *m_id;
|
||||
|
@@ -53,7 +53,7 @@ void _GSocket_GUI_Destroy(GSocket *socket)
|
||||
free(socket->m_gui_dependent);
|
||||
}
|
||||
|
||||
void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
GdkInputCondition flag;
|
||||
int c;
|
||||
@@ -76,7 +76,7 @@ void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
_GSocket_GDK_Input, (gpointer)socket);
|
||||
}
|
||||
|
||||
void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
int c;
|
||||
gint *m_id;
|
||||
|
@@ -59,7 +59,7 @@ void _GSocket_GUI_Destroy(GSocket *socket)
|
||||
free(socket->m_gui_dependent);
|
||||
}
|
||||
|
||||
void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
int *m_id;
|
||||
|
||||
@@ -88,7 +88,7 @@ void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
int c;
|
||||
int *m_id;
|
||||
|
@@ -16,11 +16,11 @@ void _GSocket_GUI_Destroy(GSocket *socket)
|
||||
{
|
||||
}
|
||||
|
||||
void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
|
||||
void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -88,6 +88,8 @@ GSocket *GSocket_new()
|
||||
socket->m_stream = TRUE;
|
||||
socket->m_gui_dependent = NULL;
|
||||
socket->m_blocking = FALSE;
|
||||
socket->m_timeout = 10*60*1000;
|
||||
// 10 minutes * 60 sec * 1000 millisec
|
||||
|
||||
/* We initialize the GUI specific entries here */
|
||||
_GSocket_GUI_Init(socket);
|
||||
@@ -132,7 +134,7 @@ void GSocket_Shutdown(GSocket *socket)
|
||||
|
||||
/* We also disable GUI callbacks */
|
||||
for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
|
||||
_GSocket_Uninstall_Fallback(socket, evt);
|
||||
_GSocket_Uninstall_Callback(socket, evt);
|
||||
}
|
||||
|
||||
/* Address handling */
|
||||
@@ -267,6 +269,9 @@ GSocketError GSocket_SetServer(GSocket *sck)
|
||||
return GSOCK_IOERR;
|
||||
}
|
||||
|
||||
GSocket_SetNonBlocking(sck, sck->m_blocking);
|
||||
GSocket_SetTimeout(sck, sck->m_timeout);
|
||||
|
||||
return GSOCK_NOERROR;
|
||||
}
|
||||
|
||||
@@ -338,6 +343,9 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
|
||||
return GSOCK_IOERR;
|
||||
}
|
||||
|
||||
GSocket_SetBlocking(sck, sck->m_blocking);
|
||||
GSocket_SetTimeout(sck, sck->m_timeout);
|
||||
|
||||
return GSOCK_NOERROR;
|
||||
}
|
||||
|
||||
@@ -393,6 +401,9 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
|
||||
/* It is not a server */
|
||||
sck->m_server = FALSE;
|
||||
|
||||
GSocket_SetBlocking(sck, sck->m_blocking);
|
||||
GSocket_SetTimeout(sck, sck->m_timeout);
|
||||
|
||||
return GSOCK_NOERROR;
|
||||
}
|
||||
|
||||
@@ -461,10 +472,10 @@ bool GSocket_DataAvailable(GSocket *socket)
|
||||
/* Flags */
|
||||
|
||||
/*
|
||||
GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
|
||||
GSocket_SetNonBlocking() puts the socket in non-blocking mode. This is useful
|
||||
if we don't want to wait.
|
||||
*/
|
||||
void GSocket_SetBlocking(GSocket *socket, bool block)
|
||||
void GSocket_SetNonBlocking(GSocket *socket, bool block)
|
||||
{
|
||||
assert(socket != NULL);
|
||||
|
||||
@@ -474,6 +485,24 @@ void GSocket_SetBlocking(GSocket *socket, bool block)
|
||||
ioctl(socket->m_fd, FIONBIO, &block);
|
||||
}
|
||||
|
||||
/*
|
||||
* GSocket_SetTimeout()
|
||||
*/
|
||||
void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
|
||||
{
|
||||
assert(socket != NULL);
|
||||
|
||||
socket->m_timeout = millisec;
|
||||
if (socket->m_fd != -1) {
|
||||
struct timeval tval;
|
||||
|
||||
tval.tv_sec = millisec / 1000;
|
||||
tval.tv_usec = (millisec % 1000) * 1000;
|
||||
setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
|
||||
setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
GSocket_GetError() returns the last error occured on the socket stream.
|
||||
*/
|
||||
@@ -498,7 +527,7 @@ GSocketError GSocket_GetError(GSocket *socket)
|
||||
Server socket -> a client request a connection
|
||||
LOST: the connection is lost
|
||||
|
||||
SetFallback accepts a combination of these flags so a same callback can
|
||||
SetCallback accepts a combination of these flags so a same callback can
|
||||
receive different events.
|
||||
|
||||
An event is generated only once and its state is reseted when the relative
|
||||
@@ -506,8 +535,8 @@ GSocketError GSocket_GetError(GSocket *socket)
|
||||
For example: INPUT -> GSocket_Read()
|
||||
CONNECTION -> GSocket_Accept()
|
||||
*/
|
||||
void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
|
||||
GSocketFallback fallback, char *cdata)
|
||||
void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
|
||||
GSocketCallback fallback, char *cdata)
|
||||
{
|
||||
int count;
|
||||
|
||||
@@ -520,17 +549,17 @@ void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
|
||||
socket->m_fbacks[count] = fallback;
|
||||
socket->m_data[count] = cdata;
|
||||
|
||||
_GSocket_Install_Fallback(socket, count);
|
||||
_GSocket_Install_Callback(socket, count);
|
||||
_GSocket_Enable(socket, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
UnsetFallback will disables all fallbacks specified by "event".
|
||||
UnsetCallback will disables all fallbacks specified by "event".
|
||||
NOTE: event may be a combination of flags
|
||||
*/
|
||||
void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
|
||||
void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
@@ -540,7 +569,7 @@ void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
|
||||
if ((event & (1 << count)) != 0) {
|
||||
_GSocket_Disable(socket, count);
|
||||
socket->m_fbacks[count] = NULL;
|
||||
_GSocket_Uninstall_Fallback(socket, count);
|
||||
_GSocket_Uninstall_Callback(socket, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -567,14 +596,14 @@ void _GSocket_Enable(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
socket->m_iocalls[event] = TRUE;
|
||||
if (socket->m_fbacks[event])
|
||||
_GSocket_Install_Fallback(socket, event);
|
||||
_GSocket_Install_Callback(socket, event);
|
||||
}
|
||||
|
||||
void _GSocket_Disable(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
socket->m_iocalls[event] = FALSE;
|
||||
if (socket->m_fbacks[event])
|
||||
_GSocket_Uninstall_Fallback(socket, event);
|
||||
_GSocket_Uninstall_Callback(socket, event);
|
||||
}
|
||||
|
||||
int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
|
||||
|
@@ -17,9 +17,10 @@ struct _GSocket {
|
||||
GSocketError m_error;
|
||||
|
||||
bool m_blocking, m_server, m_stream, m_oriented;
|
||||
unsigned long m_timeout;
|
||||
|
||||
/* Fallbacks */
|
||||
GSocketFallback m_fbacks[GSOCK_MAX_EVENT];
|
||||
/* Callbacks */
|
||||
GSocketCallback m_fbacks[GSOCK_MAX_EVENT];
|
||||
char *m_data[GSOCK_MAX_EVENT];
|
||||
|
||||
/* IO calls associated */
|
||||
@@ -45,8 +46,8 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size);
|
||||
int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size);
|
||||
int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size);
|
||||
int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
|
||||
void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent count);
|
||||
void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent count);
|
||||
void _GSocket_Install_Callback(GSocket *socket, GSocketEvent count);
|
||||
void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent count);
|
||||
void _GSocket_Detected_Read(GSocket *socket);
|
||||
void _GSocket_Detected_Write(GSocket *socket);
|
||||
void _GSocket_GUI_Init(GSocket *socket);
|
||||
|
Reference in New Issue
Block a user