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:
Guilhem Lavaux
1999-07-30 17:54:18 +00:00
parent aa994705c7
commit 39b91ecabe
14 changed files with 158 additions and 60 deletions

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)
{
}

View File

@@ -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)

View File

@@ -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);