Mercurial > code
changeset 588:6d1579861b4a
Net: rename Listener::set to Listener::reset, improve Listener tests
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 29 Aug 2016 21:16:40 +0200 |
parents | 865610e072a0 |
children | 5717cb946cd3 |
files | modules/net/net.hpp modules/net/test/main.cpp |
diffstat | 2 files changed, 200 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/modules/net/net.hpp Tue Jul 26 09:56:59 2016 +0200 +++ b/modules/net/net.hpp Mon Aug 29 21:16:40 2016 +0200 @@ -162,6 +162,8 @@ * * Set one or more condition for the given handle. * + * This erase previous flags if any. + * * ## Synopsis * * ```` @@ -965,8 +967,9 @@ */ enum class Condition { None, //!< No condition is required - Readable = (1 << 0), //!< The socket must be readable - Writable = (1 << 1) //!< The socket must be writable + Readable = (1 << 0), //!< The socket must be readable + Writable = (1 << 1), //!< The socket must be writable + All = 0x3 //! Both are requested }; /** @@ -2495,7 +2498,7 @@ length = sizeof (sun); #endif - return Address(reinterpret_cast<const sockaddr *>(&sun), length); + return Address(reinterpret_cast<const sockaddr *>(&sun), length); } /** @@ -3437,6 +3440,16 @@ } /** + * Overloaded function. + * + * \return the backend + */ + inline Backend &backend() noexcept + { + return m_backend; + } + + /** * Get the non-modifiable table. * * \return the table @@ -3494,11 +3507,13 @@ * * If incorrect flags are passed, the function does nothing. * + * Previous flags are discarded. + * * \param sc the socket * \param condition the condition (may be OR'ed) * \throw Error if the backend failed to set */ - void set(Handle sc, Condition condition) + void reset(Handle sc, Condition condition) { // Invalid or useless flags. if (condition == Condition::None || static_cast<int>(condition) > 0x3) @@ -3511,18 +3526,27 @@ m_backend.set(m_table, sc, condition, true); m_table.emplace(sc, condition); } else { - // Remove flag if already present. - if ((condition & Condition::Readable) == Condition::Readable && - (it->second & Condition::Readable) == Condition::Readable) - condition &= ~(Condition::Readable); - if ((condition & Condition::Writable) == Condition::Writable && - (it->second & Condition::Writable) == Condition::Writable) - condition &= ~(Condition::Writable); - - // Still need a call? - if (condition != Condition::None) { - m_backend.set(m_table, sc, condition, false); - it->second |= condition; + /* + * In this scenario, the socket exist in the registry with at least + * one flag, the user may call set with read, write or both flags. + * + * If one of Readable or Writable is requested, we remove the + * opposite one if present. + * + * If both are requested, we add the missing one. + */ + auto remove = it->second & ~(condition); + + if (remove != Condition::None) { + m_backend.unset(m_table, sc, remove, false); + it->second &= ~(remove); + } + + auto apply = it->second ^ condition; + + if (apply != Condition::None) { + m_backend.set(m_table, sc, it->second ^ condition, false); + it->second |= (it->second ^ condition); } } }
--- a/modules/net/test/main.cpp Tue Jul 26 09:56:59 2016 +0200 +++ b/modules/net/test/main.cpp Mon Aug 29 21:16:40 2016 +0200 @@ -248,19 +248,17 @@ class TestBackendSet { public: - int m_callcount{0}; - bool m_added{false}; - Condition m_flags{Condition::None}; + std::function<void (Condition, bool)> onSet; + std::function<void (Condition, bool)> onUnset; - inline void set(const ListenerTable &, Handle, Condition flags, bool add) noexcept + inline void set(const ListenerTable &, Handle, Condition flags, bool addition) noexcept { - m_callcount ++; - m_added = add; - m_flags |= flags; + onSet(flags, addition); } - inline void unset(const ListenerTable &, Handle, Condition, bool) noexcept + inline void unset(const ListenerTable &, Handle, Condition flags, bool removal) noexcept { + onUnset(flags, removal); } std::vector<ListenerStatus> wait(const ListenerTable &, int) @@ -286,17 +284,53 @@ } }; +TEST(ListenerSet, none) +{ + Listener<TestBackendSet> listener; + Handle s = 0; + + listener.backend().onSet = [&] (auto, auto) { + FAIL() << "unexpected set call"; + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, static_cast<Condition>(0U)); + + ASSERT_EQ(0U, listener.size()); +} + +TEST(ListenerSet, invalid) +{ + Listener<TestBackendSet> listener; + Handle s = 0; + + listener.backend().onSet = [&] (auto, auto) { + FAIL() << "unexpected set call"; + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, static_cast<Condition>(123U)); + + ASSERT_EQ(0U, listener.size()); +} + TEST(ListenerSet, initialAdd) { Listener<TestBackendSet> listener; Handle s = 0; - listener.set(s, Condition::Readable); + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::Readable, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(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 == Condition::Readable); } TEST(ListenerSet, readThenWrite) @@ -304,13 +338,28 @@ Listener<TestBackendSet> listener; Handle s = 0; - listener.set(s, Condition::Readable); - listener.set(s, Condition::Writable); + // Add Readable. + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::Readable, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, Condition::Readable); + + // Replace Readable with Writable. + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_FALSE(addition); + ASSERT_EQ(Condition::Writable, flags); + }; + listener.backend().onUnset = [&] (auto flags, auto removal) { + ASSERT_FALSE(removal); + ASSERT_EQ(Condition::Readable, flags); + }; + listener.reset(s, Condition::Writable); ASSERT_EQ(1U, listener.size()); - ASSERT_EQ(2, listener.backend().m_callcount); - ASSERT_FALSE(listener.backend().m_added); - ASSERT_TRUE(static_cast<int>(listener.backend().m_flags) == 0x3); } TEST(ListenerSet, allOneShot) @@ -318,12 +367,16 @@ Listener<TestBackendSet> listener; Handle s = 0; - listener.set(s, Condition::Readable | Condition::Writable); + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::All, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(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(static_cast<int>(listener.backend().m_flags) == 0x3); } TEST(ListenerSet, readTwice) @@ -331,13 +384,86 @@ Listener<TestBackendSet> listener; Handle s = 0; - listener.set(s, Condition::Readable); - listener.set(s, Condition::Readable); + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::Readable, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, Condition::Readable); + listener.backend().onSet = [&] (auto, auto) { + FAIL() << "double set call unexpected"; + }; + listener.reset(s, Condition::Readable); + + ASSERT_EQ(1U, listener.size()); +} + +TEST(ListenerSet, writeTwice) +{ + Listener<TestBackendSet> listener; + Handle s = 0; + + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::Writable, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, Condition::Writable); + listener.backend().onSet = [&] (auto, auto) { + FAIL() << "double set call unexpected"; + }; + listener.reset(s, 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 == Condition::Readable); +} + +TEST(ListenerSet, allTwice) +{ + Listener<TestBackendSet> listener; + Handle s = 0; + + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::All, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, Condition::All); + listener.backend().onSet = [&] (auto, auto) { + FAIL() << "double set call unexpected"; + }; + listener.reset(s, Condition::All); + + ASSERT_EQ(1U, listener.size()); +} + +TEST(ListenerSet, bothThenReadable) +{ + Listener<TestBackendSet> listener; + Handle s = 0; + + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::All, flags); + }; + listener.backend().onUnset = [&] (auto, auto) { + FAIL() << "unexpected unset call"; + }; + listener.reset(s, Condition::All); + listener.backend().onSet = [&] (auto flags, auto addition) { + ASSERT_TRUE(addition); + ASSERT_EQ(Condition::Readable, flags); + }; + listener.backend().onUnset = [&] (auto flags, auto removal) { + ASSERT_FALSE(removal); + ASSERT_EQ(Condition::Writable, flags); + }; + listener.reset(s, Condition::Readable); } TEST(ListenerSet, failure) @@ -345,7 +471,7 @@ Listener<TestBackendSetFail> listener; Handle s = 0; - ASSERT_ANY_THROW(listener.set(s, Condition::Readable)); + ASSERT_ANY_THROW(listener.reset(s, Condition::Readable)); ASSERT_EQ(0U, listener.size()); } @@ -402,7 +528,7 @@ Listener<TestBackendUnset> listener; Handle s = 0; - listener.set(s, Condition::Readable); + listener.reset(s, Condition::Readable); listener.unset(s, Condition::Readable); ASSERT_EQ(0U, listener.size()); @@ -417,7 +543,7 @@ Listener<TestBackendUnset> listener; Handle s = 0; - listener.set(s, Condition::Readable | Condition::Writable); + listener.reset(s, Condition::Readable | Condition::Writable); listener.unset(s, Condition::Readable); ASSERT_EQ(1U, listener.size()); @@ -432,7 +558,7 @@ Listener<TestBackendUnset> listener; Handle s = 0; - listener.set(s, Condition::Readable | Condition::Writable); + listener.reset(s, Condition::Readable | Condition::Writable); listener.unset(s, Condition::Readable); listener.unset(s, Condition::Writable); @@ -448,7 +574,7 @@ Listener<TestBackendUnset> listener; Handle s = 0; - listener.set(s, Condition::Readable | Condition::Writable); + listener.reset(s, Condition::Readable | Condition::Writable); listener.remove(s); ASSERT_EQ(0U, listener.size()); @@ -463,7 +589,7 @@ Listener<TestBackendUnsetFail> listener; Handle s = 0; - listener.set(s, Condition::Readable | Condition::Writable); + listener.reset(s, Condition::Readable | Condition::Writable); ASSERT_ANY_THROW(listener.remove(s)); @@ -508,7 +634,7 @@ { m_tserver = std::thread([this] () { try { - m_listener.set(m_masterTcp.handle(), Condition::Readable); + m_listener.reset(m_masterTcp.handle(), Condition::Readable); m_listener.wait(); m_masterTcp.accept(); m_masterTcp.close(); @@ -528,7 +654,7 @@ { m_tserver = std::thread([this] () { try { - m_listener.set(m_masterTcp.handle(), Condition::Readable); + m_listener.reset(m_masterTcp.handle(), Condition::Readable); m_listener.wait(); TcpSocket sc = m_masterTcp.accept();