chenBright commented on code in PR #2560:
URL: https://github.com/apache/brpc/pull/2560#discussion_r1546266286


##########
src/brpc/event_dispatcher.h:
##########
@@ -21,11 +21,74 @@
 
 #include "butil/macros.h"                     // DISALLOW_COPY_AND_ASSIGN
 #include "bthread/types.h"                   // bthread_t, bthread_attr_t
-#include "brpc/socket.h"                     // Socket, SocketId
+#include "brpc/versioned_ref_with_id.h"
 
 
 namespace brpc {
 
+// Unique identifier of a EventData.
+// Users shall store EventDataId instead of EventData and call 
EventData::Address()
+// to convert the identifier to an unique_ptr at each access. Whenever a
+// unique_ptr is not destructed, the enclosed EventData will not be recycled.
+typedef VRefId EventDataId;
+
+const VRefId INVALID_EVENT_DATA_ID = INVALID_VREF_ID;
+
+class EventData;
+
+typedef VersionedRefWithIdUniquePtr<EventData> EventDataUniquePtr;
+
+// User callback type of input event and output event.
+typedef int (*InputEventCallback) (VRefId id, uint32_t events,
+                                   const bthread_attr_t& thread_attr);
+typedef InputEventCallback OutputEventCallback;
+
+struct EventDataOptions {
+    // Find user object to handle event by `user_id'.
+    uint64_t user_id;
+    // Callback for input event.
+    InputEventCallback input_cb;
+    // Callback for output event.
+    OutputEventCallback output_cb;
+};
+
+// EventDispatcher finds EventData by EventDataId which is
+// stored in epoll/kqueue data, and calls its callback, so
+// EventDispatcher supports various IO types, such as socket,
+// pipe, eventfd, timerfd, etc.
+class EventData : public VersionedRefWithId<EventData> {
+public:
+    explicit EventData(Forbidden f)
+        : VersionedRefWithId<EventData>(f)
+        , _options{INVALID_EVENT_DATA_ID, NULL, NULL} {}
+
+    DISALLOW_COPY_AND_ASSIGN(EventData);
+
+    int CallInputEventCallback(uint32_t events,

Review Comment:
   有两种实现:
   1. `class Socket : public VersionedRefWithId<Socket>, public EventData`。
   
因为要支持多个IO类型,那么处理事件时,没有类型信息,不知道id是哪种IO类型的id,没法Address出正确的IO类型对象。除非EventDispatcher在事件注册时,记录了注册对象的类型信息。当前实现中,EventData算是一种间接记录类型信息(函数指针)的方式,屏蔽了不同IO类型Address的差异吧。
   
   2. `class EventData : public VersionedRefWithId<EventData>`、`class Socket : 
public EventData`。
   
不同IO类型统一使用EventDataId作为id,在EventDispatcher有统一的Address方式。不同IO类型实现各自的CallInputEventCallback和CallOutputEventCallback两个虚函数即可。
   
这种实现有另外的问题,例如SocketUniquePtr,无法作为Address等需要UniquePtr参数的接口,因为这些接口推导出的参数类型是EventDataUniquePtr。要解决这个问题,Socket需要实现自己的Address函数,并在内部Address到EventDataUniquePtr后再转成SocketUniquePtr。
   
   以上两种继承EventData的方式,有各自的问题,算不上是好的解决方案。
   
   综上,我认为目前EventData的使用方式,兼容性好一点,改动量也不大。
   
   @wwbmmm EventData这一块,有什么好的建议?



-- 
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: dev-unsubscr...@brpc.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org
For additional commands, e-mail: dev-h...@brpc.apache.org

Reply via email to