Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Interlocked.CompareExchange doesn't seem to have an overload for booleans.
- //Does this effectively thread-safe the Connected property?
- private object connectedLock = new object();
- public bool Connected {
- get {
- lock (connectedLock) {
- if (connection == null) return false;
- return connection.Connected;
- }
- }
- }
- //Is locking the call to connection.Send enough?
- //Should I wrap a lock around the entire method?
- private object sendLock = new object();
- public void Send(NetworkHeader header, byte[] data) {
- if (!Connected) throw new InvalidOperationException("NetworkEndpoint must be connected before sending.");
- try {
- lock (sendLock) {
- connection.Send(ByteUtils.Combine(header.Serialize(), data));
- }
- } catch (SocketException) {
- Disconnect();
- }
- }
- //Is this the correct way to clear events?
- //Would setting the events to null accomplish the same goal.
- // If so, would that be better?
- public void Clear() {
- foreach (Delegate d in DataReceived.GetInvocationList())
- DataReceived -= (EventHandler<NetworkReceiveEventArgs>)d;
- foreach (Delegate d in Disconnected.GetInvocationList())
- Disconnected -= (EventHandler)d;
- }
- //Should I be locking individual portion(s) of Disconnect rather than the entire method?
- private object disconnectLock = new object();
- public void Disconnect() {
- if (Connected) {
- lock (disconnectLock) {
- connection?.Shutdown(SocketShutdown.Both);
- connection?.Close();
- connection = null;
- OnDisconnected();
- Clear();
- }
- }
- }
- //I added a lock here which you did not mention. Is it redundant??
- private object initializeLock = new object();
- public void InitializeReceiveLoop() {
- lock (initializeLock) {
- if (Receiving) return;
- Receiving = true;
- }
- BeginReceive();
- }
- //Is this a safer implementation of EndReceive?
- //What isn't thread-safe about EndReceive?
- //It is only ever called by BeginReceive which is only called after the
- //completion of a previous call to EndReceive or by InitializeReceiveLoop
- //which can only be called once (returns immediately if Receiving is already true)
- private void EndReceive(IAsyncResult result) {
- byte[] dataBuffer = null;
- NetworkHeader header = null;
- try {
- if (connection.EndReceive(result) > 0) {
- header = NetworkHeader.Deserialize(headBuffer);
- dataBuffer = new byte[header.DataSize];
- int offset = 0;
- while (offset < header.DataSize) {
- int lengthRead = connection.Receive(dataBuffer, offset,
- (int)header.DataSize - offset, SocketFlags.None);
- if (lengthRead == 0) {
- Disconnect();
- return;
- }
- else offset += lengthRead;
- }
- }
- } catch (SocketException) {
- Disconnect();
- return;
- }
- OnDataReceived(header, dataBuffer);
- BeginReceive();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement