tango.io.selector.EpollSelector

License:

BSD style: see license.txt

Author:

Juan Jose Comellas
class EpollSelector : AbstractSelector [public] #
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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 AbstractSelector.select select #
Alias for the select() method as we're not reimplementing it in this class.
uint DefaultSize [public, const] #
Default number of SelectionKey's that will be handled by the EpollSelector.
uint DefaultMaxEvents [public, const] #
Default maximum number of events that will be received per invocation to select().
SelectionKey[ISelectable.Handle] _keys [private] #
Map to associate the conduit handles with their selection keys
int _epfd [private] #
File descriptor returned by the epoll_create() system call.
epoll_event[] _events [private] #
Array of events that is filled by epoll_wait() inside the call to select().
ISelectionSet _selectionSetIface [private] #
Persistent ISelectionSet-impl.
int _eventCount [private] #
Number of events resulting from the call to select()
~this() #
Destructor.
void open(uint size = DefaultSize, uint maxEvents = DefaultMaxEvents) [public] #
Open the epoll selector, makes a call to epoll_create()

Params:

sizeMaximum amount of conduits that will be registered; it will grow dynamically if needed.
maxEventsMaximum 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() [public] #
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() [public] #
Return the number of keys resulting from the registration of a conduit to the selector.
void register(ISelectable conduit, Event events, Object attachment = null) [public] #
Associate a conduit to the selector and track specific I/O events. If a conduit is already associated, changes the events and attachment.

Params:

conduitConduit that will be associated to the selector; must be a valid conduit (i.e. not null and open).
eventsBit mask of Event values that represent the events that will be tracked for the conduit.
attachmentOptional 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:

1
selector.register(conduit, Event.Read | Event.Write, object);
void unregister(ISelectable conduit) [public] #
Remove a conduit from the selector.

Params:

conduitConduit 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) [public] #
Wait for I/O events from the registered conduits for a specified amount of time.

Params:

timeoutTimeSpan 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 : ISelectionSet [protected] #
Class used to hold the list of Conduits that have received events.

See Also:

ISelectionSet
int opApply(int delegate(ref SelectionKey) dg) [public] #
Iterate over all the Conduits that have received events.
ISelectionSet selectedSet() [public] #
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) [public] #
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(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.