Advertisement
Guest User

Modified NetworkEndpoint.cs

a guest
Jun 26th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.72 KB | None | 0 0
  1. //Interlocked.CompareExchange doesn't seem to have an overload for booleans.
  2. //Does this effectively thread-safe the Connected property?
  3. private object connectedLock = new object();
  4. public bool Connected {
  5.     get {
  6.         lock (connectedLock) {
  7.             if (connection == null) return false;
  8.             return connection.Connected;
  9.         }
  10.     }
  11. }
  12.  
  13. //Is locking the call to connection.Send enough?
  14. //Should I wrap a lock around the entire method?
  15. private object sendLock = new object();
  16. public void Send(NetworkHeader header, byte[] data) {
  17.     if (!Connected) throw new InvalidOperationException("NetworkEndpoint must be connected before sending.");
  18.     try {
  19.         lock (sendLock) {
  20.             connection.Send(ByteUtils.Combine(header.Serialize(), data));
  21.         }
  22.  
  23.     } catch (SocketException) {
  24.         Disconnect();
  25.     }
  26. }
  27.  
  28. //Is this the correct way to clear events?
  29. //Would setting the events to null accomplish the same goal.
  30. //  If so, would that be better?
  31. public void Clear() {
  32.     foreach (Delegate d in DataReceived.GetInvocationList())
  33.         DataReceived -= (EventHandler<NetworkReceiveEventArgs>)d;
  34.     foreach (Delegate d in Disconnected.GetInvocationList())
  35.         Disconnected -= (EventHandler)d;
  36. }
  37.  
  38. //Should I be locking individual portion(s) of Disconnect rather than the entire method?
  39. private object disconnectLock = new object();
  40. public void Disconnect() {
  41.     if (Connected) {
  42.         lock (disconnectLock) {
  43.             connection?.Shutdown(SocketShutdown.Both);
  44.             connection?.Close();
  45.             connection = null;
  46.             OnDisconnected();
  47.             Clear();
  48.         }
  49.     }
  50. }
  51.  
  52. //I added a lock here which you did not mention. Is it redundant??
  53. private object initializeLock = new object();
  54. public void InitializeReceiveLoop() {
  55.     lock (initializeLock) {
  56.         if (Receiving) return;
  57.         Receiving = true;
  58.     }
  59.     BeginReceive();
  60. }
  61.  
  62. //Is this a safer implementation of EndReceive?
  63.  
  64. //What isn't thread-safe about EndReceive?
  65. //It is only ever called by BeginReceive which is only called after the
  66. //completion of a previous call to EndReceive or by InitializeReceiveLoop
  67. //which can only be called once (returns immediately if Receiving is already true)
  68. private void EndReceive(IAsyncResult result) {
  69.     byte[] dataBuffer = null;
  70.     NetworkHeader header = null;
  71.  
  72.     try {
  73.         if (connection.EndReceive(result) > 0) {
  74.             header = NetworkHeader.Deserialize(headBuffer);
  75.             dataBuffer = new byte[header.DataSize];
  76.  
  77.             int offset = 0;
  78.             while (offset < header.DataSize) {
  79.                 int lengthRead = connection.Receive(dataBuffer, offset,
  80.                     (int)header.DataSize - offset, SocketFlags.None);
  81.  
  82.                 if (lengthRead == 0) {
  83.                     Disconnect();
  84.                     return;
  85.                 }
  86.  
  87.                 else offset += lengthRead;
  88.             }
  89.         }
  90.     } catch (SocketException) {
  91.         Disconnect();
  92.         return;
  93.     }
  94.  
  95.     OnDataReceived(header, dataBuffer);
  96.     BeginReceive();
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement