mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-22 01:49:48 +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
|
||||
D2Process::runIO() {
|
||||
// Handle events registered by hooks using external IOService objects.
|
||||
IOServiceMgr::instance().pollIOServices();
|
||||
// We want to block until at least one handler is called.
|
||||
// Poll runs all that are ready. If none are ready it returns immediately
|
||||
// with a count of zero.
|
||||
size_t cnt = getIOService()->poll();
|
||||
// We want to process all ready handlers on both the managed IOServices
|
||||
// and the main IOservice. If no handlers were executed on any of the
|
||||
// IOServices will wait on the main IOService until at least one handler
|
||||
// executes or we time out.
|
||||
size_t cnt = IOServiceMgr::instance().pollIOServices();
|
||||
cnt += getIOService()->poll();
|
||||
if (!cnt) {
|
||||
// Poll ran no handlers either none are ready or the service has been
|
||||
// stopped. Either way, call runOne to wait for a IO event. If the
|
||||
// service is stopped it will return immediately with a cnt of zero.
|
||||
cnt = getIOService()->runOne();
|
||||
// Polling ran no handlers so either none are ready or the service has been
|
||||
// stopped. Either way, call runOneFor() to wait for a IO event on the
|
||||
// main service. If the service is stopped it will return immediately
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace isc {
|
||||
namespace asiolink {
|
||||
|
||||
@ -56,6 +60,26 @@ public:
|
||||
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.
|
||||
///
|
||||
/// This method executes handlers for all ready events and returns.
|
||||
@ -139,6 +163,11 @@ IOService::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
|
||||
IOService::poll() {
|
||||
return (io_impl_->poll());
|
||||
|
@ -61,6 +61,22 @@ public:
|
||||
/// @return The number of handlers that were executed.
|
||||
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.
|
||||
///
|
||||
/// This method executes handlers for all ready events and returns.
|
||||
|
@ -35,11 +35,14 @@ IOServiceMgr::unregisterIOService(IOServicePtr io_service) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
size_t
|
||||
IOServiceMgr::pollIOServices() {
|
||||
size_t cnt = 0;
|
||||
for (auto& io_service : io_services_) {
|
||||
io_service->poll();
|
||||
cnt += io_service->poll();
|
||||
}
|
||||
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
} // namespace asiolink
|
||||
|
@ -62,7 +62,9 @@ public:
|
||||
}
|
||||
|
||||
/// @brief Poll IOService objects.
|
||||
void pollIOServices();
|
||||
///
|
||||
/// @return The number of handlers that were executed.
|
||||
size_t pollIOServices();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <asiolink/io_service.h>
|
||||
#include <asiolink/interval_timer.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <functional>
|
||||
@ -45,4 +46,35 @@ TEST(IOService, post) {
|
||||
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