📄 select.cpp
字号:
/*
This file is part of SWAIN (http://sourceforge.net/projects/swain).
Copyright (C) 2006 Daniel Lindstr鰉 and Daniel Nilsson
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Select.h"
Select::Select(void){
for(int i=0; i<FD_SETSIZE; i++){
sockets[i] = NULL;
this->free_socks[i] = true;
}
num_socks = 0;
InitializeCriticalSection(&lock);
timeout = NULL;
}
Select::~Select(void){
DeleteCriticalSection(&lock);
if(timeout != NULL)
free(timeout);
}
void Select::addSocket(Socket *s){
EnterCriticalSection(&lock);
for(int i=0; i<FD_SETSIZE; i++){
if(free_socks[i]){
sockets[i] = s;
num_socks++;
free_socks[i] = false;
break;
}
}
LeaveCriticalSection(&lock);
}
void Select::removeSocket(Socket *s){
EnterCriticalSection(&lock);
for(int i=0; i<FD_SETSIZE; i++){
if(sockets[i] == s){
sockets[i] = NULL;
num_socks--;
free_socks[i] = true;
}
}
LeaveCriticalSection(&lock);
}
void Select::removeSockets(){
EnterCriticalSection(&lock);
for(int i=0; i<FD_SETSIZE; i++){
if(!free_socks[i]){
sockets[i] = NULL;
free_socks[i] = true;
}
}
LeaveCriticalSection(&lock);
}
Socket *Select::doSelect(void){
static fd_set set;
static int num = 0;
Socket *s = NULL;
int i;
if (num == 0) { // The set is empty, need to rebuild it.
EnterCriticalSection(&lock);
FD_ZERO(&set);
for(i=0; i<FD_SETSIZE; i++){
if (!free_socks[i]) {
FD_SET(sockets[i]->sock, &set);
num++;
}
}
LeaveCriticalSection(&lock);
if (num > 0) {
num = select(num, &set, NULL, NULL, timeout);
} else { // No sockets, just sleep...
Sleep(timeout->tv_sec*1000 + timeout->tv_usec/1000);
}
}
if(num == 0){
return NULL;
}
if(num == SOCKET_ERROR){
int err = WSAGetLastError();
printf("select returned SOCKET_ERROR (error %d), sleeping...\n", err);
Sleep(timeout->tv_sec*1000 + timeout->tv_usec/1000);
num = 0;
return NULL;
}
EnterCriticalSection(&lock);
for(i = 0; i<FD_SETSIZE; i++){
if(!free_socks[i] && FD_ISSET(sockets[i]->sock, &set)){
s = sockets[i];
FD_CLR(s->sock, &set);
num--;
break;
}
}
if (s == NULL) { // didn't find the socket, must have been removed
num = 0; // force a rebuild of the fd_set next time
}
LeaveCriticalSection(&lock);
return(s);
}
void Select::setTimeout(int ms){
if(timeout == NULL)
this->timeout = (timeval *)malloc(sizeof(TIMEVAL));
this->timeout->tv_sec = ms/1000;
this->timeout->tv_usec =(long)(ms%1000)*1000;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -