event/Loop: add "noexcept"

This commit is contained in:
Max Kellermann 2018-01-29 21:46:07 +01:00
parent 2c65f986d6
commit 3890bc5a96
8 changed files with 132 additions and 80 deletions

View File

@ -30,14 +30,14 @@ EventLoop::EventLoop(ThreadId _thread)
SocketMonitor::Open(SocketDescriptor(wake_fd.Get())); SocketMonitor::Open(SocketDescriptor(wake_fd.Get()));
} }
EventLoop::~EventLoop() EventLoop::~EventLoop() noexcept
{ {
assert(idle.empty()); assert(idle.empty());
assert(timers.empty()); assert(timers.empty());
} }
void void
EventLoop::Break() EventLoop::Break() noexcept
{ {
if (quit.exchange(true)) if (quit.exchange(true))
return; return;
@ -46,7 +46,7 @@ EventLoop::Break()
} }
bool bool
EventLoop::Abandon(int _fd, SocketMonitor &m) EventLoop::Abandon(int _fd, SocketMonitor &m) noexcept
{ {
assert(IsInside()); assert(IsInside());
@ -55,7 +55,7 @@ EventLoop::Abandon(int _fd, SocketMonitor &m)
} }
bool bool
EventLoop::RemoveFD(int _fd, SocketMonitor &m) EventLoop::RemoveFD(int _fd, SocketMonitor &m) noexcept
{ {
assert(IsInside()); assert(IsInside());
@ -64,7 +64,7 @@ EventLoop::RemoveFD(int _fd, SocketMonitor &m)
} }
void void
EventLoop::AddIdle(IdleMonitor &i) EventLoop::AddIdle(IdleMonitor &i) noexcept
{ {
assert(IsInside()); assert(IsInside());
@ -73,7 +73,7 @@ EventLoop::AddIdle(IdleMonitor &i)
} }
void void
EventLoop::RemoveIdle(IdleMonitor &i) EventLoop::RemoveIdle(IdleMonitor &i) noexcept
{ {
assert(IsInside()); assert(IsInside());
@ -81,7 +81,7 @@ EventLoop::RemoveIdle(IdleMonitor &i)
} }
void void
EventLoop::AddTimer(TimerEvent &t, std::chrono::steady_clock::duration d) EventLoop::AddTimer(TimerEvent &t, std::chrono::steady_clock::duration d) noexcept
{ {
assert(IsInside()); assert(IsInside());
@ -91,7 +91,7 @@ EventLoop::AddTimer(TimerEvent &t, std::chrono::steady_clock::duration d)
} }
void void
EventLoop::CancelTimer(TimerEvent &t) EventLoop::CancelTimer(TimerEvent &t) noexcept
{ {
assert(IsInside()); assert(IsInside());
@ -112,7 +112,7 @@ ExportTimeoutMS(std::chrono::steady_clock::duration timeout)
} }
void void
EventLoop::Run() EventLoop::Run() noexcept
{ {
if (thread.IsNull()) if (thread.IsNull())
thread = ThreadId::GetCurrent(); thread = ThreadId::GetCurrent();
@ -241,7 +241,7 @@ EventLoop::RemoveDeferred(DeferEvent &d) noexcept
} }
void void
EventLoop::HandleDeferred() EventLoop::HandleDeferred() noexcept
{ {
while (!deferred.empty() && !quit) { while (!deferred.empty() && !quit) {
auto &m = deferred.front(); auto &m = deferred.front();

View File

@ -114,7 +114,7 @@ public:
explicit EventLoop(ThreadId _thread); explicit EventLoop(ThreadId _thread);
EventLoop():EventLoop(ThreadId::GetCurrent()) {} EventLoop():EventLoop(ThreadId::GetCurrent()) {}
~EventLoop(); ~EventLoop() noexcept;
/** /**
* A caching wrapper for std::chrono::steady_clock::now(). * A caching wrapper for std::chrono::steady_clock::now().
@ -130,15 +130,15 @@ public:
* method is thread-safe and non-blocking: after returning, it * method is thread-safe and non-blocking: after returning, it
* is not guaranteed that the EventLoop has really stopped. * is not guaranteed that the EventLoop has really stopped.
*/ */
void Break(); void Break() noexcept;
bool AddFD(int _fd, unsigned flags, SocketMonitor &m) { bool AddFD(int _fd, unsigned flags, SocketMonitor &m) noexcept {
assert(IsInside()); assert(IsInside());
return poll_group.Add(_fd, flags, &m); return poll_group.Add(_fd, flags, &m);
} }
bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m) { bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m) noexcept {
assert(IsInside()); assert(IsInside());
return poll_group.Modify(_fd, flags, &m); return poll_group.Modify(_fd, flags, &m);
@ -149,16 +149,16 @@ public:
* has been closed. This is like RemoveFD(), but does not * has been closed. This is like RemoveFD(), but does not
* attempt to use #EPOLL_CTL_DEL. * attempt to use #EPOLL_CTL_DEL.
*/ */
bool Abandon(int fd, SocketMonitor &m); bool Abandon(int fd, SocketMonitor &m) noexcept;
bool RemoveFD(int fd, SocketMonitor &m); bool RemoveFD(int fd, SocketMonitor &m) noexcept;
void AddIdle(IdleMonitor &i); void AddIdle(IdleMonitor &i) noexcept;
void RemoveIdle(IdleMonitor &i); void RemoveIdle(IdleMonitor &i) noexcept;
void AddTimer(TimerEvent &t, void AddTimer(TimerEvent &t,
std::chrono::steady_clock::duration d); std::chrono::steady_clock::duration d) noexcept;
void CancelTimer(TimerEvent &t); void CancelTimer(TimerEvent &t) noexcept;
/** /**
* Schedule a call to DeferEvent::RunDeferred(). * Schedule a call to DeferEvent::RunDeferred().
@ -179,7 +179,7 @@ public:
* The main function of this class. It will loop until * The main function of this class. It will loop until
* Break() gets called. Can be called only once. * Break() gets called. Can be called only once.
*/ */
void Run(); void Run() noexcept;
private: private:
/** /**
@ -187,7 +187,7 @@ private:
* *
* Caller must lock the mutex. * Caller must lock the mutex.
*/ */
void HandleDeferred(); void HandleDeferred() noexcept;
bool OnSocketReady(unsigned flags) noexcept override; bool OnSocketReady(unsigned flags) noexcept override;

View File

@ -36,12 +36,23 @@ class PollResultEPoll
size_t n_events = 0; size_t n_events = 0;
public: public:
size_t GetSize() const { return n_events; } size_t GetSize() const noexcept {
unsigned GetEvents(size_t i) const { return events[i].events; } return n_events;
void *GetObject(size_t i) const { return events[i].data.ptr; } }
void Reset() { n_events = 0; }
void Clear(void *obj) { unsigned GetEvents(size_t i) const noexcept {
return events[i].events;
}
void *GetObject(size_t i) const noexcept {
return events[i].data.ptr;
}
void Reset() noexcept {
n_events = 0;
}
void Clear(void *obj) noexcept {
for (size_t i = 0; i < n_events; ++i) for (size_t i = 0; i < n_events; ++i)
if (events[i].data.ptr == obj) if (events[i].data.ptr == obj)
events[i].events = 0; events[i].events = 0;
@ -62,25 +73,25 @@ public:
PollGroupEPoll() = default; PollGroupEPoll() = default;
void ReadEvents(PollResultEPoll &result, int timeout_ms) { void ReadEvents(PollResultEPoll &result, int timeout_ms) noexcept {
int ret = epoll.Wait(result.events.data(), result.events.size(), int ret = epoll.Wait(result.events.data(), result.events.size(),
timeout_ms); timeout_ms);
result.n_events = std::max(0, ret); result.n_events = std::max(0, ret);
} }
bool Add(int fd, unsigned events, void *obj) { bool Add(int fd, unsigned events, void *obj) noexcept {
return epoll.Add(fd, events, obj); return epoll.Add(fd, events, obj);
} }
bool Modify(int fd, unsigned events, void *obj) { bool Modify(int fd, unsigned events, void *obj) noexcept {
return epoll.Modify(fd, events, obj); return epoll.Modify(fd, events, obj);
} }
bool Remove(int fd) { bool Remove(int fd) noexcept {
return epoll.Remove(fd); return epoll.Remove(fd);
} }
bool Abandon(gcc_unused int fd) { bool Abandon(gcc_unused int fd) noexcept {
// Nothing to do in this implementation. // Nothing to do in this implementation.
// Closed descriptors are automatically unregistered. // Closed descriptors are automatically unregistered.
return true; return true;

View File

@ -25,10 +25,11 @@
#include <assert.h> #include <assert.h>
PollGroupPoll::PollGroupPoll() { } PollGroupPoll::PollGroupPoll() noexcept = default;
PollGroupPoll::~PollGroupPoll() { } PollGroupPoll::~PollGroupPoll() noexcept = default;
bool PollGroupPoll::Add(int fd, unsigned events, void *obj) bool
PollGroupPoll::Add(int fd, unsigned events, void *obj) noexcept
{ {
assert(items.find(fd) == items.end()); assert(items.find(fd) == items.end());
@ -44,7 +45,8 @@ bool PollGroupPoll::Add(int fd, unsigned events, void *obj)
return true; return true;
} }
bool PollGroupPoll::Modify(int fd, unsigned events, void *obj) bool
PollGroupPoll::Modify(int fd, unsigned events, void *obj) noexcept
{ {
auto item_iter = items.find(fd); auto item_iter = items.find(fd);
assert(item_iter != items.end()); assert(item_iter != items.end());
@ -56,7 +58,8 @@ bool PollGroupPoll::Modify(int fd, unsigned events, void *obj)
return true; return true;
} }
bool PollGroupPoll::Remove(int fd) bool
PollGroupPoll::Remove(int fd) noexcept
{ {
auto item_iter = items.find(fd); auto item_iter = items.find(fd);
assert(item_iter != items.end()); assert(item_iter != items.end());
@ -72,7 +75,8 @@ bool PollGroupPoll::Remove(int fd)
return true; return true;
} }
void PollGroupPoll::ReadEvents(PollResultGeneric &result, int timeout_ms) void
PollGroupPoll::ReadEvents(PollResultGeneric &result, int timeout_ms) noexcept
{ {
int n = poll(poll_events.empty() ? nullptr : &poll_events[0], int n = poll(poll_events.empty() ? nullptr : &poll_events[0],
poll_events.size(), timeout_ms); poll_events.size(), timeout_ms);

View File

@ -48,14 +48,14 @@ public:
static constexpr unsigned ERROR = POLLERR; static constexpr unsigned ERROR = POLLERR;
static constexpr unsigned HANGUP = POLLHUP; static constexpr unsigned HANGUP = POLLHUP;
PollGroupPoll(); PollGroupPoll() noexcept;
~PollGroupPoll(); ~PollGroupPoll() noexcept;
void ReadEvents(PollResultGeneric &result, int timeout_ms); void ReadEvents(PollResultGeneric &result, int timeout_ms) noexcept;
bool Add(int fd, unsigned events, void *obj); bool Add(int fd, unsigned events, void *obj) noexcept;
bool Modify(int fd, unsigned events, void *obj); bool Modify(int fd, unsigned events, void *obj) noexcept;
bool Remove(int fd); bool Remove(int fd) noexcept;
bool Abandon(int fd) { bool Abandon(int fd) noexcept {
return Remove(fd); return Remove(fd);
} }
}; };

View File

@ -26,24 +26,27 @@
constexpr int EVENT_READ = 0; constexpr int EVENT_READ = 0;
constexpr int EVENT_WRITE = 1; constexpr int EVENT_WRITE = 1;
static inline bool HasEvent(unsigned events, int event_id) static constexpr
bool HasEvent(unsigned events, int event_id) noexcept
{ {
return (events & (1 << event_id)) != 0; return (events & (1 << event_id)) != 0;
} }
PollGroupWinSelect::PollGroupWinSelect() { } PollGroupWinSelect::PollGroupWinSelect() noexcept = default;
PollGroupWinSelect::~PollGroupWinSelect() { } PollGroupWinSelect::~PollGroupWinSelect() noexcept = default;
bool PollGroupWinSelect::CanModify(PollGroupWinSelect::Item &item, bool
unsigned events, int event_id) PollGroupWinSelect::CanModify(PollGroupWinSelect::Item &item,
unsigned events, int event_id) const noexcept
{ {
if (item.index[event_id] < 0 && HasEvent(events, event_id)) if (item.index[event_id] < 0 && HasEvent(events, event_id))
return !event_set[event_id].IsFull(); return !event_set[event_id].IsFull();
return true; return true;
} }
void PollGroupWinSelect::Modify(PollGroupWinSelect::Item &item, int fd, void
unsigned events, int event_id) PollGroupWinSelect::Modify(PollGroupWinSelect::Item &item, int fd,
unsigned events, int event_id) noexcept
{ {
int index = item.index[event_id]; int index = item.index[event_id];
auto &set = event_set[event_id]; auto &set = event_set[event_id];
@ -60,7 +63,8 @@ void PollGroupWinSelect::Modify(PollGroupWinSelect::Item &item, int fd,
} }
} }
bool PollGroupWinSelect::Add(int fd, unsigned events, void *obj) bool
PollGroupWinSelect::Add(int fd, unsigned events, void *obj) noexcept
{ {
assert(items.find(fd) == items.end()); assert(items.find(fd) == items.end());
auto &item = items[fd]; auto &item = items[fd];
@ -84,7 +88,8 @@ bool PollGroupWinSelect::Add(int fd, unsigned events, void *obj)
return true; return true;
} }
bool PollGroupWinSelect::Modify(int fd, unsigned events, void *obj) bool
PollGroupWinSelect::Modify(int fd, unsigned events, void *obj) noexcept
{ {
auto item_iter = items.find(fd); auto item_iter = items.find(fd);
assert(item_iter != items.end()); assert(item_iter != items.end());
@ -101,7 +106,8 @@ bool PollGroupWinSelect::Modify(int fd, unsigned events, void *obj)
return true; return true;
} }
bool PollGroupWinSelect::Remove(int fd) bool
PollGroupWinSelect::Remove(int fd) noexcept
{ {
auto item_iter = items.find(fd); auto item_iter = items.find(fd);
assert(item_iter != items.end()); assert(item_iter != items.end());
@ -113,7 +119,9 @@ bool PollGroupWinSelect::Remove(int fd)
return true; return true;
} }
void PollGroupWinSelect::ReadEvents(PollResultGeneric &result, int timeout_ms) void
PollGroupWinSelect::ReadEvents(PollResultGeneric &result,
int timeout_ms) noexcept
{ {
bool use_sleep = event_set[EVENT_READ].IsEmpty() && bool use_sleep = event_set[EVENT_READ].IsEmpty() &&
event_set[EVENT_WRITE].IsEmpty(); event_set[EVENT_WRITE].IsEmpty();

View File

@ -42,7 +42,10 @@ class SocketSet
{ {
fd_set set; fd_set set;
public: public:
SocketSet() { set.fd_count = 0; } SocketSet() noexcept {
set.fd_count = 0;
}
SocketSet(const SocketSet &other) noexcept { SocketSet(const SocketSet &other) noexcept {
set.fd_count = other.set.fd_count; set.fd_count = other.set.fd_count;
memcpy(set.fd_array, memcpy(set.fd_array,
@ -50,28 +53,39 @@ public:
sizeof (SOCKET) * set.fd_count); sizeof (SOCKET) * set.fd_count);
} }
fd_set *GetPtr() { return &set; } fd_set *GetPtr() noexcept {
size_t Size() { return set.fd_count; } return &set;
bool IsEmpty() { return set.fd_count == 0; } }
bool IsFull() { return set.fd_count == FD_SETSIZE; }
size_t Size() const noexcept {
return set.fd_count;
}
bool IsEmpty() const noexcept {
return set.fd_count == 0;
}
bool IsFull() const noexcept {
return set.fd_count == FD_SETSIZE;
}
int operator[](size_t index) const noexcept { int operator[](size_t index) const noexcept {
assert(index < set.fd_count); assert(index < set.fd_count);
return set.fd_array[index]; return set.fd_array[index];
} }
size_t Add(int fd) { size_t Add(int fd) noexcept {
assert(!IsFull()); assert(!IsFull());
set.fd_array[set.fd_count] = fd; set.fd_array[set.fd_count] = fd;
return set.fd_count++; return set.fd_count++;
} }
void MoveToEnd(size_t index) { void MoveToEnd(size_t index) noexcept {
assert(index < set.fd_count); assert(index < set.fd_count);
std::swap(set.fd_array[index], set.fd_array[set.fd_count - 1]); std::swap(set.fd_array[index], set.fd_array[set.fd_count - 1]);
} }
void RemoveLast() { void RemoveLast() noexcept {
assert(!IsEmpty()); assert(!IsEmpty());
--set.fd_count; --set.fd_count;
} }
@ -89,8 +103,10 @@ class PollGroupWinSelect
SocketSet event_set[2]; SocketSet event_set[2];
std::unordered_map<int, Item> items; std::unordered_map<int, Item> items;
bool CanModify(Item &item, unsigned events, int event_id); bool CanModify(Item &item, unsigned events,
void Modify(Item &item, int fd, unsigned events, int event_id); int event_id) const noexcept;
void Modify(Item &item, int fd, unsigned events,
int event_id) noexcept;
PollGroupWinSelect(PollGroupWinSelect &) = delete; PollGroupWinSelect(PollGroupWinSelect &) = delete;
PollGroupWinSelect &operator=(PollGroupWinSelect &) = delete; PollGroupWinSelect &operator=(PollGroupWinSelect &) = delete;
@ -100,14 +116,16 @@ public:
static constexpr unsigned ERROR = 0; static constexpr unsigned ERROR = 0;
static constexpr unsigned HANGUP = 0; static constexpr unsigned HANGUP = 0;
PollGroupWinSelect(); PollGroupWinSelect() noexcept;
~PollGroupWinSelect(); ~PollGroupWinSelect() noexcept;
void ReadEvents(PollResultGeneric &result, int timeout_ms); void ReadEvents(PollResultGeneric &result, int timeout_ms) noexcept;
bool Add(int fd, unsigned events, void *obj); bool Add(int fd, unsigned events, void *obj) noexcept;
bool Modify(int fd, unsigned events, void *obj); bool Modify(int fd, unsigned events, void *obj) noexcept;
bool Remove(int fd); bool Remove(int fd) noexcept;
bool Abandon(int fd) { return Remove(fd); } bool Abandon(int fd) noexcept {
return Remove(fd);
}
}; };
#endif #endif

View File

@ -34,24 +34,35 @@ class PollResultGeneric
void *obj; void *obj;
Item() = default; Item() = default;
Item(unsigned _events, void *_obj) constexpr Item(unsigned _events, void *_obj) noexcept
: events(_events), obj(_obj) { } : events(_events), obj(_obj) { }
}; };
std::vector<Item> items; std::vector<Item> items;
public: public:
size_t GetSize() const { return items.size(); } size_t GetSize() const noexcept {
unsigned GetEvents(size_t i) const { return items[i].events; } return items.size();
void *GetObject(size_t i) const { return items[i].obj; } }
void Reset() { items.clear(); }
void Clear(void *obj) { unsigned GetEvents(size_t i) const noexcept {
return items[i].events;
}
void *GetObject(size_t i) const noexcept {
return items[i].obj;
}
void Reset() noexcept {
items.clear();
}
void Clear(void *obj) noexcept {
for (auto i = items.begin(); i != items.end(); ++i) for (auto i = items.begin(); i != items.end(); ++i)
if (i->obj == obj) if (i->obj == obj)
i->events = 0; i->events = 0;
} }
void Add(unsigned events, void *obj) { void Add(unsigned events, void *obj) noexcept {
items.emplace_back(events, obj); items.emplace_back(events, obj);
} }
}; };