private void SendCallback(IAsyncResult ar) { SendState state = (SendState)ar.AsyncState; try { int len = state.SendSocket.EndSend(ar); if (len != state.SendParameters.Length) { //I don't know how this can happen, but just in case.. Debug.Assert(false, "Critical error: Server did not send the expected number of bytes. Buffer length = " + state.SendParameters.Length.ToString() + "; bytes sent = " + len.ToString() + "; remote endpoint = " + state.SendSocket.RemoteEndPoint.ToString()); } } catch (SocketException se) { Trace.WriteLine("SendCallback SocketException errorcode: " + se.ErrorCode.ToString(), this.GetType().ToString()); this.DisableClient(state.SendParameters.Id); } catch (ObjectDisposedException ode) { Trace.WriteLine("SendCallback: " + ode.Message, this.GetType().ToString()); this.DisableClient(state.SendParameters.Id); } catch (Exception e) { Trace.WriteLine(e.ToString(), this.GetType().ToString()); this.DisableClient(state.SendParameters.Id); } finally { using (Synchronizer.Cookie cookie = Synchronizer.Lock(this.m_SendQueue)) { using (Synchronizer.Lock(m_SendingParticipants)) { if (m_SendingParticipants.ContainsKey(state.SendParameters.Id)) { ((ReferenceCounter)m_SendingParticipants[state.SendParameters.Id]).Decrement(); } else { Debug.Assert(false, "Server send callback found a missing reference counter."); } --m_PendingOutboundMessageCount; Debug.Assert(m_PendingOutboundMessageCount >= 0, "Server send callback found a negative pending message count."); //Notify threads closing the socket if this is the last item in the socket queue. if (m_ClosingSockets.ContainsKey(state.SendSocket)) { if (((ReferenceCounter)m_SendingParticipants[state.SendParameters.Id]).IsZero) { ((ManualResetEvent)m_ClosingSockets[state.SendSocket]).Set(); } } // Notify the sender thread that the queue's status has changed. cookie.PulseAll(); } } } }
/// <summary> /// If a client reconnects, update the socket map and enable the client's queue /// </summary> /// <param name="id"></param> /// <param name="s"></param> internal void Reconnect(ClientData client, ulong lastMessage, ulong lastChunk) { using (Synchronizer.Lock(this.m_SocketMap)) { if (m_SocketMap.ContainsKey(client.Id)) { m_SocketMap[client.Id] = client.Socket; } } using (Synchronizer.Cookie cookie = Synchronizer.Lock(this.m_SendQueue)) { m_SendQueue.EnableClient(client, lastMessage, lastChunk); cookie.PulseAll(); } }
protected virtual void Dispose(bool disposing) { this.m_Disposed = true; if (disposing) { m_Instructor.Changed["CurrentDeckTraversal"].Remove(new PropertyEventHandler(OnCurrentDeckTraversalChanged)); if (m_DeckTraversal != null) { m_DeckTraversal.Changed["Current"].Remove(new PropertyEventHandler(OnTableOfContentsEntryChanged)); } // Notify the sending thread that we're disposed. using (Synchronizer.Cookie cookie = Synchronizer.Lock(this.m_SendQueue)) cookie.PulseAll(); } }
/// <summary> /// Enqueue the send to occur when network bandwidth is available. /// </summary> /// <param name="buffer"></param> /// <param name="length"></param> /// <param name="socket"></param> /// <param name="participant"></param> internal void Send(byte[] buffer, int length, ClientData client, MessageTags tags, ulong messageSequence, ulong chunkSequence, bool isHeartbeat) { using (Synchronizer.Lock(m_SocketMap)) { Debug.Assert(m_SocketMap.ContainsKey(client.Id), "TCPServerSender.Send found a missing Socket Map entry."); } //Trace.WriteLine("TCPServerSender.Send seq=" + messageSequence.ToString()); //Enqueue the message using (Synchronizer.Cookie cookie = Synchronizer.Lock(m_SendQueue)) { m_SendQueue.Enqueue(new SendParameters(buffer, length, client.Id, tags, messageSequence, chunkSequence, isHeartbeat), client.Participant); // Notify the sender thread that the queue's status has changed. cookie.PulseAll(); } }