mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 07:08:18 +00:00
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:
@ -22,6 +22,7 @@ namespace Genode {
|
|||||||
class Registry_base;
|
class Registry_base;
|
||||||
template <typename T> struct Registry;
|
template <typename T> struct Registry;
|
||||||
template <typename T> class Registered;
|
template <typename T> class Registered;
|
||||||
|
template <typename T> class Registered_no_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,9 +158,33 @@ class Genode::Registered : public T
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static_assert(__has_virtual_destructor(T), "registered object must have virtual destructor");
|
||||||
|
|
||||||
template <typename... ARGS>
|
template <typename... ARGS>
|
||||||
Registered(Registry<Registered<T> > ®istry, ARGS &&... args)
|
Registered(Registry<Registered<T> > ®istry, ARGS &&... args)
|
||||||
: T(args...), _element(registry, *this) { }
|
: 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> > ®istry, ARGS &&... args)
|
||||||
|
: T(args...), _element(registry, *this) { }
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__BASE__REGISTRY_H_ */
|
#endif /* _INCLUDE__BASE__REGISTRY_H_ */
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include <cpu/atomic.h>
|
#include <cpu/atomic.h>
|
||||||
|
|
||||||
|
|
||||||
static Genode::Registry<Genode::Registered<Genode::Semaphore> > blocked;
|
static Genode::Registry<Genode::Registered_no_delete<Genode::Semaphore> > blocked;
|
||||||
|
|
||||||
|
|
||||||
namespace __cxxabiv1
|
namespace __cxxabiv1
|
||||||
@ -54,7 +54,7 @@ namespace __cxxabiv1
|
|||||||
if (!Genode::cmpxchg(in_init, INIT_NONE, IN_INIT)) {
|
if (!Genode::cmpxchg(in_init, INIT_NONE, IN_INIT)) {
|
||||||
|
|
||||||
/* register current thread for blocking */
|
/* 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 */
|
/* tell guard thread that current thread needs a wakeup */
|
||||||
while (!Genode::cmpxchg(in_init, *in_init, *in_init | WAITERS)) ;
|
while (!Genode::cmpxchg(in_init, *in_init, *in_init | WAITERS)) ;
|
||||||
@ -88,7 +88,7 @@ namespace __cxxabiv1
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* we had contention - wake all up */
|
/* 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();
|
wake.up();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/registry.h>
|
|
||||||
#include <terminal_session/connection.h>
|
#include <terminal_session/connection.h>
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
@ -26,7 +25,6 @@
|
|||||||
|
|
||||||
namespace Cli_monitor {
|
namespace Cli_monitor {
|
||||||
|
|
||||||
using Genode::Registry;
|
|
||||||
using Genode::List;
|
using Genode::List;
|
||||||
using Genode::max;
|
using Genode::max;
|
||||||
using Genode::strlen;
|
using Genode::strlen;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <base/registry.h>
|
|
||||||
#include <vfs/file_system_factory.h>
|
#include <vfs/file_system_factory.h>
|
||||||
#include <vfs/dir_file_system.h>
|
#include <vfs/dir_file_system.h>
|
||||||
#include <base/component.h>
|
#include <base/component.h>
|
||||||
|
@ -63,6 +63,8 @@ class Input_filter::Input_connection
|
|||||||
_connection.sigh(_input_handler);
|
_connection.sigh(_input_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~Input_connection() { }
|
||||||
|
|
||||||
Session_label label() const { return _label; }
|
Session_label label() const { return _label; }
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
|
@ -79,6 +79,8 @@ struct Stress_test
|
|||||||
: timer_handler(env.ep(), *this, &Slave::handle_timer),
|
: timer_handler(env.ep(), *this, &Slave::handle_timer),
|
||||||
timer(env), us(ms * 1000) { timer.sigh(timer_handler); }
|
timer(env), us(ms * 1000) { timer.sigh(timer_handler); }
|
||||||
|
|
||||||
|
virtual ~Slave() { }
|
||||||
|
|
||||||
void handle_timer()
|
void handle_timer()
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
|
Reference in New Issue
Block a user