os: Move Genode::Config into 'config' library

Originally, the convenience utility for accessing a process
configuration came in the form of a header file. But this causes
aliasing problems if multiple compilation units access the config while
the configuration gets dynamically updated. Moving the implementation of
the accessor to the singleton object into a library solves those
problems.
This commit is contained in:
Norman Feske 2013-09-08 02:44:30 +02:00
parent a1effc5ad8
commit 8243329ad4
58 changed files with 191 additions and 153 deletions

View File

@ -4,7 +4,7 @@
# These linked against 'ldso' and filtered out for dynamically
# linked binaries
#
BASE_LIBS = base-common base cxx timed_semaphore alarm
BASE_LIBS = base-common base cxx timed_semaphore alarm config
#
# Name of Genode's dynamic linker

View File

@ -1,7 +1,7 @@
LIB_DIR = $(REP_DIR)/src/lib/usb
LIB_INC_DIR = $(LIB_DIR)/include
LIBS += base cxx dde_kit libc-setjmp
LIBS += base cxx dde_kit libc-setjmp config
SRC_CC += main.cc lx_emul.cc irq.cc timer.cc event.cc storage.cc \
input_component.cc nic.cc
SRC_C += dummies.c scsi.c evdev.c

View File

@ -41,9 +41,6 @@ struct Services
try {
config()->xml_node().sub_node("hid");
hid = true;
} catch (Config::Invalid) {
PDBG("No <config> node found - not starting any USB services");
return;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <hid> config node found - not starting the USB HID (Input) service");
}

View File

@ -1,4 +1,4 @@
TARGET = backdrop
SRC_CC = main.cc
LIBS = base libpng_static libz_static mini_c
LIBS = base libpng_static libz_static mini_c config
CC_OPT += -DPNG_USER_CONFIG

View File

@ -1,5 +1,5 @@
TARGET = launchpad
LIBS = launchpad scout_widgets
LIBS = launchpad scout_widgets config
SRC_CC = launchpad_window.cc \
launcher.cc \
main.cc

View File

@ -1,5 +1,5 @@
TARGET = liquid_fb
LIBS = scout_widgets
LIBS = scout_widgets config
SRC_CC = main.cc services.cc
INC_DIR += $(REP_DIR)/src/app/scout/include \
$(REP_DIR)/src/app/scout/include/genode \

View File

@ -1,4 +1,4 @@
TARGET = terminal
SRC_CC = main.cc
LIBS = base
LIBS = base config
SRC_BIN = $(notdir $(wildcard $(PRG_DIR)/*.tff))

View File

@ -4,7 +4,7 @@
LIBS = libc-string libc-locale libc-stdlib libc-stdio libc-gen libc-gdtoa \
libc-inet libc-stdtime libc-regex libc-compat libc-setjmp
LIBS += base
LIBS += base config
#
# Back end

View File

@ -86,9 +86,7 @@ Main_window::Main_window()
qDebug() << "filter:" << framebuffer_filter->name << "," << framebuffer_filter->ram_quota;
framebuffer_filters.prepend(framebuffer_filter);
}
} catch (Config::Invalid) {
} catch (Xml_node::Nonexistent_sub_node) {
}
} catch (Xml_node::Nonexistent_sub_node) { }
/* start the filtering framebuffer services */

View File

@ -1,5 +1,5 @@
TARGET = fb_drv
REQUIRES = vesa
SRC_CC = main.cc framebuffer.cc ifx86emu.cc hw_emul.cc
LIBS = base blit x86emu
LIBS = base blit x86emu config
INC_DIR += $(PRG_DIR)/include $(REP_DIR)/include/x86emu

View File

@ -83,7 +83,6 @@ static void read_config()
volume = (float)config_volume / 100;
}
catch (Genode::Config::Invalid) { }
catch (Genode::Xml_node::Nonexistent_sub_node) { }
catch (Genode::Xml_node::Nonexistent_attribute) { }
}

View File

@ -1,4 +1,4 @@
TARGET = ffat_fs
SRC_CC = main.cc
LIBS = base ffat_block
LIBS = base ffat_block config
INC_DIR += $(PRG_DIR)

View File

@ -14,100 +14,53 @@
#ifndef _INCLUDE__OS__CONFIG_H_
#define _INCLUDE__OS__CONFIG_H_
#include <util/xml_node.h>
#include <dataspace/client.h>
#include <rom_session/connection.h>
#include <dataspace/client.h>
#include <util/xml_node.h>
#include <base/exception.h>
namespace Genode {
class Config
{
private:
Rom_connection _config_rom;
Dataspace_capability _config_ds;
Xml_node _config_xml;
Xml_node _config_xml_node()
{
if (_config_ds.valid())
return Xml_node(env()->rm_session()->attach(_config_ds),
Genode::Dataspace_client(_config_ds).size());
else
return Xml_node("<config/>");
}
public:
/**
* Exception class for configuration errors
*/
class Invalid : public Exception { };
/**
* Constructor
*/
Config() :
_config_rom("config"),
_config_ds(_config_rom.dataspace()),
_config_xml(_config_xml_node())
{ }
Xml_node xml_node() { return _config_xml; }
/**
* Register signal handler for tracking config modifications
*/
void sigh(Signal_context_capability cap) { _config_rom.sigh(cap); }
/**
* Reload configuration
*
* \throw Invalid if the new configuration has an invalid syntax
*
* This function is meant to be called as response to a signal
* received by the signal handler as registered via 'sigh()'.
*/
void reload()
{
try {
/* re-acquire dataspace from ROM session */
if (_config_ds.valid())
env()->rm_session()->detach(_config_xml.addr());
_config_ds = _config_rom.dataspace();
/* re-initialize XML node with new config data */
_config_xml = _config_xml_node();
} catch (Genode::Xml_node::Invalid_syntax) {
PERR("Config file has invalid syntax");
throw Invalid();
}
}
};
class Config;
/**
* Return singleton instance of config
*/
static Config *config()
{
static bool config_failed = false;
if (!config_failed) {
try {
static Config config_inst;
return &config_inst;
} catch (Genode::Rom_connection::Rom_connection_failed) {
PERR("Could not obtain config file");
} catch (Genode::Xml_node::Invalid_syntax) {
PERR("Config file has invalid syntax");
}
}
/* do not try again to construct 'config_inst' */
config_failed = true;
throw Config::Invalid();
}
Config *config();
}
class Genode::Config
{
private:
Rom_connection _config_rom;
Dataspace_capability _config_ds;
Xml_node _config_xml;
public:
/**
* Constructor
*/
Config();
Xml_node xml_node();
/**
* Register signal handler for tracking config modifications
*/
void sigh(Signal_context_capability cap);
/**
* Reload configuration
*
* \throw Invalid if the new configuration has an invalid syntax
*
* This function is meant to be called as response to a signal
* received by the signal handler as registered via 'sigh()'.
*/
void reload();
};
#endif /* _INCLUDE__OS__CONFIG_H_ */

3
os/lib/mk/config.mk Normal file
View File

@ -0,0 +1,3 @@
SRC_CC = config.cc
vpath config.cc $(REP_DIR)/src/lib/config

View File

@ -1,3 +1,5 @@
SRC_CC = config_args.cc
LIBS += config
vpath %.cc $(REP_DIR)/src/lib/config_args

View File

@ -1,4 +1,4 @@
TARGET = cli_monitor
SRC_CC = main.cc
LIBS = base cli_monitor
LIBS = base cli_monitor config
INC_DIR += $(PRG_DIR)

View File

@ -1,6 +1,6 @@
TARGET = xvfb
REQUIRES = linux x11 xtest xdamage
SRC_CC = main.cc inject_input.cc
LIBS = base_hybrid syscall blit xev_track
LIBS = base_hybrid syscall blit xev_track config
EXT_OBJECTS += -lX11 -lXdamage /usr/lib/libXtst.so.6

View File

@ -2,7 +2,7 @@ TARGET = atapi_drv
REQUIRES = x86
SRC_CC = main.cc ata_device.cc atapi_device.cc io.cc ata_bus_master.cc
SRC_C = mindrvr.c
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR)/contrib $(PRG_DIR)

View File

@ -1,7 +1,7 @@
TARGET = fb_drv
REQUIRES = imx53
SRC_CC = main.cc
LIBS = base blit
LIBS = base blit config
INC_DIR += $(PRG_DIR)
vpath main.cc $(PRG_DIR)

View File

@ -7,7 +7,7 @@
TARGET = fb_drv
REQUIRES = omap4
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR)
vpath main.cc $(PRG_DIR)

View File

@ -1,7 +1,7 @@
TARGET = pci_drv
REQUIRES = x86
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR = $(PRG_DIR)/..

View File

@ -1,6 +1,6 @@
TARGET = uart_drv
REQUIRES = exynos5
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..

View File

@ -1,6 +1,6 @@
TARGET = uart_drv
REQUIRES = x86
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..

View File

@ -1,6 +1,6 @@
TARGET = kdb_uart_drv
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR)/.. $(PRG_DIR)/../..

View File

@ -1,6 +1,6 @@
TARGET = uart_drv
REQUIRES = omap4
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..

View File

@ -1,6 +1,6 @@
TARGET = uart_drv
REQUIRES = pl011
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..

View File

@ -229,8 +229,8 @@ int main(int, char **)
}
catch (Xml_node::Nonexistent_sub_node) {
PERR("No children to start"); }
catch (Config::Invalid) {
PERR("No valid config found"); }
catch (Xml_node::Invalid_syntax) {
PERR("No children to start"); }
catch (Init::Child::Child_name_is_not_unique) { }
/*

View File

@ -1,3 +1,3 @@
TARGET = init
SRC_CC = main.cc
LIBS = base init_pd_args
LIBS = base init_pd_args config

View File

@ -0,0 +1,97 @@
/*
* \brief Access to process configuration
* \author Norman Feske
* \date 2010-05-04
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <os/config.h>
using namespace Genode;
Xml_node _config_xml_node(Dataspace_capability config_ds)
{
return Xml_node(env()->rm_session()->attach(config_ds),
Genode::Dataspace_client(config_ds).size());
}
/**
* Fallback XML node used if the configuration is broken
*/
static Xml_node fallback_config_xml()
{
return Xml_node("<config/>");
}
void Config::reload()
{
if (!this)
return;
try {
/* re-acquire dataspace from ROM session */
if (_config_ds.valid())
env()->rm_session()->detach(_config_xml.addr());
_config_ds = _config_rom.dataspace();
/* re-initialize XML node with new config data */
_config_xml = _config_xml_node(_config_ds);
} catch (Genode::Xml_node::Invalid_syntax) {
PERR("Config file has invalid syntax");
_config_xml = fallback_config_xml();
}
}
Xml_node Config::xml_node()
{
if (!this)
return fallback_config_xml();
return _config_xml;
}
void Config::sigh(Signal_context_capability cap)
{
if (this)
_config_rom.sigh(cap);
}
Config::Config()
:
_config_rom("config"),
_config_ds(_config_rom.dataspace()),
_config_xml(_config_xml_node(_config_ds))
{ }
Config *Genode::config()
{
static bool config_failed = false;
if (!config_failed) {
try {
static Config config_inst;
return &config_inst;
} catch (Genode::Rom_connection::Rom_connection_failed) {
PERR("Could not obtain config file");
} catch (Genode::Xml_node::Invalid_syntax) {
PERR("Config file has invalid syntax");
}
}
/* do not try again to construct 'config_inst' */
config_failed = true;
return 0;
}

View File

@ -37,7 +37,6 @@ void init_config_args(void)
arg_node = arg_node.next("arg");
}
}
catch (Config::Invalid) { return; }
catch (Xml_node::Nonexistent_sub_node) { }
catch (Xml_node::Nonexistent_attribute)
{

View File

@ -1,5 +1,5 @@
TARGET = nic_bridge
LIBS = base net
LIBS = base net config
SRC_CC = component.cc env.cc mac.cc main.cc nic.cc packet_handler.cc
vpath *.cc $(REP_DIR)/src/server/proxy_arp

View File

@ -1,3 +1,3 @@
TARGET = nit_fb
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,5 +1,5 @@
TARGET = nitpicker
LIBS = base blit
LIBS = base blit config
SRC_CC = main.cc \
view_stack.cc \
view.cc \

View File

@ -1,3 +1,3 @@
TARGET = part_blk
LIBS = base
LIBS = base config
SRC_CC = main.cc back_end.cc

View File

@ -635,7 +635,6 @@ int main(int, char **)
Xml_node content = config()->xml_node().sub_node("content");
preload_content(*env()->heap(), content, root_dir); }
catch (Xml_node::Nonexistent_sub_node) { }
catch (Config::Invalid) { }
static File_system::Root root(ep, sliced_heap, sig_rec, root_dir);

View File

@ -1,4 +1,4 @@
TARGET = ram_fs
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR)

View File

@ -1,3 +1,3 @@
TARGET = rom_loopdev
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,3 +1,3 @@
TARGET = rom_prefetcher
SRC_CC = main.cc
LIBS += base
LIBS += base config

View File

@ -1,4 +1,4 @@
TARGET = tar_fs
SRC_CC = main.cc
LIBS = base
LIBS = base config
INC_DIR += $(PRG_DIR)

View File

@ -1,3 +1,3 @@
TARGET = tar_rom
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,3 +1,3 @@
TARGET = test-audio_out
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,3 +1,3 @@
TARGET = bomb
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,4 +1,4 @@
TARGET = test-chroot_loader
REQUIRES += linux
SRC_CC = main.cc
LIBS += base
LIBS += base config

View File

@ -42,12 +42,8 @@ int main(int, char **)
/* wait for config change */
sig_rec.wait_for_signal();
try {
Genode::config()->reload();
parse_config();
} catch (Genode::Config::Invalid) {
PERR("Error: reloading config failed");
}
Genode::config()->reload();
parse_config();
}
return 0;
}

View File

@ -1,3 +1,3 @@
TARGET = test-dynamic_config
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,3 +1,3 @@
TARGET = test-part
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,3 +1,3 @@
TARGET = test-rom_blk
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -1,3 +1,3 @@
TARGET = test-trace
SRC_CC = main.cc
LIBS += base
LIBS += base config

View File

@ -32,6 +32,6 @@ SRC_CC += env.cc \
INC_DIR += $(REP_DIR)/include \
$(REP_DIR)/src/lib/l4lx/include \
LIBS = base
LIBS = base config
vpath %.cc $(REP_DIR)/src/lib/l4lx

View File

@ -3,7 +3,7 @@ VERBOSE_LX_MK ?= 0
REQUIRES += foc
INC_DIR += $(REP_DIR)/include
LIBS = l4lx l4sys
GENODE_LIBS := base base-common startup syscall cxx l4lx l4sys
GENODE_LIBS := base base-common startup syscall cxx l4lx l4sys config
GENODE_LIBS := $(foreach l,$(GENODE_LIBS),$(BUILD_BASE_DIR)/var/libcache/$l/$l.lib.a)
GENODE_LIBS_SORTED = $(sort $(wildcard $(GENODE_LIBS)))

View File

@ -21,7 +21,7 @@ SRC_CC += iguana_eas.cc \
iguana_tls.cc
INC_DIR += $(REP_DIR)/include/oklx_lib
INC_DIR += $(REP_DIR)/src/lib/oklx/include
LIBS = base
LIBS = base config
# do not produce position-independent code
CC_OPT_PIC =

View File

@ -192,7 +192,7 @@ diff -urNpB kernel-2.6.23-v2/arch/l4/Makefile contrib/arch/l4/Makefile
-libs-y += -lvtimer -lvserial -ll4e -lll -liguana -ll4 -lgcc -lmutex -lcircular_buffer -lc -latomic_ops -lfs
+#libs-y += -lvtimer -lvserial -ll4e -lll -liguana -ll4 -lgcc -lmutex -lcircular_buffer -lc -latomic_ops -lfs
+
+GENODE_LIBS = base base-common cxx startup \
+GENODE_LIBS = base base-common cxx startup config \
+ oklx
+
+libs-y += $(addprefix $(GENODE_LIBS_DIR)/,$(foreach l,$(GENODE_LIBS),$l/$l.lib.a))

View File

@ -1,5 +1,5 @@
TARGET = noux
LIBS = base alarm
LIBS = base alarm config
SRC_CC = main.cc dummy_net.cc
INC_DIR += $(PRG_DIR)
INC_DIR += $(PRG_DIR)/../

View File

@ -1,5 +1,5 @@
TARGET = noux_net
LIBS += alarm libc libc_lwip
LIBS += alarm libc libc_lwip config
SRC_CC = main.cc net.cc

View File

@ -20,9 +20,6 @@ int main(void)
{
try {
config()->xml_node().sub_node("test_config_subnode");
} catch(Config::Invalid) {
PERR("Error: Missing '<config>' node.");
return -1;
} catch (Xml_node::Nonexistent_sub_node) {
PERR("Error: Missing '<test_config_subnode>' sub node.");
return -1;

View File

@ -1,3 +1,3 @@
TARGET = test-gdb_monitor_target_config
SRC_CC = main.cc
LIBS = base
LIBS = base config

View File

@ -11,7 +11,7 @@ ifeq ($(wildcard $(VANCOUVER_DIR)),)
REQUIRES += prepare_ports_vancouver
endif
LIBS += base blit alarm seoul_libc_support
LIBS += base blit alarm seoul_libc_support config
SRC_CC = main.cc nova_user_env.cc device_model_registry.cc
SRC_CC += console.cc keyboard.cc network.cc disk.cc
SRC_BIN = mono.tff

View File

@ -86,9 +86,7 @@ Main_window::Main_window()
qDebug() << "filter:" << framebuffer_filter->name << "," << framebuffer_filter->ram_quota;
framebuffer_filters.prepend(framebuffer_filter);
}
} catch (Config::Invalid) {
} catch (Xml_node::Nonexistent_sub_node) {
}
} catch (Xml_node::Nonexistent_sub_node) { }
/* start the filtering framebuffer services */