The callback of the timer inside a thread is not called

Hi, I am trying to make the attached code run but no luck. I use the compiler, gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3. I tried all combinations. The timer callback, handle_timeout is never called. The weird thing is that the similar code in windows using msvc works fine. Could anybody help me out to figure out the issue in the code below? Thanks a lot in advance, mustafa ============================================================ #include <boost/asio.hpp> #include <boost/thread.hpp> #include <boost/date_time.hpp> #include <boost/date_time/gregorian/gregorian.hpp> #include <ctime> #include <iostream> struct time_t_traits { // The time type. typedef std::time_t time_type; // The duration type. struct duration_type { duration_type() : value(0) {} duration_type(std::time_t v) : value(v) {} std::time_t value; }; // Get the current time. static time_type now() { return std::time(0); } // Add a duration to a time. static time_type add(const time_type& t, const duration_type& d) { return t + d.value; } // Subtract one time from another. static duration_type subtract(const time_type& t1, const time_type& t2) { return duration_type(t1 - t2); } // Test whether one time is less than another. static bool less_than(const time_type& t1, const time_type& t2) { return t1 < t2; } // Convert to POSIX duration type. static boost::posix_time::time_duration to_posix_duration( const duration_type& d) { return boost::posix_time::seconds(d.value); } }; typedef boost::asio::basic_deadline_timer< std::time_t, time_t_traits> time_t_timer; void handle_timeout(const boost::system::error_code&) { std::cout << "handle_timeout\n"; } boost::asio::io_service io_service; void workerFunc() { using namespace boost::gregorian; boost::posix_time::seconds workTime(8); std::cout << "Worker: running" << std::endl; try { boost::asio::strand io_strand(io_service); time_t_timer timer(io_service); timer.expires_from_now(5); std::cout << "Starting synchronous wait\n"; timer.wait(); std::cout << "Finished synchronous wait\n"; timer.expires_from_now(5); std::cout << "Starting asynchronous wait\n"; // timer.async_wait(&handle_timeout); // timer.async_wait(&handle_timeout); // std::cout << "current UTC time is '" << to_simple_string(microsec_clock::universal_time()) << "'" << std::endl; // std::cout << "current local time is '" << to_simple_string(microsec_clock::local_time()) << "'" << std::endl; std::cout << "timer is set to expire at '" << timer.expires_at() << "'" << std::endl; timer.async_wait(io_strand.wrap(&handle_timeout)); std::cout << "Finished asynchronous wait\n"; } catch (std::exception& e) { std::cout << "Exception: " << e.what() << "\n"; } // Pretend to do something useful... boost::this_thread::sleep(workTime); std::cout << "Worker: finished" << std::endl; while(true) { boost::this_thread::sleep(boost::posix_time::seconds(1)); } } int main(int argc, char* argv[]) { std::cout << "main: startup" << std::endl; boost::thread thrd_io(boost::bind(&boost::asio::io_service::run, &io_service)); std::cout << "main: after thrd_io" << std::endl; boost::thread workerThread(workerFunc); std::cout << "main: after workerThread" << std::endl; // std::cout << "main: waiting for thread" << std::endl; while ( true ) { try { // io_service.poll(); io_service.run(); // boost::this_thread::sleep(boost::posix_time::milliseconds( 20 )); } catch (const boost::thread_interrupted&) { // Thread interruption request received, break the loop std::cout << "[" << boost::this_thread::get_id() << "] WorkerThread Thread interrupted. Exiting thread."; break; } catch ( std::exception & ex ) { std::cout << "[" << boost::this_thread::get_id() << "] Exception: " << ex.what(); } } workerThread.join(); std::cout << "main: done" << std::endl; return 0; } ===================================================== this is the output when the exe file is run. You don't see this line: "handle_timeout" ===================================================== $./timer main: startup main: after workerThread main: after thrd_io Worker: running Starting synchronous wait Finished synchronous wait Starting asynchronous wait timer is set to expire at '1336627143' Finished asynchronous wait Worker: finished -- View this message in context: http://boost.2283326.n4.nabble.com/The-callback-of-the-timer-inside-a-thread... Sent from the Boost - Users mailing list archive at Nabble.com.

int main(int argc, char* argv[]) { boost::thread thrd_io(boost::bind(&boost::asio::io_service::run, &io_service));
The above will probably exit immediately, as it doesn't have work.
boost::thread workerThread(workerFunc); while ( true ) { try { io_service.run();
This one might also exit before another thread gives any work to the io_service. In short, try to create io_service::work before you call io_service::run() and see if it helps.

it worked! Thank you so much Igor. I changed it this way: int main(int argc, char* argv[]) { boost::asio::io_service::work work(io_service); boost::thread thrd_io(boost::bind(&boost::asio::io_service::run, &io_service)); boost::thread workerThread(workerFunc); ... } Can I ask why we needed io_service::work? in windows, it did not require it. Thanks, mustafa below is the output after i used it. $./timer main: startup main: after thrd_io main: after workerThread Worker: running Starting synchronous wait Finished synchronous wait Starting asynchronous wait timer is set to expire at '1336684315' Finished asynchronous wait handle_timeout Worker: finished -- View this message in context: http://boost.2283326.n4.nabble.com/The-callback-of-the-timer-inside-a-thread... Sent from the Boost - Users mailing list archive at Nabble.com.

it worked! Thank you so much Igor. I changed it this way: int main(int argc, char* argv[]) { boost::asio::io_service::work work(io_service); boost::thread thrd_io(boost::bind(&boost::asio::io_service::run, &io_service)); boost::thread workerThread(workerFunc); ... }
Can I ask why we needed io_service::work? in windows, it did not require it.
It's not a matter of platform, it's just a timing. You had a race condition, which produced different results under different circumstances.
participants (2)
-
Igor R
-
mozdemir