Browse Source

[2871] IOService::post()

To execute a callback later, from the event loop. This is to be used in
the fake resolution, instead of timer with 0 timeout (which doesn't
work, we are strict with asserting invalid parameters).
Michal 'vorner' Vaner 12 years ago
parent
commit
ef8e4e281a

+ 8 - 0
src/lib/asiolink/io_service.cc

@@ -63,6 +63,9 @@ public:
     /// It will eventually be removed once the wrapper interface is
     /// generalized.
     asio::io_service& get_io_service() { return io_service_; };
+    void post(const boost::function<void ()>& callback) {
+        io_service_.post(callback);
+    }
 private:
     asio::io_service io_service_;
     asio::io_service::work work_;
@@ -96,5 +99,10 @@ IOService::get_io_service() {
     return (io_impl_->get_io_service());
 }
 
+void
+IOService::post(const boost::function<void ()>& callback) {
+    return (io_impl_->post(callback));
+}
+
 } // namespace asiolink
 } // namespace isc

+ 13 - 0
src/lib/asiolink/io_service.h

@@ -15,6 +15,8 @@
 #ifndef ASIOLINK_IO_SERVICE_H
 #define ASIOLINK_IO_SERVICE_H 1
 
+#include <boost/function.hpp>
+
 namespace asio {
     class io_service;
 }
@@ -70,6 +72,17 @@ public:
     /// generalized.
     asio::io_service& get_io_service();
 
+    /// \brief Post a callback to the end of the queue.
+    ///
+    /// Requests the callback be called sometime later. It is not guaranteed
+    /// by the underlying asio, but it can reasonably be expected the callback
+    /// is put to the end of the callback queue. It is not called from within
+    /// this function.
+    ///
+    /// It may be used to implement "background" work, for example (doing stuff
+    /// by small bits that are called from time to time).
+    void post(const boost::function<void ()>& callback);
+
 private:
     IOServiceImpl* io_impl_;
 };

+ 1 - 0
src/lib/asiolink/tests/Makefile.am

@@ -33,6 +33,7 @@ run_unittests_SOURCES += tcp_endpoint_unittest.cc
 run_unittests_SOURCES += tcp_socket_unittest.cc
 run_unittests_SOURCES += udp_endpoint_unittest.cc
 run_unittests_SOURCES += udp_socket_unittest.cc
+run_unittests_SOURCES += io_service_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 

+ 48 - 0
src/lib/asiolink/tests/io_service_unittest.cc

@@ -0,0 +1,48 @@
+// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <asiolink/io_service.h>
+
+#include <gtest/gtest.h>
+#include <boost/bind.hpp>
+#include <vector>
+
+using namespace isc::asiolink;
+
+namespace {
+
+void
+postedEvent(std::vector<int>* destination, int value) {
+    destination->push_back(value);
+}
+
+// Check the posted events are called, in the same order they are posted.
+TEST(IOService, post) {
+    std::vector<int> called;
+    IOService service;
+    // Post two events
+    service.post(boost::bind(&postedEvent, &called, 1));
+    service.post(boost::bind(&postedEvent, &called, 2));
+    // They have not yet been called
+    EXPECT_TRUE(called.empty());
+    // Process two events
+    service.run_one();
+    service.run_one();
+    // Both events were called in the right order
+    ASSERT_EQ(2, called.size());
+    EXPECT_EQ(1, called[0]);
+    EXPECT_EQ(2, called[1]);
+}
+
+}