/// <summary> /// Called when [close]. /// </summary> protected virtual void OnClosed(CloseReason reason) { //Already closed if (!TryAddStateFlag(SocketState.Closed)) { return; } //Before changing m_SendingQueue, must check m_IsClosed while (true) { var sendingQueue = m_SendingQueue; if (sendingQueue == null) { break; } //There is no sending was started after the m_Closed ws set to 'true' if (Interlocked.CompareExchange(ref m_SendingQueue, null, sendingQueue) == sendingQueue) { sendingQueue.Clear(); m_SendingQueuePool.Push(sendingQueue); break; } } var closedHandler = Closed; if (closedHandler != null) { closedHandler(this, reason); } }
private void StartSend(SendingQueue queue, int sendingTrackID, bool initial) { if (initial) { if (!TryAddStateFlag(SocketState.InSending)) { return; } var currentQueue = m_SendingQueue; if (currentQueue != queue || sendingTrackID != currentQueue.TrackID) { //Has been sent OnSendEnd(); return; } } Socket client; if (IsInClosingOrClosed && TryValidateClosedBySocket(out client)) { OnSendEnd(); return; } SendingQueue newQueue; if (!m_SendingQueuePool.TryGet(out newQueue)) { OnSendEnd(CloseReason.InternalError, true); AppSession.Logger.Error("There is no enougth sending queue can be used."); return; } var oldQueue = Interlocked.CompareExchange(ref m_SendingQueue, newQueue, queue); if (!ReferenceEquals(oldQueue, queue)) { if (newQueue != null) { m_SendingQueuePool.Push(newQueue); } if (IsInClosingOrClosed) { OnSendEnd(); } else { OnSendEnd(CloseReason.InternalError, true); AppSession.Logger.Error("Failed to switch the sending queue."); } return; } //Start to allow enqueue newQueue.StartEnqueue(); queue.StopEnqueue(); if (queue.Count == 0) { m_SendingQueuePool.Push(queue); OnSendEnd(CloseReason.InternalError, true); AppSession.Logger.Error("There is no data to be sent in the queue."); return; } Send(queue); }