tango.io.selector.AbstractSelector

License:

BSD style: see license.txt

Author:

Juan Jose Comellas
class AbstractSelector : ISelector [abstract] #
Base class for all selectors.
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().

See Also:

ISelector

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.net.device.Socket;
import tango.io.Stdout;

AbstractSelector selector;
SocketConduit conduit1;
SocketConduit conduit2;
MyClass object1;
MyClass object2;
uint 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("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();
bool _restartInterruptedSystemCall [protected] #
Restart interrupted system calls when blocking inside a call to select.
bool restartInterruptedSystemCall() [public] #
Indicates whether interrupted system calls will be restarted when blocking inside a call to select.
void restartInterruptedSystemCall(bool value) [public] #
Sets whether interrupted system calls will be restarted when blocking inside a call to select.
void open(uint size, uint maxEvents) [public, abstract] #
Initialize the selector.

Params:

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) [public, abstract] #
Associate a conduit to the selector and track specific I/O events.

Params:

conduitconduit that will be associated to the selector
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
AbstractSelector selector;
SocketConduit conduit;
MyClass object;

selector.register(conduit, Event.Read | Event.Write, object);
void reregister(ISelectable conduit, Event events, Object attachment = null) [public, final] #
Deprecated, use register instead
void unregister(ISelectable conduit) [public, abstract] #
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.
int select() [public] #
Wait for I/O events from the registered conduits for a specified amount of time.

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.

Remarks:

This method is the same as calling select(TimeSpan.max).
int select(double timeout) [public] #
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.

Params:

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.
int select(TimeSpan timeout) [public, abstract] #
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.
ISelectionSet selectedSet() [public, abstract] #
Causes the first call to select() that has not yet returned to return immediately.
If another thread is currently blocked in an call to any of the select() methods then that call will return immediately. If no selection operation is currently in progress then the next invocation of one of these methods will return immediately. In any case the value returned by that invocation may be non-zero. Subsequent invocations of the select() methods will block as usual unless this method is invoked again in the meantime.

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 be null. No exception will be thrown by this method.
timeval* toTimeval(timeval* tv, TimeSpan interval) [public] #
Cast the time duration to a C timeval struct.
void checkErrno(char[] file, size_t line) [protected] #
Check the 'errno' global variable from the C standard library and throw an exception with the description of the error.

Params:

filename of the source file where the check is being made; you would normally use __FILE__ for this parameter.
lineline number of the source file where this method was called; you would normally use __LINE__ for this parameter.

Throws:

RegisteredConduitException when the conduit should not be registered but it is (EEXIST); UnregisteredConduitException when the conduit should be registered but it isn't (ENOENT); InterruptedSystemCallException when a system call has been interrupted (EINTR); OutOfMemoryException if a memory allocation fails (ENOMEM); SelectorException for any of the other cases in which errno is not 0.