Timer (one-off) memory ownership semantics? Delete in event?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Timer (one-off) memory ownership semantics? Delete in event?

Post by Mick P. »

I've found myself writing a replacement (or hybrid) version of GLUT (OpenGL) with wxWidgets. It has glutTimerFunc that generates one-off timers. With wxWidgets I can do "new wxTimer" and it generates the event I want. But I don't know when to delete the timer. Is it appropriate to delete the wxTimerEvent::GetTimer inside the event? I didn't even look to be sure it's the same memory. It doesn't crash to do that, but it seems inappropriate. Usually there is a KillTimer function, that in this case should have some memory ownership (transference) semantics. But I don't see anything obvious.

I apologize if this is a repeat question. I searched high and low for an answer.
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by alys666 »

i don't see a reason why this user timer cannot delete himself from timing event.
do not know wxWidgets details, but usually user timers support this feature.
another question - how accurate they are. usually system calls this user timer hooks when it's in idle state.
In which else memory user timer could be - if not an application memory.
If i were in your boots i would try to stop this timer and delete it. imho this should work.
kinda

Code: Select all

_timer.Stop(); //am sure than timer destructor calls Stop for the timer..but
delete _timer.
you must only take care about manipulations with the same timer from different threads, because it is not thread safe, imo.
ubuntu 20.04, wxWidgets 3.2.1
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by doublemax »

While delete-ing the timer from an timer event handler may be safe, nobody knows unless you look into the source. It's better to use wxAppConsole::ScheduleForDestruction().
https://docs.wxwidgets.org/trunk/classw ... 22f9de9d90

But even the, using a wxTimer directly doesn't sound very nice. Maybe it would be better to write a little helper class (possible a singleton) for that.

On top of that, why (do you think you) can't you use glutTimerFunc in a wxWidgets app?
Use the source, Luke!
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by alys666 »

doublemax wrote: Thu Jun 06, 2019 3:59 pm While delete-ing the timer from an timer event handler may be safe, nobody knows unless you look into the source.
yes. after a bit of thinking i have got that it heavily depends on implementation.
and we can be sure only if developers stated the fact that timer can be destroyed from his hook.
it is easy to implement for single shot timers, but not for periodic, because timers scheduler needs pointer to current timer after call of his hook. ref counting could help here, but im not sure about details of wxTimer(and i don't like to look in sources, because implementation could be changed in future).
ubuntu 20.04, wxWidgets 3.2.1
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by doublemax »

Using wxAppConsole::ScheduleForDestruction() is safe. It's intended for exactly that purpose.
Use the source, Luke!
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by Mick P. »

doublemax wrote: Thu Jun 06, 2019 3:59 pm On top of that, why (do you think you) can't you use glutTimerFunc in a wxWidgets app?
wxWidgets is replacing GLUT, so GLUT is not available. The software library is providing an option to not use GLUT because it's too limited for full-feature applications. I said "hybrid" because technically a few of GLUT's facilities still work, like text/teapot rendering if users want to link against both to be able to use those. A timer is linked to a "window" (GLUT owned OpenGL context) under GLUT and so glutTimerFunc cannot work without GLUT.

(EDITED: For the record glutTimerFunc may not be bound to a window. I think probably not. Either way it doesn't matter for this.)

ScheduleForDestruction sounds intriguing. It doesn't really solve the problem, but it at least keeps the pointer from dangling. To be safer the object can be dynamic_cast'ed to a known type to ensure it is a delete friendly object.

EDITED: I wrote I was curious about what ScheduleForDestruction does, but I guess it means "delete" when its docs mention deleting. Every wxTimer example I could find quote online didn't appear to use "new" to instantiate their timers. In that case I assume ScheduleForDestruction would crash. In which case, it wouldn't be safe to use without foreknowledge of the object's origins?
Last edited by Mick P. on Fri Jun 07, 2019 4:44 am, edited 1 time in total.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by doublemax »

In that case I assume ScheduleForDestruction would crash. In which case, it wouldn't be safe to use without foreknowledge of the object's origins?
Yes, you can only ScheduleForDestruction if the object was created with new. But if it wasn't, its destruction is automatic anyway.
Use the source, Luke!
iwbnwif
Super wx Problem Solver
Super wx Problem Solver
Posts: 282
Joined: Tue Mar 19, 2013 8:52 pm

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by iwbnwif »

Is it just that you want the timer to fire once and then stop?

If so, you can use StartOnce() or pass wxTIMER_ONE_SHOT to the normal Start() method.
wxWidgets 3.1.2, MinGW64 8.1.0, g++ 8.1.0, Ubuntu 19.04, Windows 10, CodeLite + wxCrafter
Some people, when confronted with a GUI problem, think "I know, I'll use Eclipse RCP". Now they have two problems.
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by Mick P. »

iwbnwif wrote: Fri Jun 07, 2019 1:58 pm Is it just that you want the timer to fire once and then stop?

If so, you can use StartOnce() or pass wxTIMER_ONE_SHOT to the normal Start() method.
The problem here is the timer can't be stored anywhere. Or I suppose you could stop it, and do something like garbage-collection on stopped timers.

Anyway, the resolution of the timers is inadequate for GLUT on Windows. So I'm going to have use wxStopWatch and check a stack of timers in the idle events against its time anyway. This is not really surprising. Windows could use timeSetEvent instead, but maybe wxWidgets doesn't want to spawn threads for timers. SetTimer is the more traditional way. But I think it would be good too if wxTimer had a mode that could be turned on individually or as a system setting to use high-resolution timer events.

EDITED: Just in case anyone is curious, I have had good success implementing GLUT with wxWidgets. It's just 1000 lines of code, without any font or teapot drawing routines. wxWidgets used mostly the same conventions as GLUT. There's probably a reason for that, but it made everything translate really easily. I'm not crazy myself about many of wxWidget's design decisions, so I don't think I would ever write code directly against it. But it's really great as a maximally expressive library to use as raw-material for more focused facades.
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by evstevemd »

Mick P. wrote: Sat Jun 08, 2019 9:34 am I'm not crazy myself about many of wxWidget's design decisions, so I don't think I would ever write code directly against it.
You mean you won't be writing code with wx anymore? Any reason as to why?
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by alys666 »

Mick P. wrote: Sat Jun 08, 2019 9:34 am
iwbnwif wrote: Fri Jun 07, 2019 1:58 pm Is it just that you want the timer to fire once and then stop?

If so, you can use StartOnce() or pass wxTIMER_ONE_SHOT to the normal Start() method.
The problem here is the timer can't be stored anywhere. Or I suppose you could stop it, and do something like garbage-collection on stopped timers.
Anyway, the resolution of the timers is inadequate for GLUT on Windows. So I'm going to have use wxStopWatch and check a stack of timers in the idle events against its time anyway. This is not really surprising. Windows could use timeSetEvent instead, but maybe wxWidgets doesn't want to spawn threads for timers. SetTimer is the more traditional way. But I think it would be good too if wxTimer had a mode that could be turned on individually or as a system setting to use high-resolution timer events.
nobody knows which demands you have for your timers.
i think, wxTimer is just a hook objects driven in wxWIdgets main thread via some timing events. they cannot be accurate, because when main thread is busy in other event handling or user code - wxTimer cannot react.
to have more accurate timers you need to drive them from context of high priority: - or from special high priority thread, or somehow from system interrupts. but in will restrict your ability to interact safely with wxWidgets visual objects and possibly the event system.
so question here - which things you want to do from your timers hooks?
imho, if you implement something kinda custom timers working in context of main thread - you won't make things better.
would be better to implement timers using high priority threads or even thread pools, which would call the ready timer's hook. but then they can interact with visual interface only using wxMessageQueue.
ubuntu 20.04, wxWidgets 3.2.1
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by Mick P. »

alys666 wrote: Sat Jun 08, 2019 9:18 pm
Mick P. wrote: Sat Jun 08, 2019 9:34 am
iwbnwif wrote: Fri Jun 07, 2019 1:58 pm Is it just that you want the timer to fire once and then stop?

If so, you can use StartOnce() or pass wxTIMER_ONE_SHOT to the normal Start() method.
The problem here is the timer can't be stored anywhere. Or I suppose you could stop it, and do something like garbage-collection on stopped timers.
Anyway, the resolution of the timers is inadequate for GLUT on Windows. So I'm going to have use wxStopWatch and check a stack of timers in the idle events against its time anyway. This is not really surprising. Windows could use timeSetEvent instead, but maybe wxWidgets doesn't want to spawn threads for timers. SetTimer is the more traditional way. But I think it would be good too if wxTimer had a mode that could be turned on individually or as a system setting to use high-resolution timer events.
nobody knows which demands you have for your timers.
i think, wxTimer is just a hook objects driven in wxWIdgets main thread via some timing events. they cannot be accurate, because when main thread is busy in other event handling or user code - wxTimer cannot react.
to have more accurate timers you need to drive them from context of high priority: - or from special high priority thread, or somehow from system interrupts. but in will restrict your ability to interact safely with wxWidgets visual objects and possibly the event system.
so question here - which things you want to do from your timers hooks?
imho, if you implement something kinda custom timers working in context of main thread - you won't make things better.
would be better to implement timers using high priority threads or even thread pools, which would call the ready timer's hook. but then they can interact with visual interface only using wxMessageQueue.
I'm a seasoned UI programmer. It makes perfect sense to process custom timers in a "heartbeat" context. wxTimer uses SetTimer on WIndows.

Like, evaluating the timers in the IDLE event works almost, but if the queue overwhelmed then that event is suppressed. In my case, there was an issue when two windows are being repainted, where the idle would not be entered. So right now when there is a PAINT event the "heatbeat" functionality is piggybacked on it too. That solves that problem. It doesn't require threads. But wxWidgets could provide on option to use timeSetEvent like I said. See your quotes.

Doing it in the main thread just means checking the wxStopWatch in the idle loop. It's not a big deal, and it's more lightweight than threads. It uses QueryPerformanceCounter which Microsoft's docs actually recommends limiting to a main thread that is assigned to a single core. But that's maybe more for games. I don't know what wxWidgets does.
evstevemd wrote: Sat Jun 08, 2019 5:24 pm You mean you won't be writing code with wx anymore? Any reason as to why?
No. wxWidgets is a wrapper around system APIs. Software libraries are wrappers around system APIs. So ideally, you write a software library around wxWidgets (virtual system API) and use that. These things serve different purposes.

Like Microsoft's MFC is a wrapper around the system API (Win32). It's a bad wrapper in my opinion. wxWidgets has a lot of things in common with MFC that are bad. But that doesn't mean it's not useful, since it solves the cross-platform problem, which is a huge problem, and very noble to tackle. It's arguably the biggest hurdle there is. Any system API is going to be ugly. You write a wrapper around it to tame it. Then you can write better code. You're using it indirectly then, and not directly. It's two different problem domains.

But yes, I would've made many different decisions had I designed wxWidgets. But that's not important. If you write a facade around some code, the whole point in the exercise is to hide the bad parts of the code on the layer below.

(I'm not suggesting "GLUT" is a better API than wxWidgets. But it's legacy of something I'm doing. And it's much simpler, and well known, so I don't know if I will retain it as a low-level description or not. It's certainly adequate for most purposes.)

I'm in the process of developing a UI framework that can be 2D and 3D and VR or use native widgets via wxWidgets, and it's providing the OpenGL context for the other modes also. The consumers of the framework don't know what is behind it. They don't include wxWidgets headers. And I would not personally use wxWidgets directly myself. If things were that easy C++ would have a standard GUI built into it. These are infeasible problems.
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by alys666 »

Mick P. wrote: Sun Jun 09, 2019 12:12 am I'm a seasoned UI programmer. It makes perfect sense to process custom timers in a "heartbeat" context. wxTimer uses SetTimer on WIndows.

Like, evaluating the timers in the IDLE event works almost, but if the queue overwhelmed then that event is suppressed. In my case, there was an issue when two windows are being repainted, where the idle would not be entered. So right now when there is a PAINT event the "heatbeat" functionality is piggybacked on it too. That solves that problem. It doesn't require threads. But wxWidgets could provide on option to use timeSetEvent like I said. See your quotes.

Doing it in the main thread just means checking the wxStopWatch in the idle loop. It's not a big deal, and it's more lightweight than threads. It uses QueryPerformanceCounter which Microsoft's docs actually recommends limiting to a main thread that is assigned to a single core. But that's maybe more for games. I don't know what wxWidgets does.
do not know what are you really doing. but a 3d game developement scheme with wxWidgets interface looks like:
1. wxWidgets main thread is running wxWIdgets visual contorls. kinda some window with buttons and frame with dynamic 3d picture.
2. the game separate thread runs in loop, doing rendering in buffer and physics, and when new 3d shot is ready, sends its pointer to wxWidgets thread via wxMessageQueue. but the game thread does not use wxTimer at all, but just asks system time in milliseconds, and possibly sleeps, if needed, for some time, - if he is making shots too fast. Because rendering and physics do not interact with wxWidgets code - everything is ok. it's the fastest scheme without any timer callbacks.
3. wxWidgets thread gets this buffer from the queue and paints it as picture in some Window control. and deletes the buffer.
4. to avoid excessive new-delete on this buffer, two buffer scheme is used.

question - what will you do, if main wxWIdgets thread is busy in some user code? just call long code synchronously from button handler and you'll lose all your timing events for this period. because main thread cannot reach idle state, and there is no any paint event(if you want to drive timers from there).
ubuntu 20.04, wxWidgets 3.2.1
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by ONEEYEMAN »

Hi,
On top of that - this is not the way to implement "heartbeat", especially if you are working in the cross-platform environment.

If you need to check the "heartbeat" of some thread or process, you better send some event to the main thread, and if the event is not arrived - the process/thread is dead.
You can implement the timer on the main/GUI thread to make it more granular, but as being said - if the main thread is stuck in some user code or doing some heavy painting - you are out of luck.

We are here maintain the huge application written in wxWidgets (starting with wxMotiff, then wxGTK) and we implement the "heartbeat" just like this. We send an event (user defined one) and if its not arrived - we restart the process.

However, I don't know whether we use wxTimer or a system timer. Program is *nix only and I didn't look close enough.

Thank you.
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Timer (one-off) memory ownership semantics? Delete in event?

Post by Mick P. »

ONEEYEMAN wrote: Sun Jun 09, 2019 5:17 am Hi,
On top of that - this is not the way to implement "heartbeat", especially if you are working in the cross-platform environment.
You're right, I didn't mean it in that sense. I wasn't thinking about that (a strategy to check if something is dead or alive right?) what I mean is a regular pulse (a heartbeat) that is something that you want to do periodically, but not too often so not to have a "heart attack".
alys666 wrote: Sun Jun 09, 2019 1:51 am question - what will you do, if main wxWIdgets thread is busy in some user code? just call long code synchronously from button handler and you'll lose all your timing events for this period. because main thread cannot reach idle state, and there is no any paint event(if you want to drive timers from there).
Well, I'm adapting it to GLUT event model now, so user code executes inline. If it takes long to execute so that many timers expire while it is working, then as soon a paint or idle event happens all of those timers are dispatched. All that matters is that the timers have decent resolution.
Last edited by Mick P. on Sun Jun 09, 2019 11:12 pm, edited 1 time in total.
Post Reply