License:
BSD style: see license.txt
author:
Juan Jose Comellas
$(DDOC_MODULE_MEMBERS
enum
Event
;
Events that are used to register a Conduit to a selector and are returned
in a SelectionKey after calling ISelector.select().
class
SelectionKey
;
The
SelectionKey
class 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 tango.io.selector.ISelector,
tango.io.selector.ISelectionSet
- this();
- Constructor
- this(ISelectable conduit, Event events, Object attachment = null);
- Constructor
Params:
| ISelectable conduit |
conduit that will be associated to this SelectionKey |
| Event events |
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:
SocketConduit cond;
auto key = new SelectionKey(cond, Event.Read | Event.Write);
- ISelectable
conduit
();
- Return the
conduit
held by the instance.
- void
conduit
(ISelectable
conduit
);
- Set the
conduit
held by the instance
- Event
events
();
- Return the registered
events
as a bit mask of different Event values.
- void
events
(Event
events
);
- Set the registered
events
as a bit mask of different Event values.
- Object
attachment
();
- Return the attached Object held by the instance.
- void
attachment
(Object
attachment
);
- Set the attached Object held by the instance
- bool
isReadable
();
- Check if a Read event has been associated to this SelectionKey.
- bool
isUrgentRead
();
- Check if an UrgentRead event has been associated to this SelectionKey.
- bool
isWritable
();
- Check if a Write event has been associated to this SelectionKey.
- bool
isError
();
- Check if an Error event has been associated to this SelectionKey.
- bool
isHangup
();
- Check if a Hangup event has been associated to this SelectionKey.
- bool
isInvalidHandle
();
- 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().
- abstract uint
length
();
- Returns the number of SelectionKey's in the set.
- abstract int
opApply
(int delegate(ref SelectionKey) dg);
- Operator to iterate over a set via a foreach block.
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:
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();
- 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 = cast(Object)null);
- 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.
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 |
Examples:
ISelector selector;
SocketConduit conduit;
MyClass object;
selector.register(conduit, Event.Read | Event.Write, object);
- deprecated abstract void
reregister
(ISelectable conduit, Event events, Object attachment = cast(Object)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.
- abstract int
select
();
- 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.
- 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.
- abstract 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.
Note:
Implementers should define this method as:
select(TimeSpan.interval(timeout));
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 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.
- 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.
|