Specifications

CHAPTER 4. DESIGN AND ARCHITECTURE 24
First, the configuration file is parsed and the included options are set. Secondly, the
command line arguments are evaluated and the included options are set. Options previously
set by parsing the configuration file are overwritten.
In order to examine the runtime behavior of the Input Abstraction Layer, a multi level
logging system is needed. Depending on which logging level is set, the daemon issues more or
less debug output. The following logging levels are needed: error (critical errors only), warning
(critical errors and warnings), info (critical errors, warnings and information) and debug (all
debug messages).
4.3 Modular Input Interface
As demanded by the first functional requirement, the Input Abstraction Layer has to take
care of the unattended input interfaces. Depending on the used hardware, input interfaces
vary a lot. It is suggestive to design a modular input interface for the Input Abstraction
Layer. For each input interface provided by the Linux kernel, a corresponding module for the
Input Abstraction Layer is necessary. Such a module is autonomous to a large extent: once
the daemon has loaded a module, the module accesses its kernel input interface and reports
occurring events.
The Input Abstraction Layer’s daemon is responsible for loading the modules upon start-
up. Each module needs to implement an initialization routine, which is setting up the access
to the kernel interface the module is designed for. If the initialization succeeds, the module
subsequently reports input events. Like the daemon, the modules need to be configured. Since
the modules are loaded by the daemon, the configuration of the modules needs to be integrated
into the daemon functions which implement the parsing of both the configuration file and the
command line options.
The daemon, in conjunction with its modules, can be implemented in two different ways:
either by using threads or by using an event loop. Programming with threads is difficult and
tough to debug. Threads are hard to synchronize and the risk of deadlocks is given. In contrast
to an event loop, threads are providing concurrency—several execution streams are running in
the same context. An event loop is a single execution stream which is event driven. Occurring
events are processed by assigned event handlers. The only significant benefit offered by threads
is concurrency. Since the modules do not need to execute code concurrently, it gives no sense
to use threads for the implementation. Using threads would actually cause problems, since
events would have to be sequenced to ensure that they are reported in the correct chronological
order.
To implement the event loop, the GLib (http://www.gtk.org) library can be used. GLib
is the core library used by the Gimp Toolkit (GTK+) and Gnome, though it has nothing to do
with GUI programming or the X Window System. Beside other useful functions, the library
offers an excellent way to implement event loops.
It is important to bear in mind that the modules are autonomous regarding what they are
doing. But all modules are running in the context of the daemon. This is why the mo dules are
not autonomous regarding when they are actually receiving control to execute their code. To
achieve a flexible architecture, adding and removing modules of the Input Abstraction Layer
should not require a recompilation of the daemon. This approach can be achieved by using
dynamically loaded shared libraries.