/* -*-Mode: indented-text;-*- */
/** \mainpage SigCX - SigC++ Extras
\section sigcx_intro Introduction
libSigCX (or SigCX for short) is an extension of libSigC++,
centered around cross-thread signals; that are signals that are
emitted in one thread and can be received in another thread. This
provides an simple, elegant and safe method of cross-thread
communcation.
This manual consists of two parts, a tutorial of how to use SigCX and
a reference part that can be accessed via the quick-links on the top
of this page.
The SigCX tutorial consists of the following sections:
- Section \ref sigcx_features is a show-off list of
features SigCX provides and is intended to draw your interest to
SigCX.
- Section \ref sigcx_starting gets you started using SigCX
by explaining a small "Hello-World!"-style program.
- Section \ref sigcx_details explains the
abstractions SigCX uses and how they interact.
\htmlonly
Go to the next section or return to the
index.
\endhtmlonly
*/
/** \page sigcx_features Features
As already mentioned, SigCX focuses on threading.
It has the following features:
- A full threading API, including classes for threads, semaphores,
mutual exclusions and thread-private data. The API can be compiled
against either POSIX Threads (pthreads) or GLib threads without
affecting binary compatibilty (ABI).
- A dispatcher class that provides an abstraction of a event loop and a
stand-alone as well as a SigC++ compatible
way of invoking slots in other threads, including creating proxy slots
that will invoke the original slot in another thread.
\htmlonly
Go to the next section or return to the
index.
\endhtmlonly
*/
/** \page sigcx_starting Starting
In my opinion, the best way of getting started with a new library is
by examining example code. So in this section, you will see a simple,
short "Hello-World!"-style example on how to use SigCX.
The examples assume you are familiar with the basic concepts of the
SigC++ library.
\section sigcx_example1 A Simple Example
\dontinclude hello_world.cc
First we include the headers for the threading API and the
cross-thread tunnels:
\until thread_tunnel
Then we import the relevant namespaces:
\until SigCX::Threads
We can then derive a class from the StandardDispatcher
class. This class will run the dispatcher in a seperate thread, so we can
create a tunnel to this thread (A tunnel is used to
transfer callbacks to the thread and execute them there).
\until public:
In our class we implement a greet() that just displays a message.
\until };
Now the main function:
\until {
Here we create a HelloWorld object, and a \c ThreadTunnel to it, which runs
the dispatcher of \c hello in a new thread.
\until tunn(hello)
Then we send invoke the HelloWorld::greet() method by calling the
\c tunnel() function. The template arguments specify the return
type and argument type. You only need them when the compiler cannot
instantiate the \c tunnel() function on its own.
\until tunnel(
Note that the \c tunnel() invocation returns immediatly,
as the passed slot will be invoked asynchronously.
As an alternative, you can create a proxy tunnel with \c open_tunnel()
and invoke that:
\until tunneled_slot
The \c tunneled_slot is also asynchronous, so you cannot use its
return value (wich is \c void in this case, anyway).
Now we are done with our \c HelloWorld thread, so we send an exit message
to it's dispatcher. Note the last argument to the \c tunnel() call. It
is by default initialized to \c false, but if you pass \c true, the method
waits until the slot has finished execution. So we are sure that after this
call all previously sent messages have been processed.
\until }
\section sigcx_gtkmm_example A GUI Example
As libSigCX is quite useful for GUI programming (using multithreading
to provide a non-blocking GUI) and integrates very well with gtkmm, a gtkmm example comes with
libSigCX since version 0.6.4. The source code is commented quite well
(feel free to suggest improvements, so there is no line-by-line
walkthrough.
\include gtkmm_example.cc
\htmlonly
Go to the next section, to the
previous section or return to the
index.
\endhtmlonly
*/
/** \page sigcx_details Diving into the Details
In this section, I will sketch the concepts of SigCX, giving you an
understanding how things work.
\section sigcx_threading The threading model
SigCX provides a full API for threads, including classes for threads
and various means of synchronisation (condition, mutex, semaphore) and
a way to create thread-private data.
In the following, the concepts are described:
A thread is a execution context within a program. A
multi-threaded program is a program that has multiple paths of
execution (threads),
which execute concurrently and share the same address space. This
makes threads distinct from processes, as processes also execute
concurrently, but have distinct address spaces. In general, there
may be one or more threads per process.
In SigCX, you define a new thread by instantiating the \c Thread class
and passing it a slot of the threads work function. This slot
is then called in the context of the new thread and executes in
concurrency with the rest of the program.
- A mutex (mutual exclusion) is a lock that can be obtained
by exactly one execution context (thread) at a time. Any other attempt
to obtain the lock results in blocking the thread that attempted to
obtain it until the lock is released. Mutexes can be used to synchronize
the access of shared data. Every thread accessing the data aquires a mutex
before the access and releases it after the access. This way the data
always accessed by only one thread and thus stays consistent.
- A semaphore is an integer counter that allows two operations
on it: \em up and \em down. The \em up operation simply increments
the counter by one, the \em down blocks until an \em up operation is
performed, if the counter is zero. After blocking (or if the counter
was greater than zero), it decrements the counter.
- A condition variable represents a condition that can be
waited upon. The condition can be signalled to wake one thread waiting
on it up, or 'broadcasted' to wake all waiting threads up.
- Thread-private data is data that is local to a thread, that is,
it can only be accessed from that thread. It behaves like a thread-split
static.
\section sigcx_dispatcher The Dispatcher concept
A dispatcher is a facility where one can register handlers for various
events and that invokes the handlers if these events happen. The
dispatcher class in SigCX has support for input, output and exception
handlers on file descriptors, timeout handlers and handlers for signals
(those issued by raise()).
\section sigcx_tunnel The Tunnel concept
A SigCX tunnel is a device that has a source and destination end. It
allows callbacks to be sent from the source to the destination end. As
callbacks are received by the destination end, they are invoked
(executed) in the order they are sent. Normally the callbacks are
executed asynchronously, that means when you send a callback, you
regain control immediatly. If this behaviour is not intended, e.g. you
have to wait for the callbacks' result, you can tell the tunnel to
execute the callback synchronously and have the send primitive wait
until the callback has finished execution.
Tunnels can be used to establish communication channels between
concurrent parts of the program, like between two threads. There is a
\c ThreadTunnel class in SigCX for this purpose. It is implemented
using a UNIX pipe to transfer the callbacks from one thread to the
other. But this class can also be used in single-threaded
applications, where the callbacks can be defered until the dispatcher
of the application handles them.
\htmlonly
Go to the previous section or return to the
index.
\endhtmlonly
*/