Basicaly, purpose of this library is to provide suffiscient mechanisms to handle independant data streams of different kind in asynchronous interactive processes (called data handlers) over a network.
This implies :
This library has been set up to use with the libWhisper library.
The nrtThread
class defines a process (method) that be threaded. This
is an abstract class since the threaded method, execute(void *)
, is
purely virtual.
When this class is derived, it is expected that either create(void *)
or createDetached(void *)
is called explicitly (e.g. in the
constructor). create
makes a joinable thread, and
createDetached
a detached one.
In both cases, the th protected variable holds the last created thread identifier.
nrtThread
holds a internal synchronisation variable that can,
directly or not, used through the kill(nrtThread *)
(current thread
activates de conditional variable of the given thread) and
wait(pthread_cond_t *_cond = 0)
(current thread is waiting for the
activation of a synchronisation variable, its own by default) methods.
nrtCyclicThread
(inherited from nrtThread
) has a special
behaviour; it calls the virtual handle(void)
method periodicaly.
Use setSecs(int)
or Secs(void)
to access period.
The internal EOT parameter has to be set to 1 whenever the thread has to be killed.
Classical mutex is provided by the rtMutex
class. It got essentialy
two accesors : P(void)
(pick the ``token'') and R(void)
(release it).
rtRecursiveMutex
(that inherits from rtMutex
class) allows
a predefined number of ``token'' to be picked at a time. Number is an
optional argument to class's constructor (default is 16).
A shared data can be written by one writer, at a time, or readen by many
readers. Basic operations are provided by
begWrite(void)
/endWrite(void)
and begRead(void)
/endRead(void)
methods.
Readers(void)
method give the reader's number, and
DirectReaders(void)
does the same thing without implicitly
assuming any other concurent access (this can be useful precautions have
been taken by programmer). Anyway, those methods are situated at a very
low level, and you probably won't care.
rtSharedInt
holds a single shared integer that can be read using
Value(void)
or DirectValue(void)
methods, and sets
by set(int _value)
or prefixed ++
and -
-
operators.
A paramater (rtParameter
class) has following protected char* members:
name
label
unit
Accessors have same name, with an upcased first character.
rtIntegerParameter
is derived from rtParameter
and rtSharedInt
and can be cloned using the
rtIntegerParameter *clone(void)
method.
It appears that a intermediate class could introduce a more flexible implementation.
rtParameters
defines a fixed number of pointers to some parameters.
You'll probably need the AddInt(...)
, GetInt(int _index)
,
and GetInt(char *_name)
methods to handle parameters.
rtSocket
defines a standard socket and provides tree important
methods :
void send(char *buffer, int _length);
,
void recv(char **buffer, int _length);
and
void recv(char *buffer, int _length);
.
It is used as the base of following classes; they all use the TCP network protocol.
rtSocketClient
is used to connect to an rtSocketServer
IPC server. Connection is made using the
void connect(char *_addr, int _port);
method.
Remember that this class inherits rtSocket
.
rtSocketServer
can be used as IPC minimal server. It adds to
the basical rtSocket
methods the protected and purely virtual
void handleClient(rtSocket *_socket)
method.
rtStreamWriterSocket
waits for clients, encodes incoming data
stream, and sends it to all connected clients, via different sockets.
For now, four clients can be connected simultaneously.
void handleSound(rtDataStreamBlock *block)
has probably to be
adapted to particular uses.
rtStreamReaderSocket
constructor allows connecting to any instance
of type rtStreamWriterSocket
, then incoming data are handled
in rtDataHandler's `handle' familly methods (for instance
void handleSound(rtDataStreamBlock *block)
).
WHISPER has a specific way to handle data. That means that both computing processes and data are some pre-defined WHISPER's objects.
A data handler (that processes data) has incoming and outgoing data streams
that consists of data blocks. Futhermore, each data handler is hold by a
chain (whisperChain
); introducing therefore another level of
flexibility.
Whenever a incoming block arrives, handler (which is a thread) is signaled,
and increments its waitingBlocks
shared variable. Then, each block
is readen through the incoming data stream's readNext(...)
method
and forwarded to one of the handle...
methods.
A data block is a typed array of characters with arbitrary length. Since
each data block can be read asynchronously by data handlers (inherited from
a nrtThread
), it has to be aware of the number of future reading
that are left.
When a block isn't useable anymore by any of its reading handlers, it is automaticaly deleted from the stream its belong to.
In WHISPER, a data stream consists of ordered independant data stream blocks.
Few methods are available to handle streams :
chain(int _type, char *_buffer, int _length)
and
*chain(rtDataStreamBlock *)
allows programmer to chain a new block
into the stream.
readNext(rtDataStreamBlock *)
returns the block following the given
block. But it hasn't to be called directly by programmer.
Some other facilities are providen to compute stream rate and such things.
A chain can hold many dependant data handlers. It has a name, and some convenience methods to report messages or errors.
Since whisperChain
class inherits nrtCyclicThread
, it
executes a virtual handle(void)
method periodicaly. By default,
this method does nothing.
In brief, a WHISPER application (whisperApplication
) is a
nrtCyclicThread
that can manage some WHISPER chains.
Most important providen methods are probably addChain(char *_name)
,
setCurrentToLast(void)
and the message handling methods.
First of all, the application must instanciate a chain, using
addChain(char *_name)
and declare it as default chain
(setCurrentToLast(void)
.
Thus, the addHandler(rtDataHandler *)
can be called and any
new handler'll go in the default chain.