Kernel: Extract dynamic Object pointer cast into its own function

This commit is contained in:
Yuri Kunde Schlesner 2017-05-29 14:42:27 -07:00
parent 3df85a103a
commit b17754f998

View file

@ -121,6 +121,18 @@ inline void intrusive_ptr_release(Object* object) {
template <typename T> template <typename T>
using SharedPtr = boost::intrusive_ptr<T>; using SharedPtr = boost::intrusive_ptr<T>;
/**
* Attempts to downcast the given Object pointer to a pointer to T.
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
*/
template <typename T>
inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
return boost::static_pointer_cast<T>(std::move(object));
}
return nullptr;
}
/// Class that represents a Kernel object that a thread can be waiting on /// Class that represents a Kernel object that a thread can be waiting on
class WaitObject : public Object { class WaitObject : public Object {
public: public:
@ -163,6 +175,15 @@ private:
std::vector<SharedPtr<Thread>> waiting_threads; std::vector<SharedPtr<Thread>> waiting_threads;
}; };
// Specialization of DynamicObjectCast for WaitObjects
template <>
inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) {
if (object != nullptr && object->IsWaitable()) {
return boost::static_pointer_cast<WaitObject>(std::move(object));
}
return nullptr;
}
/** /**
* This class allows the creation of Handles, which are references to objects that can be tested * This class allows the creation of Handles, which are references to objects that can be tested
* for validity and looked up. Here they are used to pass references to kernel objects to/from the * for validity and looked up. Here they are used to pass references to kernel objects to/from the
@ -224,15 +245,11 @@ public:
/** /**
* Looks up a handle while verifying its type. * Looks up a handle while verifying its type.
* @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
* type differs from the handle type `T::HANDLE_TYPE`. * type differs from the requested one.
*/ */
template <class T> template <class T>
SharedPtr<T> Get(Handle handle) const { SharedPtr<T> Get(Handle handle) const {
SharedPtr<Object> object = GetGeneric(handle); return DynamicObjectCast<T>(GetGeneric(handle));
if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
return boost::static_pointer_cast<T>(std::move(object));
}
return nullptr;
} }
/** /**
@ -241,11 +258,7 @@ public:
* not a waitable object. * not a waitable object.
*/ */
SharedPtr<WaitObject> GetWaitObject(Handle handle) const { SharedPtr<WaitObject> GetWaitObject(Handle handle) const {
SharedPtr<Object> object = GetGeneric(handle); return DynamicObjectCast<WaitObject>(GetGeneric(handle));
if (object != nullptr && object->IsWaitable()) {
return boost::static_pointer_cast<WaitObject>(std::move(object));
}
return nullptr;
} }
/// Closes all handles held in this table. /// Closes all handles held in this table.