diff tango/tango/io/selector/Selector.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/tango/io/selector/Selector.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,151 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+*******************************************************************************/
+
+module tango.io.selector.Selector;
+
+/**
+ * A multiplexor of conduit I/O events.
+ *
+ * A Selector can wait for I/O events (Read, Write, etc.) for multiple
+ * conduits efficiently (i.e. without consuming CPU cycles).
+ *
+ * The Selector is an alias for your system's most efficient I/O multiplexor,
+ * which will be determined during compilation.
+ *
+ * To create a Selector you need to use the open() method and when you decide
+ * you no longer need it you should call its close() method to free any system
+ * resources it may be consuming. All selectors that need to free resources
+ * when close() is called also implement a destructor that automatically calls
+ * this method. This means that if you declare your selector instance with the
+ * 'auto' keyword you won't have to worry about doing it manually.
+ *
+ * Once you have open()'ed your selector you need to associate the conduits to
+ * it by using the register() method. This method receives the conduit and the
+ * events you want to track for it. For example, if you wanted to read from
+ * the conduit you would do:
+ *
+ * ---
+ * selector.register(conduit, Event.Read, myObject);
+ * ---
+ *
+ * This method also accepts an optional third parameter to associate a
+ * user-defined object to the conduit. These three parameters together define
+ * a SelectionKey, which is what you'll receive when the conduit is "selected"
+ * (i.e. receives an event).
+ *
+ * If you need to modify your conduit's registration you need to use the
+ * reregister() method, which works like register(), but expects to be passed
+ * a conduit that has already been associated to the selector:
+ *
+ * ---
+ * selector.reregister(conduit, Event.Write, myObject);
+ * ---
+ *
+ * If you need to remove a conduit from the selector you do it by calling
+ * unregister():
+ *
+ * ---
+ * selector.unregister(conduit);
+ * ---
+ *
+ * Once you are done setting up the conduits you will want to wait for I/O
+ * events for them. To do that you need to use the select() method. This
+ * method blocks until either one of the conduits is selected or the
+ * specified timeout is reached. Even though it has two different versions:
+ * a) select(); b) select(Interval); the first one is just the same as doing
+ * select(Interval.max). In that case we don't have a timeout and
+ * select() blocks until a conduit receives an event.
+ *
+ * When select() returns you will receive an integer; if this integer is
+ * bigger than 0, it indicates the number of conduits that have been selected.
+ * If this number is 0, the it means that the selector reached a timeout, and
+ * if it's -1, then it means that there was an error. A normal block that deals 
+ * with the selection process would look like this:
+ *
+ * ---
+ * try
+ * {
+ *     int eventCount = selector.select(10.0);
+ *     if (eventCount > 0)
+ *     {
+ *         // Process the I/O events in the selected set
+ *     }
+ *     else if (eventCount == 0)
+ *     {
+ *         // Timeout
+ *     }
+ *     else if (eventCount == -1)
+ *     {
+ *         // Error
+ *     }
+ *     else
+ *     {
+ *         // Error: should never happen.
+ *     }
+ * }
+ * catch (SelectorException e)
+ * {
+ *     Stdout.format("Exception caught: {0}", e.toString()).newline();
+ * }
+ * ---
+ *
+ * Finally, to gather the events you need to iterate over the selector's
+ * selection set, which can be accessed via the selectedSet() method.
+ *
+ * ---
+ * foreach (SelectionKey key; selector.selectedSet())
+ * {
+ *     if (key.isReadable())
+ *     {
+ *         // Read from conduit
+ *         // [...]
+ *         // Then register it for writing
+ *         selector.reregister(key.conduit, Event.Write, key.attachment);
+ *     }
+ *
+ *     if (key.isWriteable())
+ *     {
+ *         // Write to conduit
+ *         // [...]
+ *         // Then register it for reading
+ *         selector.reregister(key.conduit, Event.Read, key.attachment);
+ *     }
+ *
+ *     if (key.isError())
+ *     {
+ *         // Problem with conduit; remove it from selector
+ *         selector.remove(conduit);
+ *     }
+ * }
+ * ---
+ */
+version (linux)
+{
+    public import tango.io.selector.EpollSelector;
+
+    /**
+     * Default Selector for Linux.
+     */
+    alias EpollSelector Selector;
+}
+else version(Posix)
+{
+    public import tango.io.selector.PollSelector;
+
+    /**
+     * Default Selector for POSIX-compatible platforms.
+     */
+    alias PollSelector Selector;
+}
+else
+{
+    public import tango.io.selector.SelectSelector;
+
+    /**
+     * Default Selector for Windows.
+     */
+    alias SelectSelector Selector;
+}