- Use select() to sleep when idle as opposed to busy waiting.
- Introduce com_busyWait cvar to go back to old behaviour
This commit is contained in:
parent
fa8201c9b6
commit
e5dbce839a
7 changed files with 206 additions and 183 deletions
|
@ -107,6 +107,8 @@ static cvar_t *net_port6;
|
|||
static cvar_t *net_mcast6addr;
|
||||
static cvar_t *net_mcast6iface;
|
||||
|
||||
static cvar_t *net_dropsim;
|
||||
|
||||
static struct sockaddr socksRelayAddr;
|
||||
|
||||
static SOCKET ip_socket = INVALID_SOCKET;
|
||||
|
@ -201,7 +203,7 @@ char *NET_ErrorString( void ) {
|
|||
default: return "NO ERROR";
|
||||
}
|
||||
#else
|
||||
return strerror (errno);
|
||||
return strerror(socketError);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -524,16 +526,17 @@ qboolean NET_IsLocalAddress( netadr_t adr ) {
|
|||
|
||||
/*
|
||||
==================
|
||||
Sys_GetPacket
|
||||
NET_GetPacket
|
||||
|
||||
Never called by the game logic, just the system event queing
|
||||
Receive one packet
|
||||
==================
|
||||
*/
|
||||
#ifdef _DEBUG
|
||||
int recvfromCount;
|
||||
#endif
|
||||
|
||||
qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
||||
qboolean NET_GetPacket(netadr_t *net_from, msg_t *net_message, fd_set *fdr)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_storage from;
|
||||
socklen_t fromlen;
|
||||
|
@ -543,7 +546,7 @@ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
|||
recvfromCount++; // performance check
|
||||
#endif
|
||||
|
||||
if(ip_socket != INVALID_SOCKET)
|
||||
if(ip_socket != INVALID_SOCKET && FD_ISSET(ip_socket, fdr))
|
||||
{
|
||||
fromlen = sizeof(from);
|
||||
ret = recvfrom( ip_socket, (void *)net_message->data, net_message->maxsize, 0, (struct sockaddr *) &from, &fromlen );
|
||||
|
@ -577,7 +580,7 @@ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
|||
net_message->readcount = 0;
|
||||
}
|
||||
|
||||
if( ret == net_message->maxsize ) {
|
||||
if( ret >= net_message->maxsize ) {
|
||||
Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
|
||||
return qfalse;
|
||||
}
|
||||
|
@ -587,7 +590,7 @@ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
|||
}
|
||||
}
|
||||
|
||||
if(ip6_socket != INVALID_SOCKET)
|
||||
if(ip6_socket != INVALID_SOCKET && FD_ISSET(ip6_socket, fdr))
|
||||
{
|
||||
fromlen = sizeof(from);
|
||||
ret = recvfrom(ip6_socket, (void *)net_message->data, net_message->maxsize, 0, (struct sockaddr *) &from, &fromlen);
|
||||
|
@ -604,7 +607,7 @@ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
|||
SockadrToNetadr((struct sockaddr *) &from, net_from);
|
||||
net_message->readcount = 0;
|
||||
|
||||
if(ret == net_message->maxsize)
|
||||
if(ret >= net_message->maxsize)
|
||||
{
|
||||
Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
|
||||
return qfalse;
|
||||
|
@ -615,7 +618,7 @@ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
|||
}
|
||||
}
|
||||
|
||||
if(multicast6_socket != INVALID_SOCKET && multicast6_socket != ip6_socket)
|
||||
if(multicast6_socket != INVALID_SOCKET && multicast6_socket != ip6_socket && FD_ISSET(multicast6_socket, fdr))
|
||||
{
|
||||
fromlen = sizeof(from);
|
||||
ret = recvfrom(multicast6_socket, (void *)net_message->data, net_message->maxsize, 0, (struct sockaddr *) &from, &fromlen);
|
||||
|
@ -632,7 +635,7 @@ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
|
|||
SockadrToNetadr((struct sockaddr *) &from, net_from);
|
||||
net_message->readcount = 0;
|
||||
|
||||
if(ret == net_message->maxsize)
|
||||
if(ret >= net_message->maxsize)
|
||||
{
|
||||
Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
|
||||
return qfalse;
|
||||
|
@ -1499,6 +1502,8 @@ static qboolean NET_GetCvars( void ) {
|
|||
modified += net_socksPassword->modified;
|
||||
net_socksPassword->modified = qfalse;
|
||||
|
||||
net_dropsim = Cvar_Get("net_dropsim", "", CVAR_TEMP);
|
||||
|
||||
return modified ? qtrue : qfalse;
|
||||
}
|
||||
|
||||
|
@ -1627,6 +1632,42 @@ void NET_Shutdown( void ) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Event
|
||||
|
||||
Called from NET_Sleep which uses select() to determine which sockets have seen action.
|
||||
====================
|
||||
*/
|
||||
|
||||
void NET_Event(fd_set *fdr)
|
||||
{
|
||||
byte bufData[MAX_MSGLEN + 1];
|
||||
netadr_t from;
|
||||
msg_t netmsg;
|
||||
|
||||
while(1)
|
||||
{
|
||||
MSG_Init(&netmsg, bufData, sizeof(bufData));
|
||||
|
||||
if(NET_GetPacket(&from, &netmsg, fdr))
|
||||
{
|
||||
if(net_dropsim->value > 0.0f && net_dropsim->value <= 100.0f)
|
||||
{
|
||||
// com_dropsim->value percent of incoming packets get dropped.
|
||||
if(rand() < (int) (((double) RAND_MAX) / 100.0 * (double) net_dropsim->value))
|
||||
continue; // drop this packet
|
||||
}
|
||||
|
||||
if(com_sv_running->integer)
|
||||
Com_RunAndTimeServerPacket(&from, &netmsg);
|
||||
else
|
||||
CL_PacketEvent(from, &netmsg);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -1635,31 +1676,23 @@ NET_Sleep
|
|||
Sleeps msec or until something happens on the network
|
||||
====================
|
||||
*/
|
||||
void NET_Sleep( int msec ) {
|
||||
void NET_Sleep(int msec)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set fdset;
|
||||
int highestfd = -1;
|
||||
fd_set fdr;
|
||||
int highestfd = -1, retval;
|
||||
|
||||
if (!com_dedicated->integer)
|
||||
return; // we're not a server, just run full speed
|
||||
|
||||
if (ip_socket == INVALID_SOCKET && ip6_socket == INVALID_SOCKET)
|
||||
return;
|
||||
|
||||
if (msec < 0 )
|
||||
return;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_ZERO(&fdr);
|
||||
|
||||
if(ip_socket != INVALID_SOCKET)
|
||||
{
|
||||
FD_SET(ip_socket, &fdset);
|
||||
FD_SET(ip_socket, &fdr);
|
||||
|
||||
highestfd = ip_socket;
|
||||
}
|
||||
if(ip6_socket != INVALID_SOCKET)
|
||||
{
|
||||
FD_SET(ip6_socket, &fdset);
|
||||
FD_SET(ip6_socket, &fdr);
|
||||
|
||||
if(ip6_socket > highestfd)
|
||||
highestfd = ip6_socket;
|
||||
|
@ -1667,9 +1700,32 @@ void NET_Sleep( int msec ) {
|
|||
|
||||
timeout.tv_sec = msec/1000;
|
||||
timeout.tv_usec = (msec%1000)*1000;
|
||||
select(highestfd + 1, &fdset, NULL, NULL, &timeout);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(highestfd < 0)
|
||||
{
|
||||
// windows ain't happy when select is called without valid FDs
|
||||
|
||||
if(msec > 0)
|
||||
msec--;
|
||||
|
||||
SleepEx(msec, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
#define TVW32_BIAS 999
|
||||
// windows adds a whole millisecond of latency, otherwise granularity seems to be fine.
|
||||
if(timeout.tv_usec > TVW32_BIAS)
|
||||
timeout.tv_usec -= TVW32_BIAS;
|
||||
#endif
|
||||
|
||||
retval = select(highestfd + 1, &fdr, NULL, NULL, &timeout);
|
||||
|
||||
if(retval < 0)
|
||||
Com_Printf("Warning: select() syscall failed: %s\n", NET_ErrorString());
|
||||
else if(retval > 0)
|
||||
NET_Event(&fdr);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue