private void DoReceive(ChannelRegistration registration, IActorRef handler) { Action <int, ByteBuffer> innerReceive = null; innerReceive = (readsLeft, buffer) => { buffer.Clear(); buffer.Limit(_udp.Setting.DirectBufferSize); var sender = Channel.Receive(buffer); if (sender != null) { buffer.Flip(); handler.Tell(new Udp.Received(ByteString.Create(buffer), sender)); if (readsLeft > 0) { innerReceive(readsLeft - 1, buffer); } } }; var buffr = _udp.BufferPool.Acquire(); try { innerReceive(_udp.Setting.BatchReceiveLimit, buffr); } finally { _udp.BufferPool.Release(buffr); registration.EnableInterest(SocketAsyncOperation.Receive); } }
private void DoRead(ChannelRegistration registration, IActorRef handler) { Action <int, ByteBuffer> innerRead = null; innerRead = (readsLeft, buffer) => { buffer.Clear(); buffer.Limit(_udpConn.Settings.DirectBufferSize); if (_channel.Read(buffer) > 0) { buffer.Flip(); handler.Tell(new UdpConnected.Received(ByteString.Create(buffer))); innerRead(readsLeft - 1, buffer); } }; var buffr = _udpConn.BufferPool.Acquire(); try { innerRead(_udpConn.Settings.BatchReceiveLimit, buffr); } finally { registration.EnableInterest(SocketAsyncOperation.Receive); _udpConn.BufferPool.Release(buffr); } }
private void Register(EndPoint address, ChannelRegistration registration) { ReportConnectFailure(() => { Log.Debug("Attempting connection to [{0}]", address); if (Channel.Connect(address)) { CompleteConnect(registration, _commander, _connect.Options); } else { registration.EnableInterest(SocketAsyncOperation.Connect); Become(Connecting(registration, Tcp.Settings.FinishConnectRetries)); } }); }
private void DoSend(ChannelRegistration registration) { var buffer = Udp.BufferPool.Acquire(); try { buffer.Clear(); _pendingSend.Payload.CopyToBuffer(buffer); buffer.Flip(); var writtenBytes = Channel.Send(buffer, _pendingSend.Target); if (Udp.Setting.TraceLogging) { _log.Debug("Wrote [{0}] bytes to channel", writtenBytes); } // Datagram channel either sends the whole message, or nothing if (writtenBytes == 0) { if (_retriedSend) { _pendingCommander.Tell(new Udp.CommandFailed(_pendingSend)); _retriedSend = false; _pendingSend = null; _pendingCommander = null; } else { registration.EnableInterest(SocketAsyncOperation.Send); _retriedSend = true; } } else { if (_pendingSend.WantsAck) { _pendingCommander.Tell(_pendingSend.Ack); } _retriedSend = false; _pendingSend = null; _pendingCommander = null; } } finally { Udp.BufferPool.Release(buffer); } }
private Receive ReadHandlers(ChannelRegistration registration) { return(message => { if (message is Udp.SuspendReading) { registration.DisableInterest(SocketAsyncOperation.Receive); return true; } if (message is Udp.ResumeReading) { registration.EnableInterest(SocketAsyncOperation.Receive); return true; } if (message is SelectionHandler.ChannelReadable) { DoReceive(registration, _bind.Handler); return true; } if (message is Udp.Unbind) { _log.Debug("Unbinding endpoint [{0}]", _bind.LocalAddress); try { Channel.Close(); Sender.Tell(IO.Udp.Unbound.Instance); _log.Debug("Unbound endpoint [{0}], stopping listener", _bind.LocalAddress); } finally { Context.Stop(Self); } return true; } return false; }); }
private Receive Connected(ChannelRegistration registration) { return(message => { if (message is UdpConnected.SuspendReading) { registration.DisableInterest(SocketAsyncOperation.Receive); return true; } if (message is UdpConnected.ResumeReading) { registration.EnableInterest(SocketAsyncOperation.Receive); return true; } if (message is SelectionHandler.ChannelReadable) { DoRead(registration, _connect.Handler); return true; } if (message is UdpConnected.Disconnect) { _log.Debug("Closing UDP connection to [{0}]", _connect.RemoteAddress); _channel.Close(); Sender.Tell(UdpConnected.Disconnected.Instance); _log.Debug("Connection closed to [{0}], stopping listener", _connect.RemoteAddress); Context.Stop(Self); return true; } var send = message as UdpConnected.Send; if (send != null && WritePending) { if (_udpConn.Settings.TraceLogging) { _log.Debug("Dropping write because queue is full"); } Sender.Tell(new UdpConnected.CommandFailed(send)); return true; } if (send != null && send.Payload.IsEmpty) { if (send.WantsAck) { Sender.Tell(send.Ack); } return true; } if (send != null) { _pendingSend = Tuple.Create(send, Sender); registration.EnableInterest(SocketAsyncOperation.Send); return true; } if (message is SelectionHandler.ChannelWritable) { DoWrite(); return true; } return false; }); }