Mercurial > code
changeset 464:61a6f3518c55
Socket:
- Condition is now reused for Listener,
- Add bitwise operators.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 04 Nov 2015 20:27:17 +0100 |
parents | 214f03b47d4e |
children | 55b3ec952c53 |
files | C++/modules/Socket/Sockets.cpp C++/modules/Socket/Sockets.h C++/tests/Socket/main.cpp |
diffstat | 3 files changed, 303 insertions(+), 190 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Socket/Sockets.cpp Wed Nov 04 18:01:22 2015 +0100 +++ b/C++/modules/Socket/Sockets.cpp Wed Nov 04 20:27:17 2015 +0100 @@ -262,8 +262,12 @@ /* }}} */ -const int FlagRead{1 << 0}; -const int FlagWrite{1 << 1}; +/* + * Select + * ------------------------------------------------------------------ + */ + +/* {{{ Select */ std::vector<ListenerStatus> Select::wait(const ListenerTable &table, int ms) { @@ -277,10 +281,10 @@ Handle max = 0; for (const auto &pair : table) { - if (pair.second & FlagRead) { + if ((pair.second & Condition::Readable) == Condition::Readable) { FD_SET(pair.first, &readset); } - if (pair.second & FlagWrite) { + if ((pair.second & Condition::Writable) == Condition::Writable) { FD_SET(pair.first, &writeset); } @@ -307,19 +311,24 @@ for (const auto &pair : table) { if (FD_ISSET(pair.first, &readset)) { - sockets.push_back(ListenerStatus{pair.first, FlagRead}); + sockets.push_back(ListenerStatus{pair.first, Condition::Readable}); } if (FD_ISSET(pair.first, &writeset)) { - sockets.push_back(ListenerStatus{pair.first, FlagWrite}); + sockets.push_back(ListenerStatus{pair.first, Condition::Writable}); } } return sockets; } -/* -------------------------------------------------------- +/* }}} */ + +/* {{{ Poll */ + +/* * Poll implementation - * -------------------------------------------------------- */ + * ------------------------------------------------------------------ + */ #if defined(SOCKET_HAVE_POLL) @@ -327,23 +336,23 @@ # define poll WSAPoll #endif -short Poll::topoll(int flags) const noexcept +short Poll::toPoll(Condition condition) const noexcept { short result(0); - if (flags & FlagRead) { + if ((condition & Condition::Readable) == Condition::Readable) { result |= POLLIN; } - if (flags & FlagWrite) { + if ((condition & Condition::Writable) == Condition::Writable) { result |= POLLOUT; } return result; } -int Poll::toflags(short &event) const noexcept +Condition Poll::toCondition(short &event) const noexcept { - int flags = 0; + Condition condition{Condition::None}; /* * Poll implementations mark the socket differently regarding @@ -353,32 +362,32 @@ * return 0 so we mark the socket as readable. */ if ((event & POLLIN) || (event & POLLHUP)) { - flags |= FlagRead; + condition |= Condition::Readable; } if (event & POLLOUT) { - flags |= FlagWrite; + condition |= Condition::Writable; } /* Reset event for safety */ event = 0; - return flags; + return condition; } -void Poll::set(const ListenerTable &, Handle h, int flags, bool add) +void Poll::set(const ListenerTable &, Handle h, Condition condition, bool add) { if (add) { - m_fds.push_back(pollfd{h, topoll(flags), 0}); + m_fds.push_back(pollfd{h, toPoll(condition), 0}); } else { auto it = std::find_if(m_fds.begin(), m_fds.end(), [&] (const pollfd &pfd) { return pfd.fd == h; }); - it->events |= topoll(flags); + it->events |= toPoll(condition); } } -void Poll::unset(const ListenerTable &, Handle h, int flags, bool remove) +void Poll::unset(const ListenerTable &, Handle h, Condition condition, bool remove) { auto it = std::find_if(m_fds.begin(), m_fds.end(), [&] (const pollfd &pfd) { return pfd.fd == h; @@ -387,7 +396,7 @@ if (remove) { m_fds.erase(it); } else { - it->events &= ~(topoll(flags)); + it->events &= ~(toPoll(condition)); } } @@ -404,7 +413,7 @@ std::vector<ListenerStatus> sockets; for (auto &fd : m_fds) { if (fd.revents != 0) { - sockets.push_back(ListenerStatus{fd.fd, toflags(fd.revents)}); + sockets.push_back(ListenerStatus{fd.fd, toCondition(fd.revents)}); } } @@ -413,47 +422,48 @@ #endif // !SOCKET_HAVE_POLL -/* -------------------------------------------------------- +/* * Epoll implementation - * -------------------------------------------------------- */ + * ------------------------------------------------------------------ + */ #if defined(SOCKET_HAVE_EPOLL) -uint32_t Epoll::toepoll(int flags) const noexcept +uint32_t Epoll::toEpoll(Condition condition) const noexcept { uint32_t events = 0; - if (flags & FlagRead) { + if ((condition & Condition::Readable) == Condition::Readable) { events |= EPOLLIN; } - if (flags & FlagWrite) { + if ((condition & Condition::Writable) == Condition::Writable) { events |= EPOLLOUT; } return events; } -int Epoll::toflags(uint32_t events) const noexcept +Condition Epoll::toCondition(uint32_t events) const noexcept { - int flags = 0; + Condition condition{Condition::None}; if ((events & EPOLLIN) || (events & EPOLLHUP)) { - flags |= FlagRead; + condition |= Condition::Readable; } if (events & EPOLLOUT) { - flags |= FlagWrite; + condition |= Condition::Writable; } - return flags; + return condition; } -void Epoll::update(Handle h, int op, int flags) +void Epoll::update(Handle h, int op, int eflags) { epoll_event ev; std::memset(&ev, 0, sizeof (epoll_event)); - ev.events = flags; + ev.events = eflags; ev.data.fd = h; if (epoll_ctl(m_handle, op, h, &ev) < 0) { @@ -462,7 +472,7 @@ } Epoll::Epoll() - : m_handle(epoll_create1(0)) + : m_handle{epoll_create1(0)} { if (m_handle < 0) { throw Error{Error::System, "epoll_create"}; @@ -477,9 +487,9 @@ /* * Add a new epoll_event or just update it. */ -void Epoll::set(const ListenerTable &, Handle h, int flags, bool add) +void Epoll::set(const ListenerTable &, Handle h, Condition condition, bool add) { - update(h, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, toepoll(flags)); + update(h, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, toEpoll(condition)); if (add) { m_events.resize(m_events.size() + 1); @@ -487,20 +497,20 @@ } /* - * Unset is a bit complicated case because SocketListener tells us which + * Unset is a bit complicated case because Listener tells us which * flag to remove but to update epoll descriptor we need to pass * the effective flags that we want to be applied. * * So we put the same flags that are currently effective and remove the * requested one. */ -void Epoll::unset(const ListenerTable &table, Handle sc, int flags, bool remove) +void Epoll::unset(const ListenerTable &table, Handle sc, Condition condition, bool remove) { if (remove) { update(sc, EPOLL_CTL_DEL, 0); m_events.resize(m_events.size() - 1); } else { - update(sc, EPOLL_CTL_MOD, table.at(sc) & ~(toepoll(flags))); + update(sc, EPOLL_CTL_MOD, toEpoll(table.at(sc)) & ~(toEpoll(condition))); } } @@ -517,7 +527,7 @@ } for (int i = 0; i < ret; ++i) { - result.push_back(ListenerStatus{m_events[i].data.fd, toflags(m_events[i].events)}); + result.push_back(ListenerStatus{m_events[i].data.fd, toCondition(m_events[i].events)}); } return result; @@ -544,7 +554,7 @@ close(m_handle); } -void Kqueue::update(Handle h, int filter, int flags) +void Kqueue::update(Handle h, int filter, int kflags) { kevent ev; @@ -555,12 +565,12 @@ } } -void Kqueue::set(const ListenerTable &, Handle h, int flags, bool add) +void Kqueue::set(const ListenerTable &, Handle h, Condition condition, bool add) { - if (flags & FlagRead) { + if ((condition & Condition::Readable) == Condition::Readable) { update(h, EVFILT_READ, EV_ADD | EV_ENABLE); } - if (flags & FlagWrite) { + if ((condition & Condition::Writable) == Condition::Writable) { update(h, EVFILT_WRITE, EV_ADD | EV_ENABLE); } @@ -569,12 +579,12 @@ } } -void Kqueue::unset(const ListenerTable &, Handle h, int flags, bool remove) +void Kqueue::unset(const ListenerTable &, Handle h, Condition condition, bool remove) { - if (flags & FlagRead) { + if ((flags & Condition::Readable) == Condition::Readable) { update(h, EVFILT_READ, EV_DELETE); } - if (flags & FlagWrite) { + if ((flags & Condition::Writable) == Condition::Writable) { update(h, EVFILT_WRITE, EV_DELETE); } @@ -604,7 +614,7 @@ for (int i = 0; i < nevents; ++i) { sockets.push_back(ListenerStatus{ static_cast<Handle>(m_result[i].ident), - m_result[i].filter == EVFILT_READ ? FlagRead : FlagWrite + m_result[i].filter == EVFILT_READ ? Condition::Readable : Condition::Writable }); }
--- a/C++/modules/Socket/Sockets.h Wed Nov 04 18:01:22 2015 +0100 +++ b/C++/modules/Socket/Sockets.h Wed Nov 04 20:27:17 2015 +0100 @@ -408,6 +408,15 @@ /* }}} */ +/* + * Action enum + * ------------------------------------------------------------------ + * + * Defines the pending operation. + */ + +/* {{{ Action */ + /** * @enum Action * @brief Define the current operation that must complete. @@ -430,6 +439,17 @@ Send //!< The send operation has not succeded yet, caller must call send() or sendto() again }; +/* }}} */ + +/* + * Condition enum + * ------------------------------------------------------------------ + * + * Defines if we must wait for reading or writing. + */ + +/* {{{ Condition */ + /** * @enum Condition * @brief Define the required condition for the socket. @@ -438,11 +458,102 @@ * operations, the user must wait the socket to be readable or writable. This can be checked with Socket::condition. */ enum class Condition { - None, //!< No condition is required - Readable, //!< The socket must be readable - Writable //!< The socket must be writable + None, //!< No condition is required + Readable = (1 << 0), //!< The socket must be readable + Writable = (1 << 1) //!< The socket must be writable }; +/** + * Apply bitwise XOR. + * + * @param v1 the first value + * @param v2 the second value + * @return the new value + */ +constexpr Condition operator^(Condition v1, Condition v2) noexcept +{ + return static_cast<Condition>(static_cast<int>(v1) ^ static_cast<int>(v2)); +} + +/** + * Apply bitwise AND. + * + * @param v1 the first value + * @param v2 the second value + * @return the new value + */ +constexpr Condition operator&(Condition v1, Condition v2) noexcept +{ + return static_cast<Condition>(static_cast<int>(v1) & static_cast<int>(v2)); +} + +/** + * Apply bitwise OR. + * + * @param v1 the first value + * @param v2 the second value + * @return the new value + */ +constexpr Condition operator|(Condition v1, Condition v2) noexcept +{ + return static_cast<Condition>(static_cast<int>(v1) | static_cast<int>(v2)); +} + +/** + * Apply bitwise NOT. + * + * @param v the value + * @return the complement + */ +constexpr Condition operator~(Condition v) noexcept +{ + return static_cast<Condition>(~static_cast<int>(v)); +} + +/** + * Assign bitwise OR. + * + * @param v1 the first value + * @param v2 the second value + * @return the new value + */ +constexpr Condition &operator|=(Condition &v1, Condition v2) noexcept +{ + v1 = static_cast<Condition>(static_cast<int>(v1) | static_cast<int>(v2)); + + return v1; +} + +/** + * Assign bitwise AND. + * + * @param v1 the first value + * @param v2 the second value + * @return the new value + */ +constexpr Condition &operator&=(Condition &v1, Condition v2) noexcept +{ + v1 = static_cast<Condition>(static_cast<int>(v1) & static_cast<int>(v2)); + + return v1; +} + +/** + * Assign bitwise XOR. + * + * @param v1 the first value + * @param v2 the second value + * @return the new value + */ +constexpr Condition &operator^=(Condition &v1, Condition v2) noexcept +{ + v1 = static_cast<Condition>(static_cast<int>(v1) ^ static_cast<int>(v2)); + + return v1; +} + +/* }}} */ + /* * Base Socket class * ------------------------------------------------------------------ @@ -2169,14 +2280,14 @@ class ListenerStatus { public: Handle socket; //!< which socket is ready - int flags; //!< the flags + Condition flags; //!< the flags }; /** * Table used in the socket listener to store which sockets have been * set in which directions. */ -using ListenerTable = std::map<Handle, int>; +using ListenerTable = std::map<Handle, Condition>; /** * @class Select @@ -2187,27 +2298,27 @@ class Select { public: /** + * No-op, uses the ListenerTable directly. + */ + inline void set(const ListenerTable &, Handle, Condition, bool) noexcept {} + + /** + * No-op, uses the ListenerTable directly. + */ + inline void unset(const ListenerTable &, Handle, Condition, bool) noexcept {} + + /** + * Return the sockets + */ + std::vector<ListenerStatus> wait(const ListenerTable &table, int ms); + + /** * Backend identifier */ inline const char *name() const noexcept { return "select"; } - - /** - * No-op, uses the ListenerTable directly. - */ - inline void set(const ListenerTable &, Handle, int, bool) noexcept {} - - /** - * No-op, uses the ListenerTable directly. - */ - inline void unset(const ListenerTable &, Handle, int, bool) noexcept {} - - /** - * Return the sockets - */ - std::vector<ListenerStatus> wait(const ListenerTable &table, int ms); }; #if defined(SOCKET_HAVE_POLL) @@ -2223,19 +2334,19 @@ private: std::vector<pollfd> m_fds; - short topoll(int flags) const noexcept; - int toflags(short &event) const noexcept; + short toPoll(Condition flags) const noexcept; + Condition toCondition(short &event) const noexcept; public: /** * Set the handle. */ - void set(const ListenerTable &, Handle, int, bool); + void set(const ListenerTable &, Handle, Condition, bool); /** * Unset the handle. */ - void unset(const ListenerTable &, Handle, int, bool); + void unset(const ListenerTable &, Handle, Condition, bool); /** * Wait for events. @@ -2269,9 +2380,9 @@ Epoll(const Epoll &&) = delete; Epoll &operator=(const Epoll &&) = delete; - uint32_t toepoll(int flags) const noexcept; - int toflags(uint32_t events) const noexcept; - void update(Handle sc, int op, int flags); + uint32_t toEpoll(Condition flags) const noexcept; + Condition toCondition(uint32_t events) const noexcept; + void update(Handle sc, int op, int eflags); public: /** @@ -2287,12 +2398,12 @@ /** * Set the handle. */ - void set(const ListenerTable &, Handle, int, bool); + void set(const ListenerTable &, Handle, Condition, bool); /** * Unset the handle. */ - void unset(const ListenerTable &, Handle, int, bool); + void unset(const ListenerTable &, Handle, Condition, bool); /** * Wait for events. @@ -2329,7 +2440,7 @@ Kqueue(Kqueue &&) = delete; Kqueue &operator=(Kqueue &&) = delete; - void update(Handle sc, int filter, int flags); + void update(Handle sc, int filter, int kflags); public: /** @@ -2345,12 +2456,12 @@ /** * Set the handle. */ - void set(const ListenerTable &, Handle, int, bool); + void set(const ListenerTable &, Handle, Condition, bool); /** * Unset the handle. */ - void unset(const ListenerTable &, Handle, int, bool); + void unset(const ListenerTable &, Handle, Condition, bool); /** * Wait for events. @@ -2369,16 +2480,6 @@ #endif /** - * Mark the socket for read operation. - */ -extern const int FlagRead; - -/** - * Mark the socket for write operation. - */ -extern const int FlagWrite; - -/** * @class Listener * @brief Synchronous multiplexing * @@ -2398,10 +2499,10 @@ * ### Set * * @code - * void set(const ListenerTable &, Handle sc, int flags, bool add); + * void set(const ListenerTable &, Handle sc, Condition condition, bool add); * @endcode * - * This function, takes the socket to be added and the flags. The flags are + * This function, takes the socket to be added and the flags. The condition is * always guaranteed to be correct and the function will never be called twice * even if the user tries to set the same flag again. * @@ -2412,10 +2513,10 @@ * ### Unset * * @code - * void unset(const ListenerTable &, Handle sc, int flags, bool remove); + * void unset(const ListenerTable &, Handle sc, Condition condition, bool remove); * @endcode * - * Like set, this function is only called if the flags are actually set and will + * Like set, this function is only called if the condition is actually set and will * not be called multiple times. * * Also like set, an optional remove argument is set if the socket is being @@ -2440,8 +2541,6 @@ */ template <typename Backend = SOCKET_DEFAULT_BACKEND> class Listener { -public: - private: Backend m_backend; ListenerTable m_table; @@ -2521,13 +2620,13 @@ * If incorrect flags are passed, the function does nothing. * * @param sc the socket - * @param flags (may be OR'ed) + * @param condition the condition (may be OR'ed) * @throw Error if the backend failed to set */ - void set(Handle sc, int flags) + void set(Handle sc, Condition condition) { /* Invalid or useless flags */ - if (flags == 0 || flags > 0x3) + if (condition == Condition::None || static_cast<int>(condition) > 0x3) return; auto it = m_table.find(sc); @@ -2537,20 +2636,23 @@ * or update. */ if (it == m_table.end()) { - m_backend.set(m_table, sc, flags, true); - m_table.emplace(sc, flags); + m_backend.set(m_table, sc, condition, true); + m_table.emplace(sc, condition); } else { - if ((flags & FlagRead) && (it->second & FlagRead)) { - flags &= ~(FlagRead); + /* Remove flag if already present */ + if ((condition & Condition::Readable) == Condition::Readable && + (it->second & Condition::Readable) == Condition::Readable) { + condition &= ~(Condition::Readable); } - if ((flags & FlagWrite) && (it->second & FlagWrite)) { - flags &= ~(FlagWrite); + if ((condition & Condition::Writable) == Condition::Writable && + (it->second & Condition::Writable) == Condition::Writable) { + condition &= ~(Condition::Writable); } /* Still need a call? */ - if (flags != 0) { - m_backend.set(m_table, sc, flags, false); - it->second |= flags; + if (condition != Condition::None) { + m_backend.set(m_table, sc, condition, false); + it->second |= condition; } } } @@ -2563,38 +2665,40 @@ * unsetting the write flags will keep the socket for reading. * * @param sc the socket - * @param flags the flags (may be OR'ed) + * @param condition the condition (may be OR'ed) * @see remove */ - void unset(Handle sc, int flags) + void unset(Handle sc, Condition condition) { auto it = m_table.find(sc); /* Invalid or useless flags */ - if (flags == 0 || flags > 0x3 || it == m_table.end()) + if (condition == Condition::None || static_cast<int>(condition) > 0x3 || it == m_table.end()) return; /* * Like set, do not update if the socket is already at the appropriate * state. */ - if ((flags & FlagRead) && !(it->second & FlagRead)) { - flags &= ~(FlagRead); - } - if ((flags & FlagWrite) && !(it->second & FlagWrite)) { - flags &= ~(FlagWrite); + if ((condition & Condition::Readable) == Condition::Readable && + (it->second & Condition::Readable) != Condition::Readable) { + condition &= ~(Condition::Readable); } - - if (flags != 0) { + if ((condition & Condition::Writable) == Condition::Writable && + (it->second & Condition::Writable) != Condition::Writable) { + condition &= ~(Condition::Writable); + } + + if (condition != Condition::None) { /* Determine if it's a complete removal */ - bool removal = ((it->second) & ~(flags)) == 0; - - m_backend.unset(m_table, sc, flags, removal); + bool removal = ((it->second) & ~(condition)) == Condition::None; + + m_backend.unset(m_table, sc, condition, removal); if (removal) { m_table.erase(it); } else { - it->second &= ~(flags); + it->second &= ~(condition); } } } @@ -2602,13 +2706,13 @@ /** * Remove completely the socket from the listener. * - * It is a shorthand for unset(sc, FlagRead | FlagWrite); + * It is a shorthand for unset(sc, Condition::Readable | Condition::Writable); * * @param sc the socket */ inline void remove(Handle sc) { - unset(sc, FlagRead | FlagWrite); + unset(sc, Condition::Readable | Condition::Writable); } /** @@ -2727,7 +2831,7 @@ * Client connected on the server side. */ -/* {{{ */ +/* {{{ StreamConnection */ /** * @class StreamConnection @@ -2834,7 +2938,7 @@ * Convenient stream oriented server. */ -/* {{{ */ +/* {{{ StreamServer */ /** * @class StreamServer @@ -2881,9 +2985,9 @@ m_listener.remove(client->socket().handle()); if (client->socket().condition() == Condition::Readable) { - m_listener.set(client->socket().handle(), FlagRead); + m_listener.set(client->socket().handle(), Condition::Readable); } else { - m_listener.set(client->socket().handle(), FlagWrite); + m_listener.set(client->socket().handle(), Condition::Writable); } } @@ -2903,7 +3007,7 @@ /* 2. If accept is not finished, wait for the appropriate condition */ if (client->socket().state() == State::Accepted) { /* 3. Client is accepted, notify the user */ - m_listener.set(client->socket().handle(), FlagRead); + m_listener.set(client->socket().handle(), Condition::Readable); m_onConnection(client); } else { /* Operation still in progress */ @@ -2932,7 +3036,7 @@ /* Do not update the listener immediately if an action is pending */ if (client && client->socket().action() == Action::None && !client->output().empty()) { - m_listener.set(client->socket().handle(), FlagWrite); + m_listener.set(client->socket().handle(), Condition::Writable); } }); @@ -2975,7 +3079,7 @@ * case the write flag may be removed, add it if required. */ if (!client->output().empty()) { - m_listener.set(client->socket().handle(), FlagWrite); + m_listener.set(client->socket().handle(), Condition::Writable); } m_onRead(client, buffer); @@ -3003,7 +3107,7 @@ /* 3. Update listener */ if (output.empty()) { - m_listener.unset(client->socket().handle(), FlagWrite); + m_listener.unset(client->socket().handle(), Condition::Writable); } /* 4. Notify user */ @@ -3012,16 +3116,16 @@ updateFlags(client); } } - - void processSync(std::shared_ptr<StreamConnection<Address, Type>> &client, int flags) + void processSync(std::shared_ptr<StreamConnection<Address, Type>> &client, Condition flags) { try { auto action = client->socket().action(); - if (action == Action::Receive || (action == Action::None && (flags & FlagRead))) { + if (action == Action::Receive || + (action == Action::None && (flags & Condition::Readable) == Condition::Readable)) { processRead(client); - } else if (flags & FlagWrite) { + } else if ((flags & Condition::Writable) == Condition::Writable) { processWrite(client); } } catch (const Error &error) { @@ -3046,7 +3150,7 @@ m_master.set(SOL_SOCKET, SO_REUSEADDR, 1); m_master.bind(address); m_master.listen(max); - m_listener.set(m_master.handle(), FlagRead); + m_listener.set(m_master.handle(), Condition::Readable); } /** @@ -3218,9 +3322,9 @@ m_listener.remove(m_socket.handle()); if (m_socket.condition() == Condition::Readable) { - m_listener.set(m_socket.handle(), FlagRead); + m_listener.set(m_socket.handle(), Condition::Readable); } else { - m_listener.set(m_socket.handle(), FlagWrite); + m_listener.set(m_socket.handle(), Condition::Writable); } } @@ -3244,7 +3348,7 @@ if (m_socket.state() == State::Connected) { m_onConnection(); - m_listener.set(m_socket.handle(), FlagRead); + m_listener.set(m_socket.handle(), Condition::Readable); } else { /* Connection still in progress */ updateFlags(); @@ -3269,7 +3373,7 @@ * case the write flag may be removed, add it if required. */ if (!m_output.empty()) { - m_listener.set(m_socket.handle(), FlagWrite); + m_listener.set(m_socket.handle(), Condition::Writable); } m_onRead(received); @@ -3297,7 +3401,7 @@ /* 3. Update flags if needed */ if (m_output.empty()) { - m_listener.unset(m_socket.handle(), FlagWrite); + m_listener.unset(m_socket.handle(), Condition::Writable); } /* 4. Notify user */ @@ -3311,9 +3415,10 @@ /* * Receive or send. */ - void processSync(int flags) + void processSync(Condition condition) { - if ((m_socket.action() == Action::Receive) || (m_socket.action() == Action::None && (flags & FlagRead))) { + if ((m_socket.action() == Action::Receive) || + (m_socket.action() == Action::None && (condition & Condition::Readable) == Condition::Readable)) { processRead(); } else { processWrite(); @@ -3332,7 +3437,7 @@ : m_socket{address, std::move(type)} { m_socket.setBlockMode(false); - m_listener.set(m_socket.handle(), FlagRead); + m_listener.set(m_socket.handle(), Condition::Readable); } /** @@ -3409,7 +3514,7 @@ /* Don't update the listener if there is a pending operation */ if (m_socket.state() == State::Connected && m_socket.action() == Action::None && !m_output.empty()) { - m_listener.set(m_socket.handle(), FlagWrite); + m_listener.set(m_socket.handle(), Condition::Writable); } }
--- a/C++/tests/Socket/main.cpp Wed Nov 04 18:01:22 2015 +0100 +++ b/C++/tests/Socket/main.cpp Wed Nov 04 20:27:17 2015 +0100 @@ -101,6 +101,8 @@ * UDP tests * -------------------------------------------------------- */ +#if 0 + class UdpServerTest : public testing::Test { protected: SocketUdp<Ipv4> m_server; @@ -152,6 +154,8 @@ }); } +#endif + /* -------------------------------------------------------- * Listener: set function * -------------------------------------------------------- */ @@ -160,16 +164,16 @@ public: int m_callcount{0}; bool m_added{false}; - int m_flags{0}; + Condition m_flags{Condition::None}; - inline void set(const ListenerTable &, Handle, int flags, bool add) noexcept + inline void set(const ListenerTable &, Handle, Condition flags, bool add) noexcept { m_callcount ++; m_added = add; m_flags |= flags; } - inline void unset(const ListenerTable &, Handle, int, bool) noexcept + inline void unset(const ListenerTable &, Handle, Condition, bool) noexcept { } @@ -181,12 +185,12 @@ class TestBackendSetFail { public: - inline void set(const ListenerTable &, Handle, int, bool) + inline void set(const ListenerTable &, Handle, Condition, bool) { throw "fail"; } - inline void unset(const ListenerTable &, Handle, int, bool) noexcept + inline void unset(const ListenerTable &, Handle, Condition, bool) noexcept { } @@ -201,12 +205,12 @@ Listener<TestBackendSet> listener; Handle s{0}; - listener.set(s, FlagRead); + listener.set(s, Condition::Readable); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(1, listener.backend().m_callcount); ASSERT_TRUE(listener.backend().m_added); - ASSERT_TRUE(listener.backend().m_flags == FlagRead); + ASSERT_TRUE(listener.backend().m_flags == Condition::Readable); } TEST(ListenerSet, readThenWrite) @@ -214,13 +218,13 @@ Listener<TestBackendSet> listener; Handle s{0}; - listener.set(s, FlagRead); - listener.set(s, FlagWrite); + listener.set(s, Condition::Readable); + listener.set(s, Condition::Writable); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(2, listener.backend().m_callcount); ASSERT_FALSE(listener.backend().m_added); - ASSERT_TRUE(listener.backend().m_flags == 0x3); + ASSERT_TRUE(static_cast<int>(listener.backend().m_flags) == 0x3); } TEST(ListenerSet, allOneShot) @@ -228,12 +232,12 @@ Listener<TestBackendSet> listener; Handle s{0}; - listener.set(s, FlagRead | FlagWrite); + listener.set(s, Condition::Readable | Condition::Writable); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(1, listener.backend().m_callcount); ASSERT_TRUE(listener.backend().m_added); - ASSERT_TRUE(listener.backend().m_flags == 0x3); + ASSERT_TRUE(static_cast<int>(listener.backend().m_flags) == 0x3); } TEST(ListenerSet, readTwice) @@ -241,13 +245,13 @@ Listener<TestBackendSet> listener; Handle s{0}; - listener.set(s, FlagRead); - listener.set(s, FlagRead); + listener.set(s, Condition::Readable); + listener.set(s, Condition::Readable); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(1, listener.backend().m_callcount); ASSERT_TRUE(listener.backend().m_added); - ASSERT_TRUE(listener.backend().m_flags == FlagRead); + ASSERT_TRUE(listener.backend().m_flags == Condition::Readable); } TEST(ListenerSet, failure) @@ -256,7 +260,7 @@ Handle s{0}; try { - listener.set(s, FlagRead); + listener.set(s, Condition::Readable); FAIL() << "exception expected"; } catch (...) { } @@ -272,16 +276,16 @@ public: bool m_isset{false}; bool m_isunset{false}; - int m_flags{0}; + Condition m_flags{Condition::None}; bool m_removal{false}; - inline void set(const ListenerTable &, Handle &, int flags, bool) noexcept + inline void set(const ListenerTable &, Handle &, Condition flags, bool) noexcept { m_isset = true; m_flags |= flags; } - inline void unset(const ListenerTable &, Handle &, int flags, bool remove) noexcept + inline void unset(const ListenerTable &, Handle &, Condition flags, bool remove) noexcept { m_isunset = true; m_flags &= ~(flags); @@ -296,11 +300,11 @@ class TestBackendUnsetFail { public: - inline void set(const ListenerTable &, Handle &, int, bool) noexcept + inline void set(const ListenerTable &, Handle &, Condition, bool) noexcept { } - inline void unset(const ListenerTable &, Handle &, int, bool) + inline void unset(const ListenerTable &, Handle &, Condition, bool) { throw "fail"; } @@ -316,13 +320,13 @@ Listener<TestBackendUnset> listener; Handle s{0}; - listener.set(s, FlagRead); - listener.unset(s, FlagRead); + listener.set(s, Condition::Readable); + listener.unset(s, Condition::Readable); ASSERT_EQ(0U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); ASSERT_TRUE(listener.backend().m_isunset); - ASSERT_TRUE(listener.backend().m_flags == 0); + ASSERT_TRUE(listener.backend().m_flags == Condition::None); ASSERT_TRUE(listener.backend().m_removal); } @@ -331,13 +335,13 @@ Listener<TestBackendUnset> listener; Handle s{0}; - listener.set(s, FlagRead | FlagWrite); - listener.unset(s, FlagRead); + listener.set(s, Condition::Readable | Condition::Writable); + listener.unset(s, Condition::Readable); ASSERT_EQ(1U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); ASSERT_TRUE(listener.backend().m_isunset); - ASSERT_TRUE(listener.backend().m_flags == FlagWrite); + ASSERT_TRUE(listener.backend().m_flags == Condition::Writable); ASSERT_FALSE(listener.backend().m_removal); } @@ -346,14 +350,14 @@ Listener<TestBackendUnset> listener; Handle s{0}; - listener.set(s, FlagRead | FlagWrite); - listener.unset(s, FlagRead); - listener.unset(s, FlagWrite); + listener.set(s, Condition::Readable | Condition::Writable); + listener.unset(s, Condition::Readable); + listener.unset(s, Condition::Writable); ASSERT_EQ(0U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); ASSERT_TRUE(listener.backend().m_isunset); - ASSERT_TRUE(listener.backend().m_flags == 0); + ASSERT_TRUE(listener.backend().m_flags == Condition::None); ASSERT_TRUE(listener.backend().m_removal); } @@ -362,13 +366,13 @@ Listener<TestBackendUnset> listener; Handle s{0}; - listener.set(s, FlagRead | FlagWrite); + listener.set(s, Condition::Readable | Condition::Writable); listener.remove(s); ASSERT_EQ(0U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); ASSERT_TRUE(listener.backend().m_isunset); - ASSERT_TRUE(listener.backend().m_flags == 0); + ASSERT_TRUE(listener.backend().m_flags == Condition::None); ASSERT_TRUE(listener.backend().m_removal); } @@ -377,7 +381,7 @@ Listener<TestBackendUnsetFail> listener; Handle s{0}; - listener.set(s, FlagRead | FlagWrite); + listener.set(s, Condition::Readable | Condition::Writable); try { listener.remove(s); @@ -425,7 +429,7 @@ { m_tserver = std::thread([this] () { try { - m_listener.set(m_masterTcp.handle(), FlagRead); + m_listener.set(m_masterTcp.handle(), Condition::Readable); m_listener.wait(); m_masterTcp.accept(nullptr); m_masterTcp.close(); @@ -445,7 +449,7 @@ { m_tserver = std::thread([this] () { try { - m_listener.set(m_masterTcp.handle(), FlagRead); + m_listener.set(m_masterTcp.handle(), Condition::Readable); m_listener.wait(); auto sc = m_masterTcp.accept(nullptr); @@ -603,10 +607,7 @@ try { auto client = m_server.accept(nullptr); - printf("state: %d\n", client.state()); - ASSERT_EQ("hello", client.recv(32)); - std::this_thread::sleep_for(5s); } catch (const net::Error &ex) { FAIL() << ex.function() << ": " << ex.what(); } @@ -614,17 +615,14 @@ std::this_thread::sleep_for(250ms); -#if 0 - m_tclient = std::thread([this] () { try { m_client.connect(Ipv4{"127.0.0.1", 16000}); - //m_client.send("hello"); + m_client.send("hello"); } catch (const net::Error &ex) { FAIL() << ex.function() << ": " << ex.what(); } }); -#endif } int main(int argc, char **argv)