boost::asio::steady_timer only firing once
I am trying to perform a task on an interval and I made a POC using
boost::asio::steady_timer. When I debug it, it only performs the callback
once and does not fire again. I am not sure what I am doing wrong. Any
suggestions?
// DoMouseEvents.cpp : This file contains the 'main' function. Program
execution begins and ends there.
//
#include
On Thu, Jul 11, 2019 at 5:43 PM Christopher Pisz via Boost-users
boost::asio::steady_timer...only performs the callback once and does not fire again. I am not sure what I am doing wrong. Any suggestions?
That's how it is supposed to work. If you want it to fire again, call async_wait again. Regards
async_wait is called again in the call back. It is scheduled every time it fires. On Thu, Jul 11, 2019 at 11:54 PM Vinnie Falco via Boost-users < boost-users@lists.boost.org> wrote:
On Thu, Jul 11, 2019 at 5:43 PM Christopher Pisz via Boost-users
wrote: boost::asio::steady_timer...only performs the callback once and does not fire again. I am not sure what I am doing wrong. Any suggestions?
That's how it is supposed to work. If you want it to fire again, call async_wait again.
Regards _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
On Fri, 12 Jul 2019 at 03:43, Christopher Pisz via Boost-users < boost-users@lists.boost.org> wrote:
I am trying to perform a task on an interval and I made a POC using boost::asio::steady_timer. When I debug it, it only performs the callback once and does not fire again. I am not sure what I am doing wrong. Any suggestions?
Why would it 'fire' more than once, there is no loop? int main() { boost::asio::io_context ioContext; auto pooper = Pooper(ioContext); while ( true ) { pooper.Run(); ioContext.run(); } std::cerr << "Exited..." << std::endl; } Now it will poop till you drop. Other than that, this appears to be [you don't state what you would like to achieve] some kind of event-loop, where you suspend till the next frame. You can suspend the current thread with std::this_thread::sleep_for ( std::chrono::milliseconds ( milliseconds_to_sleep ) ); or std::this_thread::sleep_until ( some_time_point_in_the_future ); using just std-lib facilities. Having said that, have a look at SFML ( https://www.sfml-dev.org/), which has all those things, event-loop, event-polling, mouse, touch, joy-stick, sound, image rendering, window creation etc. degski -- @realdegski https://edition.cnn.com/interactive/2019/06/middleeast/saudi-teen-death-pena... "Anyone who believes that exponential growth can go on forever in a finite world is either a madman or an economist" - Kenneth E. Boulding
No loop should be needed. io context runs until there is no more work. There is always work as long as the timer is being waited on, On Fri, Jul 12, 2019 at 12:00 AM degski via Boost-users < boost-users@lists.boost.org> wrote:
On Fri, 12 Jul 2019 at 03:43, Christopher Pisz via Boost-users < boost-users@lists.boost.org> wrote:
I am trying to perform a task on an interval and I made a POC using boost::asio::steady_timer. When I debug it, it only performs the callback once and does not fire again. I am not sure what I am doing wrong. Any suggestions?
Why would it 'fire' more than once, there is no loop?
int main() { boost::asio::io_context ioContext; auto pooper = Pooper(ioContext); while ( true ) { pooper.Run(); ioContext.run(); } std::cerr << "Exited..." << std::endl; }
Now it will poop till you drop.
Other than that, this appears to be [you don't state what you would like to achieve] some kind of event-loop, where you suspend till the next frame. You can suspend the current thread with std::this_thread::sleep_for ( std::chrono::milliseconds ( milliseconds_to_sleep ) ); or std::this_thread::sleep_until ( some_time_point_in_the_future ); using just std-lib facilities. Having said that, have a look at SFML ( https://www.sfml-dev.org/), which has all those things, event-loop, event-polling, mouse, touch, joy-stick, sound, image rendering, window creation etc.
degski -- @realdegski
https://edition.cnn.com/interactive/2019/06/middleeast/saudi-teen-death-pena... "Anyone who believes that exponential growth can go on forever in a finite world is either a madman or an economist" - Kenneth E. Boulding _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
It looks like my problems aren't with the timer at all. This listing pretty
much mimicked example 3.
It ends up that my problem is that if you click on a console window in
windows 10, the program ceases execution when it enters "quick edit" mode.
I was not aware of that new behavior and thought the timer was not working.
The program run fine, as is, if you don't touch the mouse.
Sorry, false alarm.
On Thu, Jul 11, 2019 at 7:42 PM Christopher Pisz
I am trying to perform a task on an interval and I made a POC using boost::asio::steady_timer. When I debug it, it only performs the callback once and does not fire again. I am not sure what I am doing wrong. Any suggestions?
// DoMouseEvents.cpp : This file contains the 'main' function. Program execution begins and ends there. //
#include
#include "boost/asio/deadline_timer.hpp" #include #include <chrono> #include <iostream> class Pooper { boost::asio::io_context & m_ioContext; boost::asio::steady_timer m_timer;
public: Pooper(boost::asio::io_context & ioContext) : m_ioContext(ioContext) , m_timer(boost::asio::steady_timer(ioContext)) { }
void Run() { m_timer.expires_from_now(std::chrono::seconds(5)); m_timer.async_wait(boost::bind(&Pooper::OnTimerExpired, this, boost::asio::placeholders::error)); }
void OnTimerExpired(const boost::system::error_code & error) { if (error.failed()) { std::cerr << "boost error: Failed" << std::endl; }
std::cout << "Poop" << std::endl;
try { // Move the mouse int x = 500; int y = 500; if (!::SetCursorPos(x, y)) { int errorCode = GetLastError(); std::cerr << "SetCursorPos error: " << errorCode << std::endl; }
// Left button down x = 65536 * 500; y = 65536 * 500; ::mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, x, y, NULL, NULL);
// Left button up x = 65536 * 500; y = 65536 * 500; ::mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP, x, y, NULL, NULL);
m_timer.expires_from_now(std::chrono::seconds(5)); m_timer.async_wait(boost::bind(&Pooper::OnTimerExpired, this, boost::asio::placeholders::error)); } catch (std::exception &) { std::cerr << "An exception occured." << std::endl; } } };
int main() { boost::asio::io_context ioContext; auto pooper = Pooper(ioContext); pooper.Run(); ioContext.run();
std::cerr << "Exited..." << std::endl; }
On Fri, Jul 12, 2019 at 7:11 AM Christopher Pisz via Boost-users < boost-users@lists.boost.org> wrote:
It ends up that my problem is that if you click on a console window in windows 10, the program ceases execution when it enters "quick edit" mode.
I was not aware of that new behavior and thought the timer was not working.
The program run fine, as is, if you don't touch the mouse.
FWIW, that's not new behavior. It's always been that way in the DOS console. --DD
On 15/07/2019 18:34, Dominique Devienne wrote:
On Fri, Jul 12, 2019 at 7:11 AM Christopher Pisz wrote:
It ends up that my problem is that if you click on a console window in windows 10, the program ceases execution when it enters "quick edit" mode.
I was not aware of that new behavior and thought the timer was not working. The program run fine, as is, if you don't touch the mouse.
FWIW, that's not new behavior. It's always been that way in the DOS console. --DD
Prior to Windows 10, QuickEdit was disabled by default, though. It only paused if you selected the Mark menu option explicitly, not if you simply left-clicked the window. (Unless you enabled that option yourself.) You can turn QuickEdit off in the console properties if it's annoying. (Also, oddly, I didn't receive Christopher's reply above...)
On 16.07.19 02:27, Gavin Lambert via Boost-users wrote:
On 15/07/2019 18:34, Dominique Devienne wrote:
On Fri, Jul 12, 2019 at 7:11 AM Christopher Pisz wrote:
It ends up that my problem is that if you click on a console window in windows 10, the program ceases execution when it enters "quick edit" mode.
I was not aware of that new behavior and thought the timer was not working. The program run fine, as is, if you don't touch the mouse.
FWIW, that's not new behavior. It's always been that way in the DOS console. --DD
Prior to Windows 10, QuickEdit was disabled by default, though. It only paused if you selected the Mark menu option explicitly, not if you simply left-clicked the window. (Unless you enabled that option yourself.)
You can turn QuickEdit off in the console properties if it's annoying.
For what it's worth: I ran into the same "problem" when I was porting some apps to Windows 10; so I decided to restore the old behaviour by running this code during startup (when starting inside a console): static void console_disable_quick_edit() { DWORD console_mode; HANDLE console_handle = GetStdHandle( STD_INPUT_HANDLE ); if( NULL == console_handle ) { return; } if( GetConsoleMode( console_handle, &console_mode ) ) { console_mode &= ~ENABLE_QUICK_EDIT_MODE; SetConsoleMode( console_handle, (console_mode | ENABLE_EXTENDED_FLAGS) ); } CloseHandle( console_handle ); } Regards, Andreas
On Tue, Jul 16, 2019 at 2:28 AM Gavin Lambert via Boost-users < boost-users@lists.boost.org> wrote:
On 15/07/2019 18:34, Dominique Devienne wrote:
On Fri, Jul 12, 2019 at 7:11 AM Christopher Pisz wrote: It ends up that my problem is that if you click on a console window in windows 10, the program ceases execution when it enters "quick edit" mode. FWIW, that's not new behavior. It's always been that way in the DOS console. --DD
Prior to Windows 10, QuickEdit was disabled by default, though.
Good point, thanks. I indeed always enable it myself. And still mainly on Win7, so wasn't aware of the default change. Thanks for Andreas' code snippet too, interesting. Not sure changing the behavior of the console is a good idea, there are pros and cons both sides. --DD
On 12/07/2019 12:42, Christopher Pisz wrote:
I am trying to perform a task on an interval and I made a POC using boost::asio::steady_timer. When I debug it, it only performs the callback once and does not fire again. I am not sure what I am doing wrong. Any suggestions?
I can't see any particular reason why this shouldn't work. Have you tried it in older versions of Boost.Asio? It wouldn't surprise me if somewhere in the switchover to io_contexts and executors, something has broken the execution guarantees. In particular I think timers are implemented with a helper thread, so it's marshalling work between two different contexts, and it wouldn't surprise me if there were a moment when the outer context doesn't have any work but the inner context does. Most apps wouldn't notice since they use a work/run loop to keep the context running when there's no "work". (I really think Asio has become too complicated for its own good.)
participants (6)
-
Andreas Wehrmann
-
Christopher Pisz
-
degski
-
Dominique Devienne
-
Gavin Lambert
-
Vinnie Falco