diff --git a/src/java/com/threerings/nio/SocketChannelAcceptor.java b/src/java/com/threerings/nio/SocketChannelAcceptor.java deleted file mode 100644 index da7a1ca53..000000000 --- a/src/java/com/threerings/nio/SocketChannelAcceptor.java +++ /dev/null @@ -1,198 +0,0 @@ -// -// $Id$ -// -// Narya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://www.threerings.net/code/narya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.nio; - -import java.util.List; -import java.util.Map; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.primitives.Ints; - -import com.samskivert.util.StringUtil; - -import com.threerings.nio.SelectorIterable.SelectFailureHandler; - -import static com.threerings.presents.Log.log; - -/** - * Listens for socket connections on a set of ports for a hostname and passes those connected - * sockets on to a listener when they're ready. {@link #listen()} must be called after - * creating the acceptor to open the channels, and then tick must be called periodically to process - * new connections. - */ -public class SocketChannelAcceptor -{ - /** Used to pass freshly accepted sockets to entities that want them. */ - public interface SocketChannelHandler - { - /** Called when a new connection has been accepted and is ready for use. */ - void handleSocketChannel (SocketChannel channel, long when); - } - - /** - * Creates a address to the given host, or the wildcard host if the hostname is - * {@link StringUtil#blank}. - */ - public static InetSocketAddress getAddress (String hostname, int port) - { - return StringUtil.isBlank(hostname) ? - new InetSocketAddress(port) : new InetSocketAddress(hostname, port); - } - - /** - * Creates an acceptor that passes socket connections on to the given handler. - * - * @param failureHandler - called when the selector is irredemably broken. - * @param bindHostname - the hostname to bind to or null for all interfaces - * @param ports - the ports to bind to, or an empty array to skip binding - * @param selectLoopTime - the amount of time to wait in select, or 0 to skip the wait at all. - */ - public SocketChannelAcceptor (SocketChannelHandler connectionHandler, - SelectFailureHandler failureHandler, String bindHostname, int[] ports, int selectLoopTime) - throws IOException - { - Preconditions.checkNotNull(ports, "Ports must be non-null."); - _bindHostname = bindHostname; - _ports = ports; - _selectorSelector = new SelectorIterable(_selector, selectLoopTime, failureHandler); - _connHandler = connectionHandler; - } - - /** - * Checks the selector for ready keys and passes any through to the handlers. - */ - public void tick (long when) - { - for (SelectionKey key : _selectorSelector) { - ServerSocketChannel ssocket = _channels.get(key); - SocketChannel channel = null; - try { - channel = ssocket.accept(); - } catch (IOException e) { - log.warning("Got exception on accept", e); - continue; - } - if (channel == null) { - // in theory this shouldn't happen because we got an ACCEPT_READY event... - log.info("Psych! Got ACCEPT_READY, but no connection."); - continue; - } -// log.debug("Accepted connection " + channel + "."); - _connHandler.handleSocketChannel(channel, when); - } - } - - /** - * Returns the ports on which we are listening for connections. - */ - public Iterable getPorts () - { - return Ints.asList(_ports); - } - - /** - * Listens for socket connections on the configured addresses. - */ - public boolean listen () - { - for (int port : _ports) { - try { - // create a listening socket and add it to the select set - final ServerSocketChannel ssocket = ServerSocketChannel.open(); - ssocket.configureBlocking(false); - - InetSocketAddress isa = getAddress(_bindHostname, port); - ssocket.socket().bind(isa); - SelectionKey sk = ssocket.register(_selector, SelectionKey.OP_ACCEPT); - _channels.put(sk, ssocket); - log.info("Server listening on " + isa + "."); - _ssockets.add(ssocket); - - } catch (IOException ioe) { - log.warning("Failure listening to socket", "hostname", _bindHostname, - "port", port, ioe); - } - } - - // NOTE: this is not currently working; it works but for whatever inscrutable reason the - // inherited channel claims to be readable immediately every time through the select() loop - // which causes the server to consume 100% of the CPU repeatedly ignoring the inherited - // channel (except when an actual connection comes in in which case it does the right - // thing) - -// // now look to see if we were passed a socket inetd style by a -// // privileged parent process -// try { -// Channel inherited = System.inheritedChannel(); -// if (inherited instanceof ServerSocketChannel) { -// _ssocket = (ServerSocketChannel)inherited; -// _ssocket.configureBlocking(false); -// registerChannel(_ssocket); -// successes++; -// log.info("Server listening on " + -// _ssocket.socket().getInetAddress() + ":" + -// _ssocket.socket().getLocalPort() + "."); - -// } else if (inherited != null) { -// log.warning("Inherited non-server-socket channel " + inherited + "."); -// } -// } catch (IOException ioe) { -// log.warning("Failed to check for inherited channel."); -// } - - // if we failed to listen on at least one port, give up the ghost - return !_channels.isEmpty(); - } - - /** - * Closes all listening sockets and shuts down. - */ - public void shutdown() - { - // unbind our listening sockets; note: because we wait for the objmgr to exit before we do, - // we will still be accepting connections as long as there are events pending - for (ServerSocketChannel ssocket : _ssockets) { - try { - ssocket.socket().close(); - } catch (IOException ioe) { - log.warning("Failed to close listening socket: " + ssocket, ioe); - } - } - } - - protected final int[] _ports; - protected final String _bindHostname; - protected final Map _channels = Maps.newHashMap(); - protected final Selector _selector = Selector.open(); - protected final SelectorIterable _selectorSelector; - protected final List _ssockets = Lists.newArrayList(); - protected final SocketChannelHandler _connHandler; -} diff --git a/src/java/com/threerings/presents/server/net/BindingConnectionManager.java b/src/java/com/threerings/presents/server/net/BindingConnectionManager.java index 0fa34766c..dee326825 100644 --- a/src/java/com/threerings/presents/server/net/BindingConnectionManager.java +++ b/src/java/com/threerings/presents/server/net/BindingConnectionManager.java @@ -27,18 +27,19 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; +import java.nio.channels.ServerSocketChannel; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.inject.Inject; import com.google.inject.Singleton; +import com.samskivert.net.AddressUtil; import com.samskivert.util.Lifecycle; +import com.samskivert.util.StringUtil; import com.threerings.presents.server.ReportManager; -import com.threerings.nio.SocketChannelAcceptor; - import static com.threerings.presents.Log.log; /** @@ -47,11 +48,10 @@ import static com.threerings.presents.Log.log; @Singleton public class BindingConnectionManager extends ConnectionManager { - @Inject public BindingConnectionManager (Lifecycle cycle, ReportManager repmgr, - IncomingEventWaitHolder incomingEventWait) + @Inject public BindingConnectionManager (Lifecycle cycle, ReportManager repmgr) throws IOException { - super(cycle, repmgr, incomingEventWait); + super(cycle, repmgr); } /** @@ -66,85 +66,127 @@ public class BindingConnectionManager extends ConnectionManager * @param socketPorts the ports on which to listen for TCP connection. * @param datagramPorts the ports on which to listen for datagram packets. */ - public void init (String socketHostname, String datagramHostname, int[] socketPorts, - int[] datagramPorts) + public void init (String socketHostname, String datagramHostname, + int[] socketPorts, int[] datagramPorts) throws IOException { Preconditions.checkNotNull(socketPorts, "Socket ports must be non-null."); Preconditions.checkNotNull(datagramPorts, "Datagram ports must be non-null. " + - "Pass a zero-length array to bind no datagram ports."); + "Pass a zero-length array to bind no datagram ports."); - // Listen for socket connections, but don't wait to select on them. The connection check - // occurs as part of ConnectionManager's incoming event loop, which already has a wait. - _socketAcceptor = new SocketChannelAcceptor(this, _failureHandler, socketHostname, - socketPorts, 0); - - _datagramPorts = datagramPorts; + _bindHostname = socketHostname; + _ports = socketPorts; _datagramHostname = datagramHostname; + _datagramPorts = datagramPorts; } @Override protected void willStart () { - if (!_socketAcceptor.listen()) { - log.warning("ConnectionManager failed to bind to any ports. Shutting down."); - _server.queueShutdown(); + super.willStart(); - } else { - // open up the datagram ports as well - for (int port : _datagramPorts) { - try { - acceptDatagrams(port); - } catch (IOException ioe) { - log.warning("Failure opening datagram channel", "hostname", _datagramHostname, - "port", port, ioe); - } + // open our TCP listening ports + int successes = 0; + for (int port : _ports) { + try { + acceptConnections(port); + successes++; + } catch (IOException ioe) { + log.warning("Failure listening to socket", "hostname", _bindHostname, + "port", port, ioe); } } - } + if (successes == 0) { + log.warning("ConnectionManager failed to bind to any ports. Shutting down."); + _server.queueShutdown(); + return; + } - @Override - protected void processIncomingEvents (long iterStamp) - { - // first check for any new sockets, ready to be accepted - _socketAcceptor.tick(iterStamp); - - // then do our standard processing for existing connected sockets - super.processIncomingEvents(iterStamp); + // open up the datagram ports as well + for (int port : _datagramPorts) { + try { + acceptDatagrams(port); + } catch (IOException ioe) { + log.warning("Failure opening datagram channel", "hostname", _datagramHostname, + "port", port, ioe); + } + } } @Override protected void didShutdown () { super.didShutdown(); - // TODO: consider closing the listen sockets earlier, like in the shutdown method - _socketAcceptor.shutdown(); + + // unbind our listening sockets; note: because we wait for the objmgr to exit before we do, + // we will still be accepting connections as long as there are events pending. + for (ServerSocketChannel ssocket : _ssockets) { + try { + ssocket.socket().close(); + } catch (IOException ioe) { + log.warning("Failed to close listening socket: " + ssocket, ioe); + } + } + // unbind datagram channels, if any for (DatagramChannel datagramChannel : _datagramChannels) { datagramChannel.socket().close(); } } + protected void acceptConnections (int port) + throws IOException + { + // create a listening socket + final ServerSocketChannel ssocket = ServerSocketChannel.open(); + ssocket.configureBlocking(false); + InetSocketAddress isa = AddressUtil.getAddress(_bindHostname, port); + ssocket.socket().bind(isa); + + // and add it to the select set + SelectionKey sk = ssocket.register(_selector, SelectionKey.OP_ACCEPT); + _handlers.put(sk, new NetEventHandler() { + public int handleEvent (long when) { + try { + handleAcceptedSocket(ssocket.accept()); + } catch (IOException ioe) { + log.info("Failure accepting connected socket: " +ioe); + } + // there's no easy way to measure bytes read when accepting a connection, so we + // claim nothing + return 0; + } + public boolean checkIdle (long now) { + return false; // we're never idle + } + public void becameIdle () { + // we're never idle + } + }); + _ssockets.add(ssocket); + log.info("Server listening on " + isa + "."); + } + protected void acceptDatagrams (int port) throws IOException { - // create a channel and add it to the select set + // create a channel final DatagramChannel channel = DatagramChannel.open(); channel.socket().setTrafficClass(0x10); // IPTOS_LOWDELAY channel.configureBlocking(false); - InetSocketAddress isa = SocketChannelAcceptor.getAddress(_datagramHostname, port); + InetSocketAddress isa = AddressUtil.getAddress(_datagramHostname, port); channel.socket().bind(isa); + + // and add it to the select set SelectionKey sk = channel.register(_selector, SelectionKey.OP_READ); _handlers.put(sk, new NetEventHandler() { public int handleEvent (long when) { return handleDatagram(channel, when); } - public boolean checkIdle (long now) { return false;// Can't be idle } - public void becameIdle () {} }); _datagramChannels.add(channel); @@ -192,9 +234,9 @@ public class BindingConnectionManager extends ConnectionManager return size; } - protected SocketChannelAcceptor _socketAcceptor; - protected int[] _datagramPorts; - protected String _datagramHostname; + protected int[] _ports, _datagramPorts; + protected String _bindHostname, _datagramHostname; - protected final List _datagramChannels = Lists.newArrayList(); + protected List _ssockets = Lists.newArrayList(); + protected List _datagramChannels = Lists.newArrayList(); } diff --git a/src/java/com/threerings/presents/server/net/ConnectionManager.java b/src/java/com/threerings/presents/server/net/ConnectionManager.java index 74da66289..888e42386 100644 --- a/src/java/com/threerings/presents/server/net/ConnectionManager.java +++ b/src/java/com/threerings/presents/server/net/ConnectionManager.java @@ -38,6 +38,8 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.inject.Inject; import com.google.inject.Singleton; +import com.google.inject.name.Named; + import com.samskivert.util.IntMap; import com.samskivert.util.IntMaps; import com.samskivert.util.Invoker; @@ -52,6 +54,7 @@ import com.threerings.io.FramingOutputStream; import com.threerings.io.ObjectOutputStream; import com.threerings.io.UnreliableObjectInputStream; import com.threerings.io.UnreliableObjectOutputStream; +import com.threerings.nio.SelectorIterable; import com.threerings.presents.annotation.AuthInvoker; import com.threerings.presents.client.Client; @@ -68,10 +71,6 @@ import com.threerings.presents.server.PresentsServer; import com.threerings.presents.server.ReportManager; import com.threerings.presents.util.DatagramSequencer; -import com.threerings.nio.SocketChannelAcceptor; -import com.threerings.nio.SelectorIterable; -import com.threerings.nio.SelectorIterable.SelectFailureHandler; - import static com.threerings.presents.Log.log; /** @@ -79,29 +78,24 @@ import static com.threerings.presents.Log.log; * connection objects interact closely with the connection manager because network I/O is done via * a poll()-like mechanism rather than via threads.

* - * ConnectionManager doesn't directly accept TCP connections; it expects an external entity to do - * so and call its {@link #handleSocketChannel} method. - * - * @see BindingConnectionManager - * @see SocketChannelAcceptor + * ConnectionManager doesn't directly accept TCP connections; it expects a custom derived class or + * external entity to do so and call its {@link #handleAcceptedSocket} method. + * See {@link BindingConnectionManager} for the standalone implementation. */ @Singleton public class ConnectionManager extends LoopingThread - implements Lifecycle.ShutdownComponent, ReportManager.Reporter, - SocketChannelAcceptor.SocketChannelHandler + implements Lifecycle.ShutdownComponent, ReportManager.Reporter { /** * Creates a connection manager instance. */ - @Inject public ConnectionManager (Lifecycle cycle, ReportManager repmgr, - IncomingEventWaitHolder incomingEventWait) + public ConnectionManager (Lifecycle cycle, ReportManager repmgr) throws IOException { super("ConnectionManager"); cycle.addComponent(this); repmgr.registerReporter(this); - _selectorSelector = new SelectorIterable( - _selector, incomingEventWait.value, _failureHandler); + _selector = Selector.open(); } /** @@ -145,6 +139,39 @@ public class ConnectionManager extends LoopingThread return _stats.clone(); } + /** + * This is called to introduce a new active socket into the system. For Presents systems + * handling their own socket listening, this is called by the {@link BindingConnectionManager}. + * If Presents is embedded in another framework that handles socket acceptance, this will be + * called by a custom ConnectionManager derived class that integrates Presents with that + * system. + */ + public void handleAcceptedSocket (SocketChannel channel) + { + try { + // create a new authing connection object to manage the authentication of this client + // connection and register it with our selection set + channel.configureBlocking(false); + AuthingConnection aconn = new AuthingConnection(); + aconn.selkey = channel.register(_selector, SelectionKey.OP_READ); + aconn.init(this, channel, System.currentTimeMillis()); + _handlers.put(aconn.selkey, aconn); + synchronized (this) { + _stats.connects++; + } + + } catch (IOException ioe) { + // no need to generate a warning because this happens in the normal course of events + log.info("Failure accepting new connection: " + ioe); + // make sure we don't leak a socket if something went awry + try { + channel.socket().close(); + } catch (IOException ioe2) { + log.warning("Failed closing aborted connection: " + ioe2); + } + } + } + /** * Opens an outgoing connection to the supplied address. The connection will be opened in a * non-blocking manner and added to the connection manager's select set. Messages posted to the @@ -224,33 +251,6 @@ public class ConnectionManager extends LoopingThread report.append(bytesOut*1000/sinceLast).append(" bps\n"); } - // from interface SocketChannelAcceptor.SocketChannelHandler - public void handleSocketChannel (SocketChannel channel, long when) - { - try { - // create a new authing connection object to manage the authentication of this client - // connection and register it with our selection set - channel.configureBlocking(false); - AuthingConnection aconn = new AuthingConnection(); - aconn.selkey = channel.register(_selector, SelectionKey.OP_READ); - aconn.init(this, channel, System.currentTimeMillis()); - _handlers.put(aconn.selkey, aconn); - synchronized (this) { - _stats.connects++; - } - - } catch (IOException ioe) { - // no need to generate a warning because this happens in the normal course of events - log.info("Failure accepting new connection: " + ioe); - // make sure we don't leak a socket if something went awry - try { - channel.socket().close(); - } catch (IOException ioe2) { - log.warning("Failed closing aborted connection: " + ioe2); - } - } - } - @Override // from LoopingThread public boolean isRunning () { @@ -258,6 +258,78 @@ public class ConnectionManager extends LoopingThread return super.isRunning() || _omgr.isRunning(); } + @Override // from LoopingThread + protected void willStart () + { + super.willStart(); + + log.info("Creating selector selector!"); + _selectorSelector = new SelectorIterable( + _selector, _selectLoopTime, new SelectorIterable.SelectFailureHandler() { + public void handleSelectFailure (Exception e) { + log.error("One of our selectors crapped out completely. " + + "Shutting down the connection manager.", e); + shutdown(); + } + }); + } + + @Override // from LoopingThread + protected void iterate () + { + // performs the select loop; this is the body of the conmgr thread + final long iterStamp = System.currentTimeMillis(); + + // note whether or not we're generating a debug report + boolean generateDebugReport = (iterStamp - _lastDebugStamp > DEBUG_REPORT_INTERVAL); + if (DEBUG_REPORT && generateDebugReport) { + _lastDebugStamp = iterStamp; + } + + // close any connections that have been queued up to die + Connection dconn; + while ((dconn = _deathq.getNonBlocking()) != null) { + // it's possible that we caught an EOF trying to read from this connection even after + // it was queued up for death, so let's avoid trying to close it twice + if (!dconn.isClosed()) { + dconn.close(); + } + } + + // close connections that have had no network traffic for too long + for (NetEventHandler handler : _handlers.values()) { + if (handler.checkIdle(iterStamp)) { + // this will queue the connection for closure on our next tick + handler.becameIdle(); + } + } + + // send any messages that are waiting on the outgoing overflow and message queues + sendOutgoingMessages(iterStamp); + + // we may be in the middle of shutting down (in which case super.isRunning() is false but + // isRunning() is true); this is because we stick around until the dobject manager is + // totally done so that we can send shutdown-related events out to our clients; during + // those last moments we don't want to accept new connections or read any incoming messages + if (super.isRunning()) { + // start up any outgoing connections that need to be connected + Tuple pconn; + while ((pconn = _connectq.getNonBlocking()) != null) { + startOutgoingConnection(pconn.left, pconn.right); + } + + // check for connections that have completed authentication + processAuthedConnections(iterStamp); + + // listen for and process incoming network events + processIncomingEvents(iterStamp); + } + + if (DEBUG_REPORT && generateDebugReport) { + log.info("CONMGR status " + getStats()); + } + } + /** * Performs the authentication process on the specified connection. This is called by {@link * AuthingConnection} itself once it receives its auth request. @@ -347,64 +419,6 @@ public class ConnectionManager extends LoopingThread } } - /** - * Performs the select loop. This is the body of the conmgr thread. - */ - @Override - protected void iterate () - { - final long iterStamp = System.currentTimeMillis(); - - // note whether or not we're generating a debug report - boolean generateDebugReport = (iterStamp - _lastDebugStamp > DEBUG_REPORT_INTERVAL); - if (DEBUG_REPORT && generateDebugReport) { - _lastDebugStamp = iterStamp; - } - - // close any connections that have been queued up to die - Connection dconn; - while ((dconn = _deathq.getNonBlocking()) != null) { - // it's possible that we caught an EOF trying to read from this connection even after - // it was queued up for death, so let's avoid trying to close it twice - if (!dconn.isClosed()) { - dconn.close(); - } - } - - // close connections that have had no network traffic for too long - for (NetEventHandler handler : _handlers.values()) { - if (handler.checkIdle(iterStamp)) { - // this will queue the connection for closure on our next tick - handler.becameIdle(); - } - } - - // send any messages that are waiting on the outgoing overflow and message queues - sendOutgoingMessages(iterStamp); - - // we may be in the middle of shutting down (in which case super.isRunning() is false but - // isRunning() is true); this is because we stick around until the dobject manager is - // totally done so that we can send shutdown-related events out to our clients; during - // those last moments we don't want to accept new connections or read any incoming messages - if (super.isRunning()) { - // start up any outgoing connections that need to be connected - Tuple pconn; - while ((pconn = _connectq.getNonBlocking()) != null) { - startOutgoingConnection(pconn.left, pconn.right); - } - - // check for connections that have completed authentication - processAuthedConnections(iterStamp); - - // listen for and process incoming network events - processIncomingEvents(iterStamp); - } - - if (DEBUG_REPORT && generateDebugReport) { - log.info("CONMGR status " + getStats()); - } - } - /** * Converts connections that have completed the authentication process into full running * connections and notifies the client manager that new connections have been established. @@ -929,14 +943,6 @@ public class ConnectionManager extends LoopingThread protected int _msgs, _partials; } - protected final SelectFailureHandler _failureHandler = new SelectFailureHandler() { - public void handleSelectFailure (Exception e) { - log.error("One of our selectors crapped out completely. " + - "Shutting down the connection manager.", e); - shutdown(); - } - }; - /** Used to create an overflow queue on the first partial write. */ protected PartialWriteHandler _oflowHandler = new PartialWriteHandler() { public void handlePartialWrite (Connection conn, ByteBuffer msgbuf) { @@ -946,19 +952,13 @@ public class ConnectionManager extends LoopingThread } }; - /** Helper for Guice to allow the incoming event wait to be injected optionally. */ - protected static class IncomingEventWaitHolder - { - @Inject(optional=true) @IncomingEventWait int value = SELECT_LOOP_TIME; - } - /** Handles client authentication. The base authenticator is injected but optional services * like the PeerManager may replace this authenticator with one that intercepts certain types * of authentication and then passes normal authentications through. */ @Inject(optional=true) protected Authenticator _author = new DummyAuthenticator(); protected List _authors = Lists.newArrayList(); - protected Selector _selector = Selector.open(); + protected Selector _selector; protected SelectorIterable _selectorSelector; /** Maps selection keys to network event handlers. */ @@ -993,18 +993,19 @@ public class ConnectionManager extends LoopingThread /** A runnable to execute when the connection manager thread exits. */ protected volatile Runnable _onExit; + /** Duration in milliseconds for which we wait for network events before checking our running + * flag to see if we should still be running. We don't want to loop too tightly, but we need to + * make sure we don't sit around listening for incoming network events too long when there are + * outgoing messages in the queue. */ + @Inject(optional=true) @Named("presents.net.selectLoopTime") + protected int _selectLoopTime = 100; + // some dependencies @Inject @AuthInvoker protected Invoker _authInvoker; @Inject protected ClientManager _clmgr; @Inject protected PresentsDObjectMgr _omgr; @Inject protected PresentsServer _server; - /** How long we wait for network events before checking our running flag to see if we should - * still be running. We don't want to loop too tightly, but we need to make sure we don't sit - * around listening for incoming network events too long when there are outgoing messages in - * the queue. */ - protected static final int SELECT_LOOP_TIME = 100; - /** Used to denote asynchronous close requests. */ protected static final byte[] ASYNC_CLOSE_REQUEST = new byte[0]; diff --git a/src/java/com/threerings/presents/server/net/IncomingEventWait.java b/src/java/com/threerings/presents/server/net/IncomingEventWait.java deleted file mode 100644 index fd13149ce..000000000 --- a/src/java/com/threerings/presents/server/net/IncomingEventWait.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $Id$ -// -// Narya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://www.threerings.net/code/narya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.presents.server.net; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.google.inject.BindingAnnotation; - -/** - * Identifies the amount of time to wait for incoming events in ConnectionManager's select. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.PARAMETER }) -@BindingAnnotation -public @interface IncomingEventWait -{ -}