tango.io.selector.model.ISelector

License:

BSD style: see license.txt

Author:

Juan Jose Comellas <juanjo@comellas.com.ar>
enum Event : uint
Events that are used to register a Conduit to a selector and are returned in a SelectionKey after calling ISelector.select().
struct SelectionKey
The SelectionKey struct holds the information concerning the conduits and their association to a selector. Each key keeps a reference to a registered conduit and the events that are to be tracked for it. The 'events' member of the key can take two meanings, depending on where it's used. If used with the register() method of the selector it represents the events we want to track; if used within a foreach cycle on an ISelectionSet it represents the events that have been detected for a conduit.
The SelectionKey can also hold an optional object via the 'attachment' member. This member is very convenient to keep application-specific data that will be needed when the tracked events are triggered.

See Also:

ISelectable conduit
The conduit referred to by the SelectionKey.
Event events
The registered (or selected) events as a bit mask of different Event values.
Object attachment
The attached Object referred to by the SelectionKey.
bool isReadable() [public]
Check if a Read event has been associated to this SelectionKey.
bool isUrgentRead() [public]
Check if an UrgentRead event has been associated to this SelectionKey.
bool isWritable() [public]
Check if a Write event has been associated to this SelectionKey.
bool isError() [public]
Check if an Error event has been associated to this SelectionKey.
bool isHangup() [public]
Check if a Hangup event has been associated to this SelectionKey.
bool isInvalidHandle() [public]
Check if an InvalidHandle event has been associated to this SelectionKey.
interface ISelectionSet
Container that holds the SelectionKey's for all the conduits that have triggered events during a previous invocation to ISelector.select(). Instances of this container are normally returned from calls to ISelector.selectedSet().
size_t length() [public, abstract]
Returns the number of SelectionKey's in the set.
int opApply(scope int delegate(ref SelectionKey) dg) [public, abstract]
Operator to iterate over a set via a foreach block. Note that any modifications to the SelectionKey will be ignored.
interface ISelector
A selector is a multiplexor for I/O events associated to a Conduit. All selectors must implement this interface.
A selector needs to be initialized by calling the open() method to pass it the initial amount of conduits that it will handle and the maximum amount of events that will be returned per call to select(). In both cases, these values are only hints and may not even be used by the specific ISelector implementation you choose to use, so you cannot make any assumptions regarding what results from the call to select() (i.e. you may receive more or less events per call to select() than what was passed in the 'maxEvents' argument. The amount of conduits that the selector can manage will be incremented dynamically if necessary.

To add or modify conduit registrations in the selector, use the register() method. To remove conduit registrations from the selector, use the unregister() method.

To wait for events from the conduits you need to call any of the select() methods. The selector cannot be modified from another thread while blocking on a call to these methods.

Once the selector is no longer used you must call the close() method so that the selector can free any resources it may have allocated in the call to open().

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.model.ISelector;
import tango.io.SocketConduit;
import tango.io.Stdout;

ISelector selector;
SocketConduit conduit1;
SocketConduit conduit2;
MyClass object1;
MyClass object2;
int eventCount;

// Initialize the selector assuming that it will deal with 2 conduits and
// will receive 2 events per invocation to the select() method.
selector.open(2, 2);

selector.register(conduit, Event.Read, object1);
selector.register(conduit, 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.print("Sent 'MESSAGE' to peer\n");
                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();
void open(uint size, uint maxEvents) [public, abstract]
Initialize the selector.

Parameters:

sizevalue that provides a hint for the maximum amount of conduits that will be registered
maxEventsvalue that provides a hint for the maximum amount of conduit events that will be returned in the selection set per call to select.
void close() [public, abstract]
Free any operating system resources that may have been allocated in the call to open().

Remarks:

Not all of the selectors need to free resources other than allocated memory, but those that do will normally also add a call to close() in their destructors.
void register(ISelectable conduit, Event events, Object attachment = null) [public, abstract]
Associate a conduit to the selector and track specific I/O events. If the conduit is already part of the selector, modify the events or atachment.

Parameters:

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

Examples:

1
2
3
4
5
ISelector selector;
SocketConduit conduit;
MyClass object;

selector.register(conduit, Event.Read | Event.Write, object);
void reregister(ISelectable conduit, Event events, Object attachment = null) [public, deprecated, abstract]
Deprecated, use register instead
void unregister(ISelectable conduit) [public, abstract]
Remove a conduit from the selector.

Parameters:

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.
int select() [public, abstract]
Wait indefinitely for I/O events from the registered conduits.

Returns:

The amount of conduits that have received events; 0 if no conduits have received events within the specified timeout and -1 if there was an error.
int select(TimeSpan timeout) [public, abstract]
Wait for I/O events from the registered conduits for a specified amount of time.

Parameters:

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.
int select(double timeout) [public, abstract]
Wait for I/O events from the registered conduits for a specified amount of time.

Note:

This representation of timeout is not always accurate, so it is possible that the function will return with a timeout before the specified period. For more accuracy, use the TimeSpan version.

Note:

Implementers should define this method as:
1
select(TimeSpan.interval(timeout));

Parameters:

timeoutthe maximum amount of time in seconds 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.
ISelectionSet selectedSet() [public, abstract]
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, abstract]
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 sk) dg) [public, abstract]
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.