Added GSocket_Select()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3612 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -524,27 +524,71 @@ int GSocket_Write(GSocket *socket, const char *buffer,
|
|||||||
return _GSocket_Send_Dgram(socket, buffer, size);
|
return _GSocket_Send_Dgram(socket, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSocket_DataAvailable(GSocket *socket)
|
/* 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(GSocket *socket, GSocketEventFlags flags)
|
||||||
{
|
{
|
||||||
fd_set read_set;
|
fd_set readfds, writefds, exceptfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
GSocketEventFlags mask;
|
||||||
|
int error, len;
|
||||||
|
|
||||||
assert(socket != NULL);
|
assert(socket != NULL);
|
||||||
|
|
||||||
if (socket->m_fd == -1 || socket->m_server) {
|
if (socket->m_fd == -1)
|
||||||
|
{
|
||||||
socket->m_error = GSOCK_INVSOCK;
|
socket->m_error = GSOCK_INVSOCK;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_ZERO(&read_set);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(socket->m_fd, &read_set);
|
FD_ZERO(&writefds);
|
||||||
|
FD_ZERO(&exceptfds);
|
||||||
|
FD_SET(socket->m_fd, &readfds);
|
||||||
|
FD_SET(socket->m_fd, &writefds);
|
||||||
|
FD_SET(socket->m_fd, &exceptfds);
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv);
|
||||||
|
|
||||||
select(socket->m_fd+1, &read_set, NULL, NULL, &tv);
|
mask = 0;
|
||||||
|
|
||||||
return FD_ISSET(socket->m_fd, &read_set);
|
/* If select() says that the socket is readable, then we have
|
||||||
|
* no way to distinguish if that means 'data available' (to
|
||||||
|
* recv) or 'incoming connection' (to accept). The same goes
|
||||||
|
* for writability: we cannot distinguish between 'you can
|
||||||
|
* send data' and 'connection request completed'. So we will
|
||||||
|
* assume the following: if the flag was set upon entry,
|
||||||
|
* that means that the event was possible.
|
||||||
|
*/
|
||||||
|
if (FD_ISSET(socket->m_fd, &readfds))
|
||||||
|
{
|
||||||
|
mask |= (flags & GSOCK_CONNECTION_FLAG);
|
||||||
|
mask |= (flags & GSOCK_INPUT_FLAG);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(socket->m_fd, &writefds))
|
||||||
|
{
|
||||||
|
if (socket->m_establishing)
|
||||||
|
{
|
||||||
|
getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
mask |= (flags & GSOCK_LOST_FLAG);
|
||||||
|
else
|
||||||
|
mask |= (flags & GSOCK_CONNECTION_FLAG);
|
||||||
|
}
|
||||||
|
mask |= (flags & GSOCK_OUTPUT_FLAG);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(socket->m_fd, &exceptfds))
|
||||||
|
mask |= (flags & GSOCK_LOST_FLAG);
|
||||||
|
|
||||||
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
@@ -606,7 +650,7 @@ GSocketError GSocket_GetError(GSocket *socket)
|
|||||||
For example: INPUT -> GSocket_Read()
|
For example: INPUT -> GSocket_Read()
|
||||||
CONNECTION -> GSocket_Accept()
|
CONNECTION -> GSocket_Accept()
|
||||||
*/
|
*/
|
||||||
void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
|
void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
|
||||||
GSocketCallback callback, char *cdata)
|
GSocketCallback callback, char *cdata)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
@@ -616,7 +660,7 @@ void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
|
|||||||
for (count=0;count<GSOCK_MAX_EVENT;count++) {
|
for (count=0;count<GSOCK_MAX_EVENT;count++) {
|
||||||
/* We test each flag and, if it is enabled, we enable the corresponding
|
/* We test each flag and, if it is enabled, we enable the corresponding
|
||||||
event */
|
event */
|
||||||
if ((event & (1 << count)) != 0) {
|
if ((flags & (1 << count)) != 0) {
|
||||||
socket->m_cbacks[count] = callback;
|
socket->m_cbacks[count] = callback;
|
||||||
socket->m_data[count] = cdata;
|
socket->m_data[count] = cdata;
|
||||||
_GSocket_Enable(socket, count);
|
_GSocket_Enable(socket, count);
|
||||||
@@ -625,17 +669,17 @@ void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
UnsetCallback will disables all callbacks specified by "event".
|
UnsetCallback will disables all callbacks specified by "flags".
|
||||||
NOTE: event may be a combination of flags
|
NOTE: "flags" may be a combination of flags
|
||||||
*/
|
*/
|
||||||
void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
|
void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
assert(socket != NULL);
|
assert(socket != NULL);
|
||||||
|
|
||||||
for (count=0;count<GSOCK_MAX_EVENT;count++) {
|
for (count=0;count<GSOCK_MAX_EVENT;count++) {
|
||||||
if ((event & (1 << count)) != 0) {
|
if ((flags & (1 << count)) != 0) {
|
||||||
_GSocket_Disable(socket, count);
|
_GSocket_Disable(socket, count);
|
||||||
socket->m_cbacks[count] = NULL;
|
socket->m_cbacks[count] = NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user