public void Send(ISocketWriterJob job) { if (Interlocked.CompareExchange(ref _currentJob, job, null) != null) { _writeQueue.Enqueue(job); return; } _currentJob.Write(_writeArgs); // The job is invoked asynchronously here }
/// <summary> /// Sends the specified slice. /// </summary> /// <exception cref="System.ArgumentNullException">slice</exception> /// <exception cref="System.InvalidOperationException">Socket as not been Assign():ed.</exception> /// <seealso cref="StreamSocketWriterJob"/> /// <seealso cref="SliceSocketWriterJob"/> public void Send(ISocketWriterJob job) { if (job == null) throw new ArgumentNullException("job"); if (_socket == null || !_socket.Connected) throw new InvalidOperationException("Socket is not connected."); lock (this) { if (_currentJob != null) { _logger.Debug(_writeArgs.GetHashCode() + ": Enqueueing "); _writeQueue.Enqueue(job); return; } _logger.Debug(_writeArgs.GetHashCode() + ": sending directly "); _currentJob = job; } _currentJob.Write(_writeArgs); var isPending = _socket.SendAsync(_writeArgs); if (!isPending) HandleWriteCompleted(_writeArgs.SocketError, _writeArgs.BytesTransferred); }
/// <summary> /// Sends the specified slice. /// </summary> /// <exception cref="System.ArgumentNullException">slice</exception> /// <exception cref="System.InvalidOperationException">Socket as not been Assign():ed.</exception> /// <seealso cref="StreamSocketWriterJob"/> /// <seealso cref="SliceSocketWriterJob"/> public void Send(ISocketWriterJob job) { if (job == null) { throw new ArgumentNullException("job"); } if (_socket == null || !_socket.Connected) { throw new InvalidOperationException("Socket is not connected."); } lock (this) { if (_currentJob != null) { _logger.Debug(_writeArgs.GetHashCode() + ": Enqueueing "); _writeQueue.Enqueue(job); return; } _logger.Debug(_writeArgs.GetHashCode() + ": sending directly "); _currentJob = job; } _currentJob.Write(_writeArgs); var isPending = _socket.SendAsync(_writeArgs); if (!isPending) { HandleWriteCompleted(_writeArgs.SocketError, _writeArgs.BytesTransferred); } }
public void Send(ISocketWriterJob job) { bool spin = true; while (spin) { switch (_state) { case State.Idle: if (Interlocked.CompareExchange(ref _state, State.Active, State.Idle) == State.Idle) { spin = false; } // else consider new state break; case State.Active: if (Interlocked.CompareExchange(ref _state, State.Enqueue, State.Active) == State.Active) { _writeQueue.Enqueue(job); Interlocked.Exchange(ref _state, State.Active); return; } // else consider new state break; case State.Enqueue: case State.Dequeue: // spin to wait for new state Thread.Yield(); break; } } _currentJob.Write(_writeArgs); // The job is invoked asynchronously here }
private void HandleWriteCompleted(SocketError error, int bytesTransferred) { // error checks etc removed for this sample. if (_currentJob.WriteCompleted(bytesTransferred)) { _currentJob.Dispose(); bool spin = true; while (spin) { switch (_state) { case State.Active: if (Interlocked.CompareExchange(ref _state, State.Dequeue, State.Active) == State.Active) { if (!_writeQueue.TryDequeue(out _currentJob)) { // handle in state _currentJob = null; _state = State.Idle; return; } else { _state = State.Active; } } // else consider new state break; case State.Enqueue: // spin to wait for new state Thread.Yield(); break; // impossible states case State.Idle: case State.Dequeue: break; } } } _logger.Debug(_writeArgs.GetHashCode() + ": writing more "); _currentJob.Write(_writeArgs); // the job is invoked asycnhronously here. }
private void HandleWriteCompleted(SocketError error, int bytesTransferred) { if (_currentJob == null || _socket == null || !_socket.Connected) { return; // got disconnected } if (error == SocketError.Success && bytesTransferred > 0) { lock (this) { if (_currentJob.WriteCompleted(bytesTransferred)) { _currentJob.Dispose(); if (!_writeQueue.TryDequeue(out _currentJob)) { _logger.Debug(_writeArgs.GetHashCode() + ": no new job "); _currentJob = null; return; } } } _currentJob.Write(_writeArgs); var isPending = _socket.SendAsync(_writeArgs); if (!isPending) { HandleWriteCompleted(_writeArgs.SocketError, _writeArgs.BytesTransferred); } } else { if (error == SocketError.Success) { error = SocketError.ConnectionReset; } HandleDisconnect(error); } }