bryancall commented on code in PR #13830:
URL: https://github.com/apache/trafficserver/pull/13830#discussion_r4332852721
##########
include/iocore/eventsystem/Continuation.h:
##########
@@ -82,70 +79,135 @@ extern EThread *this_event_thread();
*/
#define CONTINUATION_CONT 1
+class force_VFPT_to_top
+{
+public:
+ virtual ~force_VFPT_to_top() {}
+};
+
/**
- Pointer-to-member type of an event handler, as stored in
- @c Continuation::handler.
+ A copyable binding to an event-handler member function of
+ @c Continuation or a class derived from it.
- The handler receives the event code and payload of each event
- dispatched to the Continuation, and returns a Processor-specific
- status.
+ Bind a handler of type @c int(D::*)(int, T*), then invoke it on a
+ @c Continuation pointer with a @c void* payload, which is converted to
+ @c T* before the call. One ContinuationHandler can thus hold, over
+ time, handlers whose classes and payload types differ. Copy one to save
+ a Continuation's current handler and assign it back to restore it.
- @note A handler declared in a class derived from @c Continuation MUST be
- converted to this type with @c static_cast, which applies the
- base-class offset.
+ A default-constructed ContinuationHandler is null: it holds no handler.
- @note Invoking a converted handler is undefined behavior unless the
- Continuation's dynamic type is, or derives from, the class that
- declared the handler.
+ @par Thread Safety
+ Concurrent invocations and other reads are safe. Binding a handler to
+ a ContinuationHandler or assigning to it MUST NOT run concurrently
+ with any other access to it.
*/
-using ContinuationHandler = int (Continuation::*)(int, void *);
-
-template <class C, typename T>
-constexpr ContinuationHandler
-continuation_handler_void_ptr(int (C::*fp)(int, T *))
+class ContinuationHandler
{
- auto fp2 = reinterpret_cast<int (C::*)(int, void *)>(fp);
-
- // We keep this a static_cast for added static type analysis from the
- // compiler. If a compiler warning is generated for the following line of
- // code of the type "-Werror=shift-negative-value", then this may be an issue
- // with multiple inheritance of the C templated type. Make sure that for type
- // C the Continuation parent is listed first (either directly or indirectly
- // via the inheritance tree) before any other parent in the multiple class
- // hierarchy of C.
- return static_cast<ContinuationHandler>(fp2);
-}
+public:
+ /**
+ Binds @p M as the handler, or clears the handler if @p M is
+ @c nullptr.
-/**
- Overload for a literal @c nullptr, from which the converting overload
- cannot deduce a handler type.
+ @tparam M @c nullptr, or a non-null pointer to a member function of
+ type @c int(D::*)(int, T*), where @c D is @c Continuation
+ or a class derived from it.
- @return A null @c ContinuationHandler.
+ @post If @p M is not @c nullptr, invoking this ContinuationHandler
+ calls @p M.
- @par Thread Safety
- Thread-safe.
-*/
-constexpr ContinuationHandler
-continuation_handler_void_ptr(std::nullptr_t)
-{
-#undef X
-#if !defined(__GNUC__)
-#define X 1
-#else
-#define X (__GNUC__ > 7)
-#endif
-#if X
- static_assert(!static_cast<ContinuationHandler>(nullptr));
-#endif
-#undef X
+ @par Thread Safety
+ Not thread-safe.
+ */
+ template <auto M>
+ void
+ set()
+ {
+ if constexpr (std::is_null_pointer_v<decltype(M)>) {
+ this->handler = nullptr;
+ } else {
+ this->handler = &invoke_handler<M>;
+ }
+ }
- return static_cast<ContinuationHandler>(nullptr);
-}
+ /**
+ Tests whether this ContinuationHandler holds the handler @p M.
-class force_VFPT_to_top
-{
-public:
- virtual ~force_VFPT_to_top() {}
+ @tparam M @c nullptr, or a pointer to a member function of type
+ @c int(D::*)(int, T*), where @c D is @c Continuation or
+ derives from it.
+
+ @return If @p M is @c nullptr, whether this ContinuationHandler is
+ null; otherwise, whether it holds @p M.
+
+ @note @c &B::f and @c &D::f are distinct handlers even when
+ @c D::f overrides @c B::f.
+
+ @par Thread Safety
+ Safe to call concurrently with other reads of this
+ ContinuationHandler, but not with @c set or an assignment to it.
+ */
+ template <auto M>
+ bool
+ is() const
+ {
+ if constexpr (std::is_null_pointer_v<decltype(M)>) {
+ return nullptr == this->handler;
+ } else {
+ return &invoke_handler<M> == this->handler;
+ }
+ }
+
+ /**
+ Invokes the bound handler on @p c with @p event and @p data.
+
+ @param[in] b The object to invoke the handler on.
Review Comment:
Nit: the parameter is `c`, so this should be `@param[in] c`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]