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:
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();
- protected bool _restartInterruptedSystemCall;
- Restart interrupted system calls when blocking inside a call to select.
- bool restartInterruptedSystemCall();
- Indicates whether interrupted system calls will be restarted when
blocking inside a call to select.
- void restartInterruptedSystemCall(bool value);
- Sets whether interrupted system calls will be restarted when
blocking inside a call to select.
- abstract void open(uint size, uint maxEvents);
- Initialize the selector.
Params:
uint size |
value that provides a hint for the maximum amount of
conduits that will be registered |
uint maxEvents |
value that provides a hint for the maximum amount of
conduit events that will be returned in the selection
set per call to select. |
- abstract void close();
- 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.
- abstract void register(ISelectable conduit, Event events, Object attachment);
- Associate a conduit to the selector and track specific I/O events.
Params:
ISelectable conduit |
conduit that will be associated to the selector |
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 |
Examples:
AbstractSelector selector;
SocketConduit conduit;
MyClass object;
selector.register(conduit, Event.Read | Event.Write, object);
- deprecated final void reregister(ISelectable conduit, Event events, Object attachment = null);
- Deprecated, use register instead
- abstract 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.
- int select();
- 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);
- 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:
double timeout |
the 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.
- abstract 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.
- abstract ISelectionSet selectedSet();
- 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.
- abstract 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 be null. No exception will be thrown by this method.
- abstract size_t count();
- Return the number of keys resulting from the registration of a conduit
to the selector.
- timeval* toTimeval(timeval* tv, TimeSpan interval);
- Cast the time duration to a C timeval struct.
- protected void checkErrno(string file, size_t line);
- Check the 'errno' global variable from the C standard library and
throw an exception with the description of the error.
Params:
string file |
Name of the source file where the check is being made; you
would normally use _FILE__ for this parameter. |
size_t line |
Line number of the source file where this method was called;
you would normally use _LINE__ for this parameter.
- 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.
|