aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLee Salzman <[email protected]>2013-05-11 21:53:55 +0300
committerLee Salzman <[email protected]>2013-05-11 21:53:55 +0300
commit69b98608e5fb48160947807256ea53f5574dae37 (patch)
tree5f654f4bd2e80ef6ce82333a3425cae2672d1da7
parent2bb83d9813bf013b63a6b7818893dd375bd84118 (diff)
downloadenet-69b98608e5fb48160947807256ea53f5574dae37.tar.gz
enet-69b98608e5fb48160947807256ea53f5574dae37.zip
track the number of connected peers to make throttling a bit cheaper
-rw-r--r--host.c51
-rw-r--r--include/enet/enet.h4
-rw-r--r--peer.c34
-rw-r--r--protocol.c49
4 files changed, 93 insertions, 45 deletions
diff --git a/host.c b/host.c
index 43c6f75..f07d714 100644
--- a/host.c
+++ b/host.c
@@ -102,6 +102,9 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> totalReceivedData = 0;
host -> totalReceivedPackets = 0;
+ host -> connectedPeers = 0;
+ host -> bandwidthLimitedPeers = 0;
+
host -> compressor.context = NULL;
host -> compressor.compress = NULL;
host -> compressor.decompress = NULL;
@@ -328,13 +331,12 @@ enet_host_bandwidth_throttle (ENetHost * host)
{
enet_uint32 timeCurrent = enet_time_get (),
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
- peersTotal = 0,
- dataTotal = 0,
- peersRemaining,
- bandwidth,
+ peersRemaining = (enet_uint32) host -> connectedPeers,
+ dataTotal = ~0,
+ bandwidth = ~0,
throttle = 0,
bandwidthLimit = 0;
- int needsAdjustment = 0;
+ int needsAdjustment = host -> bandwidthLimitedPeers > 0 ? 1 : 0;
ENetPeer * peer;
ENetProtocol command;
@@ -343,35 +345,30 @@ enet_host_bandwidth_throttle (ENetHost * host)
host -> bandwidthThrottleEpoch = timeCurrent;
- for (peer = host -> peers;
- peer < & host -> peers [host -> peerCount];
- ++ peer)
+ if (peersRemaining == 0)
+ return;
+
+ if (host -> outgoingBandwidth != 0)
{
- if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
- continue;
+ dataTotal = 0;
+ bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
- if (peer -> incomingBandwidth != 0)
- needsAdjustment = 1;
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+ continue;
- ++ peersTotal;
- dataTotal += peer -> outgoingDataTotal;
+ dataTotal += peer -> outgoingDataTotal;
+ }
}
- if (peersTotal == 0)
- return;
-
- peersRemaining = peersTotal;
-
- if (host -> outgoingBandwidth == 0)
- bandwidth = ~0;
- else
- bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
-
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
- if (dataTotal < bandwidth)
+ if (dataTotal <= bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
@@ -414,7 +411,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
if (peersRemaining > 0)
{
- if (dataTotal < bandwidth)
+ if (dataTotal <= bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
@@ -441,7 +438,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
{
host -> recalculateBandwidthLimits = 0;
- peersRemaining = peersTotal;
+ peersRemaining = (enet_uint32) host -> connectedPeers;
bandwidth = host -> incomingBandwidth;
needsAdjustment = 1;
diff --git a/include/enet/enet.h b/include/enet/enet.h
index 7bd10da..07ed9d2 100644
--- a/include/enet/enet.h
+++ b/include/enet/enet.h
@@ -383,6 +383,8 @@ typedef struct _ENetHost
enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */
+ size_t connectedPeers;
+ size_t bandwidthLimitedPeers;
} ENetHost;
/**
@@ -566,6 +568,8 @@ extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
+extern void enet_peer_on_connect (ENetPeer *);
+extern void enet_peer_on_disconnect (ENetPeer *);
ENET_API void * enet_range_coder_create (void);
ENET_API void enet_range_coder_destroy (void *);
diff --git a/peer.c b/peer.c
index a86d793..6a9641c 100644
--- a/peer.c
+++ b/peer.c
@@ -337,6 +337,30 @@ enet_peer_reset_queues (ENetPeer * peer)
peer -> channelCount = 0;
}
+void
+enet_peer_on_connect (ENetPeer * peer)
+{
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+ {
+ if (peer -> incomingBandwidth != 0)
+ ++ peer -> host -> bandwidthLimitedPeers;
+
+ ++ peer -> host -> connectedPeers;
+ }
+}
+
+void
+enet_peer_on_disconnect (ENetPeer * peer)
+{
+ if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+ {
+ if (peer -> incomingBandwidth != 0)
+ -- peer -> host -> bandwidthLimitedPeers;
+
+ -- peer -> host -> connectedPeers;
+ }
+}
+
/** Forcefully disconnects a peer.
@param peer peer to forcefully disconnect
@remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
@@ -345,6 +369,8 @@ enet_peer_reset_queues (ENetPeer * peer)
void
enet_peer_reset (ENetPeer * peer)
{
+ enet_peer_on_disconnect (peer);
+
peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
peer -> connectID = 0;
@@ -519,7 +545,11 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
- peer -> state = ENET_PEER_STATE_DISCONNECTING;
+ {
+ enet_peer_notify_disconnect (peer);
+
+ peer -> state = ENET_PEER_STATE_DISCONNECTING;
+ }
else
{
enet_host_flush (peer -> host);
@@ -584,7 +614,7 @@ void
enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
{
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
-
+
peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
if (outgoingCommand -> command.header.channelID == 0xFF)
diff --git a/protocol.c b/protocol.c
index 0fbd012..c8adb7a 100644
--- a/protocol.c
+++ b/protocol.c
@@ -32,6 +32,30 @@ enet_protocol_command_size (enet_uint8 commandNumber)
return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
}
+static void
+enet_protocol_change_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
+{
+ if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER)
+ enet_peer_on_connect (peer);
+ else
+ enet_peer_on_disconnect (peer);
+
+ peer -> state = state;
+}
+
+static void
+enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
+{
+ enet_peer_change_state (host, peer, state);
+
+ if (! peer -> needsDispatch)
+ {
+ enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
+
+ peer -> needsDispatch = 1;
+ }
+}
+
static int
enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
@@ -45,7 +69,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
case ENET_PEER_STATE_CONNECTION_PENDING:
case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
- peer -> state = ENET_PEER_STATE_CONNECTED;
+ enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED);
event -> type = ENET_EVENT_TYPE_CONNECT;
event -> peer = peer;
@@ -93,26 +117,13 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
}
static void
-enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
-{
- peer -> state = state;
-
- if (! peer -> needsDispatch)
- {
- enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
-
- peer -> needsDispatch = 1;
- }
-}
-
-static void
enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
{
host -> recalculateBandwidthLimits = 1;
if (event != NULL)
{
- peer -> state = ENET_PEER_STATE_CONNECTED;
+ enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED);
event -> type = ENET_EVENT_TYPE_CONNECT;
event -> peer = peer;
@@ -762,9 +773,15 @@ enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const EN
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
return -1;
+ if (peer -> incomingBandwidth != 0)
+ -- host -> bandwidthLimitedPeers;
+
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
+ if (peer -> incomingBandwidth != 0)
+ ++ host -> bandwidthLimitedPeers;
+
if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else
@@ -812,7 +829,7 @@ enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetPro
}
else
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
- peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT;
+ enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT);
else
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);