Selector that uses the Linux epoll* family of system calls.
This selector is the best option when dealing with large amounts of
conduits under Linux. It will scale much better than any of the other
options (PollSelector, SelectSelector). For small amounts of conduits
(n < 20) the PollSelector will probably be more performant.
See Also:
ISelector, AbstractSelector
Examples:
import tango.io.selector.EpollSelector;
import tango.net.device.Socket;
import tango.io.Stdout;
SocketConduit conduit1;
SocketConduit conduit2;
EpollSelector selector = new EpollSelector();
MyClass object1 = new MyClass();
MyClass object2 = new MyClass();
uint eventCount;
// Initialize the selector assuming that it will deal with 10 conduits and
// will receive 3 events per invocation to the select() method.
selector.open(10, 3);
selector.register(conduit1, Event.Read, object1);
selector.register(conduit2, Event.Write, object2);
eventCount = selector.select();
if (eventCount > 0)
{
char[16] buffer;
int count;
foreach (SelectionKey key; selector.selectedSet())
{
if (key.isReadable())
{
count = (cast(SocketConduit) key.conduit).read(buffer);
if (count != IConduit.Eof)
{
Stdout.format("Received '{0}' from peer\n", buffer[0..count]);
selector.register(key.conduit, Event.Write, key.attachment);
}
else
{
selector.unregister(key.conduit);
key.conduit.close();
}
}
if (key.isWritable())
{
count = (cast(SocketConduit) key.conduit).write("MESSAGE");
if (count != IConduit.Eof)
{
Stdout("Sent 'MESSAGE' to peer");
selector.register(key.conduit, Event.Read, key.attachment);
}
else
{
selector.unregister(key.conduit);
key.conduit.close();
}
}
if (key.isError() || key.isHangup() || key.isInvalidHandle())
{
selector.unregister(key.conduit);
key.conduit.close();
}
}
}
selector.close();
- alias select;
- Alias for the select() method as we're not reimplementing it in
this class.
- const uint DefaultSize;
- Default number of SelectionKey's that will be handled by the
EpollSelector.
- const uint DefaultMaxEvents;
- Default maximum number of events that will be received per
invocation to select().
- void open(uint size = DefaultSize, uint maxEvents = DefaultMaxEvents);
- Open the epoll selector, makes a call to epoll_create()
Params:
uint size |
maximum amount of conduits that will be registered;
it will grow dynamically if needed. |
uint maxEvents |
maximum amount of conduit events that will be
returned in the selection set per call to select();
this limit is enforced by this selector. |
Throws:
SelectorException if there are not enough resources to open the
selector (e.g. not enough file handles or memory available).
- void close();
- Close the selector, releasing the file descriptor that had been
created in the previous call to open().
Remarks:
It can be called multiple times without harmful side-effects.
- size_t count();
- Return the number of keys resulting from the registration of a conduit
to the selector.
- void register(ISelectable conduit, Event events, Object attachment = null);
- Associate a conduit to the selector and track specific I/O events.
If a conduit is already associated, changes the events and
attachment.
Params:
ISelectable conduit |
conduit that will be associated to the selector;
must be a valid conduit (i.e. not null and open). |
Event events |
bit mask of Event values that represent the events
that will be tracked for the conduit. |
Object attachment |
optional object with application-specific data that
will be available when an event is triggered for the
conduit |
Throws:
RegisteredConduitException if the conduit had already been
registered to the selector; SelectorException if there are not
enough resources to add the conduit to the selector.
Examples:
selector.register(conduit, Event.Read | Event.Write, object);
- void unregister(ISelectable conduit);
- Remove a conduit from the selector.
Params:
ISelectable conduit |
conduit that had been previously associated to the
selector; it can be null. |
Remarks:
Unregistering a null conduit is allowed and no exception is thrown
if this happens.
Throws:
UnregisteredConduitException if the conduit had not been previously
registered to the selector; SelectorException if there are not
enough resources to remove the conduit registration.
- int select(TimeSpan timeout);
- Wait for I/O events from the registered conduits for a specified
amount of time.
Params:
TimeSpan timeout |
TimeSpan with the maximum amount of time that the
selector will wait for events from the conduits; the
amount of time is relative to the current system time
(i.e. just the number of milliseconds that the selector
has to wait for the events). |
Returns:
The amount of conduits that have received events; 0 if no conduits
have received events within the specified timeout; and -1 if the
wakeup() method has been called from another thread.
Throws:
InterruptedSystemCallException if the underlying system call was
interrupted by a signal and the 'restartInterruptedSystemCall'
property was set to false; SelectorException if there were no
resources available to wait for events from the conduits.
- class EpollSelectionSet: tango.io.selector.model.ISelector.ISelectionSet;
- Class used to hold the list of Conduits that have received events.
See Also:
ISelectionSet
- int opApply(scope int delegate(ref SelectionKey) dg);
- Iterate over all the Conduits that have received events.
- ISelectionSet selectedSet();
- Return the selection set resulting from the call to any of the
select() methods.
Remarks:
If the call to select() was unsuccessful or it did not return any
events, the returned value will be null.
- SelectionKey key(ISelectable conduit);
- Return the selection key resulting from the registration of a conduit
to the selector.
Remarks:
If the conduit is not registered to the selector the returned
value will SelectionKey.init. No exception will be thrown by this
method.
- int opApply(scope int delegate(ref SelectionKey) dg);
- Iterate through the currently registered selection keys. Note that
you should not erase or add any items from the selector while
iterating, although you can register existing conduits again.