Mercurial > projects > dreactor
view dreactor/core/Dispatcher.d @ 11:5836613d16ac
reorg! reorg!
author | rick@minifunk |
---|---|
date | Tue, 12 Aug 2008 16:59:56 -0400 |
parents | 5412a1ff2e49 |
children |
line wrap: on
line source
module dreactor.protocol.Dispatcher; import tango.io.selector.model.ISelector; import tango.util.collection.CircularSeq; import tango.net.Socket; public import tango.core.Exception; import dreactor.transport.AsyncSocketConduit; import tango.util.log.Log; import tango.util.log.Config; class Dispatcher { public this (Conduit trans) { cond = trans; ibuf_len = 0; o_offset = 0; out_buffers = new CircularSeq!(char[]); log = Log.lookup("dreactor.core.Dispatcher"); } /************************************************************************** onSend -- Send method Called by the vat in response to a FD writeable event. Sends data, returns amount sent. Unregisters Handler for sending if there is no more data left to send. ***************************************************************************/ public int onSend() { Logger log = Log.lookup("Handlers.onSend"); char[] outbuf = nextBuffer(); if (outbuf !is null) { int sent = cond.write(outbuf); if (sent > 0) { if (! addOffset(sent)) { return UNREGISTER; } } else if (sent == 0) { log.error("Select said socket was writable, but sent 0 bytes"); } else { log.error("Socket send return ERR {}", sent); } return REMAIN; } else { return UNREGISTER; } } /************************************************************************** appendOutBuffer Adds an outgoing buffer to the list. This returns true if the list was empty, indicating that the handler should be registered with the SelectLoop. If it returns false, it was probably already registered. **************************************************************************/ bool appendOutBuffer(char[] outbuf) { out_buffers.append(outbuf); out_buffers_len++; if (out_buffers_len == 1) return true; else return false; } /************************************************************************** addOffset Use this function to update the offset position after a successful data send. This not only manages the current offset, but will update the out buffer chain if necessary. Returns: false if there is nothing left to send, true if there is. **************************************************************************/ bool addOffset(int off) in { assert(out_buffers_len > 0); } body { char[] hd = out_buffers.head(); if ((off + o_offset) >= hd.length) { out_buffers.removeHead(); o_offset = 0; out_buffers_len--; return (out_buffers_len > 0); } else o_offset += off; return true; } /************************************************************************** char[] nextBuffer Returns a slice of the current outbound buffer, returns a char[] pointing to null if there is no current outbound buffer **************************************************************************/ synchronized char[] nextBuffer() { if (out_buffers_len < 1) { return null; } return out_buffers.head()[o_offset .. $]; } Conduit cond; CircularSeq!(char[]) out_buffers; int out_buffers_len; int ibuf_len; int o_offset; Logger log; }