mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 13:07:50 +00:00
[#4049] Preliminary commit
/src/bin/d2/d2_process.cc D2Process::runIO() - use new IOService::runOneFor() /src/lib/asiolink/io_service.* IOServcie::runOneFor() - new func /src/lib/asiolink/io_service_mgr.* IOServiceMgr::pollIOServices() - return count of handlers executed /src/lib/asiolink/tests/io_service_unittest.cc TEST(IOService, runOneFor) - new test
This commit is contained in:
parent
5a3fbb5dd5
commit
688d0fd67e
@ -150,18 +150,27 @@ D2Process::run() {
|
|||||||
|
|
||||||
size_t
|
size_t
|
||||||
D2Process::runIO() {
|
D2Process::runIO() {
|
||||||
// Handle events registered by hooks using external IOService objects.
|
// We want to process all ready handlers on both the managed IOServices
|
||||||
IOServiceMgr::instance().pollIOServices();
|
// and the main IOservice. If no handlers were executed on any of the
|
||||||
// We want to block until at least one handler is called.
|
// IOServices will wait on the main IOService until at least one handler
|
||||||
// Poll runs all that are ready. If none are ready it returns immediately
|
// executes or we time out.
|
||||||
// with a count of zero.
|
size_t cnt = IOServiceMgr::instance().pollIOServices();
|
||||||
size_t cnt = getIOService()->poll();
|
cnt += getIOService()->poll();
|
||||||
if (!cnt) {
|
if (!cnt) {
|
||||||
// Poll ran no handlers either none are ready or the service has been
|
// Polling ran no handlers so either none are ready or the service has been
|
||||||
// stopped. Either way, call runOne to wait for a IO event. If the
|
// stopped. Either way, call runOneFor() to wait for a IO event on the
|
||||||
// service is stopped it will return immediately with a cnt of zero.
|
// main service. If the service is stopped it will return immediately
|
||||||
cnt = getIOService()->runOne();
|
// with a cnt of zero and timed_out set to false.
|
||||||
|
bool timed_out;
|
||||||
|
/// @todo TKM wait time should probably be configurable.
|
||||||
|
/// Currently microseconds, should be milliseconds?
|
||||||
|
cnt = getIOService()->runOneFor(100 * 1000, timed_out);
|
||||||
|
if (timed_out) {
|
||||||
|
// Return 1 so caller knows the service has not stopped.
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (cnt);
|
return (cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
namespace isc {
|
namespace isc {
|
||||||
namespace asiolink {
|
namespace asiolink {
|
||||||
|
|
||||||
@ -56,6 +60,26 @@ public:
|
|||||||
return (static_cast<size_t>(io_service_.run_one()));
|
return (static_cast<size_t>(io_service_.run_one()));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Run the underlying event loop for a single event or until
|
||||||
|
/// a wait time expires.
|
||||||
|
///
|
||||||
|
/// This method returns control to the caller as soon as the
|
||||||
|
/// first handler has completed or the wait time elapses. If the
|
||||||
|
/// number of handlers executed is zero and timed_out is set to
|
||||||
|
/// false this indicates that the IOService was stopped.
|
||||||
|
///
|
||||||
|
/// @param wait_time_usecs wait time in microseconds
|
||||||
|
/// @param[out] time_out set to true if th wait time expired
|
||||||
|
/// without any handlers executing.
|
||||||
|
/// timed_out parameter will be set true if the wait time elapsed
|
||||||
|
///
|
||||||
|
/// @return The number of handlers that were executed.
|
||||||
|
size_t runOneFor(size_t wait_time_usecs, bool& timed_out) {
|
||||||
|
size_t cnt = io_service_.run_one_for(microseconds(wait_time_usecs));
|
||||||
|
timed_out = (!cnt && !io_service_.stopped());
|
||||||
|
return (cnt);
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Run the underlying event loop for a ready events.
|
/// @brief Run the underlying event loop for a ready events.
|
||||||
///
|
///
|
||||||
/// This method executes handlers for all ready events and returns.
|
/// This method executes handlers for all ready events and returns.
|
||||||
@ -139,6 +163,11 @@ IOService::runOne() {
|
|||||||
return (io_impl_->runOne());
|
return (io_impl_->runOne());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
IOService::runOneFor(size_t wait_time_usecs, bool& timed_out) {
|
||||||
|
return (io_impl_->runOneFor(wait_time_usecs, timed_out));
|
||||||
|
};
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
IOService::poll() {
|
IOService::poll() {
|
||||||
return (io_impl_->poll());
|
return (io_impl_->poll());
|
||||||
|
@ -61,6 +61,22 @@ public:
|
|||||||
/// @return The number of handlers that were executed.
|
/// @return The number of handlers that were executed.
|
||||||
size_t runOne();
|
size_t runOne();
|
||||||
|
|
||||||
|
/// @brief Run the underlying event loop for a single event or until
|
||||||
|
/// a wait time expires.
|
||||||
|
///
|
||||||
|
/// This method returns control to the caller as soon as the
|
||||||
|
/// first handler has completed or the wait time elapses. If the
|
||||||
|
/// number of handlers executed is zero and timed_out is set to
|
||||||
|
/// false this indicates that the IOService was stopped.
|
||||||
|
///
|
||||||
|
/// @param wait_time_usecs wait time in microseconds
|
||||||
|
/// @param[out] time_out set to true if th wait time expired
|
||||||
|
/// without any handlers executing.
|
||||||
|
/// timed_out parameter will be set true if the wait time elapsed
|
||||||
|
///
|
||||||
|
/// @return The number of handlers that were executed.
|
||||||
|
size_t runOneFor(size_t wait_time_usecs, bool& timed_out);
|
||||||
|
|
||||||
/// @brief Run the underlying event loop for a ready events.
|
/// @brief Run the underlying event loop for a ready events.
|
||||||
///
|
///
|
||||||
/// This method executes handlers for all ready events and returns.
|
/// This method executes handlers for all ready events and returns.
|
||||||
|
@ -35,11 +35,14 @@ IOServiceMgr::unregisterIOService(IOServicePtr io_service) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
size_t
|
||||||
IOServiceMgr::pollIOServices() {
|
IOServiceMgr::pollIOServices() {
|
||||||
|
size_t cnt = 0;
|
||||||
for (auto& io_service : io_services_) {
|
for (auto& io_service : io_services_) {
|
||||||
io_service->poll();
|
cnt += io_service->poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace asiolink
|
} // namespace asiolink
|
||||||
|
@ -62,7 +62,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Poll IOService objects.
|
/// @brief Poll IOService objects.
|
||||||
void pollIOServices();
|
///
|
||||||
|
/// @return The number of handlers that were executed.
|
||||||
|
size_t pollIOServices();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <asiolink/io_service.h>
|
#include <asiolink/io_service.h>
|
||||||
|
#include <asiolink/interval_timer.h>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -45,4 +46,35 @@ TEST(IOService, post) {
|
|||||||
EXPECT_EQ(3, called[2]);
|
EXPECT_EQ(3, called[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the runOneFor() operates correctly.
|
||||||
|
TEST(IOService, runOneFor) {
|
||||||
|
IOServicePtr io_service(new IOService());
|
||||||
|
|
||||||
|
// Setup up a timer to expire in 200 ms.
|
||||||
|
IntervalTimer timer(io_service);
|
||||||
|
size_t wait_ms = 200;
|
||||||
|
bool timer_fired = false;
|
||||||
|
timer.setup([&timer_fired] { timer_fired = true; },
|
||||||
|
wait_ms, IntervalTimer::ONE_SHOT);
|
||||||
|
|
||||||
|
size_t time_outs = 0;
|
||||||
|
while (timer_fired == false && time_outs < 5) {
|
||||||
|
// Call runOneFor() with 1/4 of the timer duration.
|
||||||
|
bool timed_out = false;
|
||||||
|
auto cnt = io_service->runOneFor(50 * 1000, timed_out);
|
||||||
|
if (cnt || timer_fired) {
|
||||||
|
ASSERT_FALSE(timed_out);
|
||||||
|
} else {
|
||||||
|
ASSERT_TRUE(timed_out);
|
||||||
|
++time_outs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should have had at least two time outs.
|
||||||
|
EXPECT_GE(time_outs, 2);
|
||||||
|
|
||||||
|
// Timer should have fired.
|
||||||
|
EXPECT_EQ(timer_fired, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user