Skip to content

Commit a13e1ae

Browse files
committed
Merge branch 'feature-EventSelect' into develop
2 parents f73d4cc + d543b65 commit a13e1ae

File tree

7 files changed

+507
-2
lines changed

7 files changed

+507
-2
lines changed

modules/event/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
PROJECT = event
2222
LIB_NAME = event
2323
LIB_VERSION_X = 1
24-
LIB_VERSION_Y = 1
25-
LIB_VERSION_Z = 2
24+
LIB_VERSION_Y = 2
25+
LIB_VERSION_Z = 0
2626

2727
HEAD_FILES = \
2828
forward.h \
@@ -45,6 +45,8 @@ CPP_SRC_FILES = \
4545
stat.cpp \
4646
engines/epoll/loop.cpp \
4747
engines/epoll/fd_event.cpp \
48+
engines/select/loop.cpp \
49+
engines/select/fd_event.cpp \
4850

4951
TEST_CPP_SRC_FILES = \
5052
$(CPP_SRC_FILES) \
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
* .============.
3+
* // M A K E / \
4+
* // C++ DEV / \
5+
* // E A S Y / \/ \
6+
* ++ ----------. \/\ .
7+
* \\ \ \ /\ /
8+
* \\ \ \ /
9+
* \\ \ \ /
10+
* -============'
11+
*
12+
* Copyright (c) 2024 Hevake and contributors, all rights reserved.
13+
*
14+
* This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox)
15+
* Use of this source code is governed by MIT license that can be found
16+
* in the LICENSE file in the root of the source tree. All contributing
17+
* project authors may be found in the CONTRIBUTORS.md file in the root
18+
* of the source tree.
19+
*/
20+
#include <algorithm>
21+
22+
#include "fd_event.h"
23+
#include "loop.h"
24+
#include <tbox/base/assert.h>
25+
#include <tbox/base/defines.h>
26+
#include <tbox/base/wrapped_recorder.h>
27+
28+
namespace tbox {
29+
namespace event {
30+
31+
SelectFdEvent::SelectFdEvent(SelectLoop *wp_loop, const std::string &what)
32+
: FdEvent(what)
33+
, wp_loop_(wp_loop)
34+
{ }
35+
36+
SelectFdEvent::~SelectFdEvent()
37+
{
38+
TBOX_ASSERT(cb_level_ == 0);
39+
40+
disable();
41+
42+
wp_loop_->unrefFdSharedData(fd_);
43+
}
44+
45+
bool SelectFdEvent::initialize(int fd, short events, Mode mode)
46+
{
47+
if (isEnabled())
48+
return false;
49+
50+
if (fd != fd_) {
51+
wp_loop_->unrefFdSharedData(fd_);
52+
fd_ = fd;
53+
d_ = wp_loop_->refFdSharedData(fd_);
54+
}
55+
56+
events_ = events;
57+
if (mode == FdEvent::Mode::kOneshot)
58+
is_stop_after_trigger_ = true;
59+
60+
return true;
61+
}
62+
63+
bool SelectFdEvent::enable()
64+
{
65+
if (d_ == nullptr)
66+
return false;
67+
68+
if (is_enabled_)
69+
return true;
70+
71+
if (events_ & kReadEvent)
72+
++d_->read_event_num;
73+
74+
if (events_ & kWriteEvent)
75+
++d_->write_event_num;
76+
77+
if (events_ & kExceptEvent)
78+
++d_->except_event_num;
79+
80+
if (events_ & kHupEvent)
81+
++d_->hup_event_num;
82+
83+
d_->fd_events.push_back(this);
84+
85+
is_enabled_ = true;
86+
return true;
87+
}
88+
89+
bool SelectFdEvent::disable()
90+
{
91+
if (d_ == nullptr || !is_enabled_)
92+
return true;
93+
94+
if (events_ & kReadEvent)
95+
--d_->read_event_num;
96+
97+
if (events_ & kWriteEvent)
98+
--d_->write_event_num;
99+
100+
if (events_ & kExceptEvent)
101+
--d_->except_event_num;
102+
103+
if (events_ & kHupEvent)
104+
--d_->hup_event_num;
105+
106+
auto iter = std::find(d_->fd_events.begin(), d_->fd_events.end(), this);
107+
d_->fd_events.erase(iter);
108+
109+
is_enabled_ = false;
110+
return true;
111+
}
112+
113+
Loop* SelectFdEvent::getLoop() const
114+
{
115+
return wp_loop_;
116+
}
117+
118+
void SelectFdEvent::OnEventCallback(bool is_readable, bool is_writable, bool is_except, SelectFdSharedData *data)
119+
{
120+
RECORD_SCOPE();
121+
short tbox_events = 0;
122+
123+
if (is_readable)
124+
tbox_events |= kReadEvent;
125+
126+
if (is_writable)
127+
tbox_events |= kWriteEvent;
128+
129+
if (is_except)
130+
tbox_events |= kExceptEvent;
131+
132+
//! 要先复制一份,因为在for中很可能会改动到d->fd_events,引起迭代器失效问题
133+
auto tmp = data->fd_events;
134+
for (auto event : tmp)
135+
event->onEvent(tbox_events);
136+
}
137+
138+
void SelectFdEvent::onEvent(short events)
139+
{
140+
/**
141+
* 由于EPOLLHUP会一直触发,所以无论事件有没有监听HupEvent,只要发生了EPOLLHUB事件,
142+
* 对应fd所有的事件都要强制disable()。否则会导致Loop空跑问题。
143+
*/
144+
if (events & kHupEvent)
145+
disable();
146+
147+
if (events_ & events) {
148+
if (is_stop_after_trigger_)
149+
disable();
150+
151+
wp_loop_->beginEventProcess();
152+
if (cb_) {
153+
RECORD_SCOPE();
154+
++cb_level_;
155+
cb_(events);
156+
--cb_level_;
157+
}
158+
wp_loop_->endEventProcess(this);
159+
}
160+
}
161+
162+
}
163+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* .============.
3+
* // M A K E / \
4+
* // C++ DEV / \
5+
* // E A S Y / \/ \
6+
* ++ ----------. \/\ .
7+
* \\ \ \ /\ /
8+
* \\ \ \ /
9+
* \\ \ \ /
10+
* -============'
11+
*
12+
* Copyright (c) 2024 Hevake and contributors, all rights reserved.
13+
*
14+
* This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox)
15+
* Use of this source code is governed by MIT license that can be found
16+
* in the LICENSE file in the root of the source tree. All contributing
17+
* project authors may be found in the CONTRIBUTORS.md file in the root
18+
* of the source tree.
19+
*/
20+
#ifndef TBOX_EVENT_SELECT_FD_EVENT_H_20240619
21+
#define TBOX_EVENT_SELECT_FD_EVENT_H_20240619
22+
23+
#include "../../fd_event.h"
24+
#include "types.h"
25+
26+
namespace tbox {
27+
namespace event {
28+
29+
class SelectLoop;
30+
31+
class SelectFdEvent : public FdEvent {
32+
public:
33+
explicit SelectFdEvent(SelectLoop *wp_loop, const std::string &what);
34+
virtual ~SelectFdEvent() override;
35+
36+
public:
37+
virtual bool initialize(int fd, short events, Mode mode) override;
38+
virtual void setCallback(CallbackFunc &&cb) override { cb_ = std::move(cb); }
39+
40+
virtual bool isEnabled() const override{ return is_enabled_; }
41+
virtual bool enable() override;
42+
virtual bool disable() override;
43+
44+
virtual Loop* getLoop() const override;
45+
46+
public:
47+
static void OnEventCallback(bool is_readable, bool is_writable, bool is_except, SelectFdSharedData *data);
48+
49+
protected:
50+
void onEvent(short events);
51+
52+
private:
53+
SelectLoop *wp_loop_;
54+
bool is_stop_after_trigger_ = false;
55+
56+
int fd_ = -1;
57+
uint32_t events_ = 0;
58+
bool is_enabled_ = false;
59+
60+
CallbackFunc cb_;
61+
SelectFdSharedData *d_ = nullptr;
62+
63+
int cb_level_ = 0;
64+
};
65+
66+
}
67+
}
68+
69+
#endif //TBOX_EVENT_SELECT_FD_EVENT_H_20240619

0 commit comments

Comments
 (0)