Check Registered base class provides virtual destructor

The base class of Registered must provide a virtual destructor to enable
safe deletion with just a base class pointer. This requirement can be
lifted by using Registered_no_delete in places where the deletion
property is not needed.

Fixes #2331
This commit is contained in:
Christian Helmuth 2017-03-14 11:51:15 +01:00
parent 139525b6c9
commit b35df4578b
6 changed files with 32 additions and 6 deletions

View File

@ -22,6 +22,7 @@ namespace Genode {
class Registry_base;
template <typename T> struct Registry;
template <typename T> class Registered;
template <typename T> class Registered_no_delete;
}
@ -157,9 +158,33 @@ class Genode::Registered : public T
public:
static_assert(__has_virtual_destructor(T), "registered object must have virtual destructor");
template <typename... ARGS>
Registered(Registry<Registered<T> > &registry, ARGS &&... args)
: T(args...), _element(registry, *this) { }
};
/**
* Variant of Registered that does not require a vtable in the base class
*
* The generic Registered convenience class requires the base class to provide
* a vtable resp. a virtual destructor for safe deletion of a base class
* pointer. By using Registered_no_delete this requirement can be lifted.
*/
template <typename T>
class Genode::Registered_no_delete : public T
{
private:
typename Registry<Registered_no_delete<T> >::Element _element;
public:
template <typename... ARGS>
Registered_no_delete(Registry<Registered_no_delete<T> > &registry, ARGS &&... args)
: T(args...), _element(registry, *this) { }
};
#endif /* _INCLUDE__BASE__REGISTRY_H_ */

View File

@ -17,7 +17,7 @@
#include <cpu/atomic.h>
static Genode::Registry<Genode::Registered<Genode::Semaphore> > blocked;
static Genode::Registry<Genode::Registered_no_delete<Genode::Semaphore> > blocked;
namespace __cxxabiv1
@ -54,7 +54,7 @@ namespace __cxxabiv1
if (!Genode::cmpxchg(in_init, INIT_NONE, IN_INIT)) {
/* register current thread for blocking */
Genode::Registered<Genode::Semaphore> block(blocked);
Genode::Registered_no_delete<Genode::Semaphore> block(blocked);
/* tell guard thread that current thread needs a wakeup */
while (!Genode::cmpxchg(in_init, *in_init, *in_init | WAITERS)) ;
@ -88,7 +88,7 @@ namespace __cxxabiv1
return;
/* we had contention - wake all up */
blocked.for_each([](Genode::Registered<Genode::Semaphore> &wake) {
blocked.for_each([](Genode::Registered_no_delete<Genode::Semaphore> &wake) {
wake.up();
});
}

View File

@ -16,7 +16,6 @@
/* Genode includes */
#include <base/printf.h>
#include <base/registry.h>
#include <terminal_session/connection.h>
#include <util/string.h>
#include <util/list.h>
@ -26,7 +25,6 @@
namespace Cli_monitor {
using Genode::Registry;
using Genode::List;
using Genode::max;
using Genode::strlen;

View File

@ -13,7 +13,6 @@
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <base/registry.h>
#include <vfs/file_system_factory.h>
#include <vfs/dir_file_system.h>
#include <base/component.h>

View File

@ -63,6 +63,8 @@ class Input_filter::Input_connection
_connection.sigh(_input_handler);
}
virtual ~Input_connection() { }
Session_label label() const { return _label; }
template <typename FUNC>

View File

@ -79,6 +79,8 @@ struct Stress_test
: timer_handler(env.ep(), *this, &Slave::handle_timer),
timer(env), us(ms * 1000) { timer.sigh(timer_handler); }
virtual ~Slave() { }
void handle_timer()
{
count++;