I debugged the program with printfs and found out that the dangling pointer is not the one as parameter to repeat_timeout (which is "this" of the class), but the current_timer->timer one. It seems there’s a running issue with the list of mac_timers and their timing to be ready to be called on repeat_timeout, leading them to be not initialized. I am unsure of this Fl_Cocoa_Screen_Driver.cxx code as it seems to be running on one thread but do things that several threads would do. void Fl_Cocoa_Screen_Driver::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) { if (!current_timer) { add_timeout(time, cb, data); return; } //////////////////////// ADDED and fixes my crashes, but I consider this a hack and not a true solution. if ( current_timer->timer == nullptr ) { return; }
On 12/7/21 2:22 PM, Albrecht Schlosser wrote:
[..]
The (false) assumption in FLTK on macOS that the user code calls Fl::repeat_timeout() *only* in the timer callback of the same timer it wants to *repeat* is the culprit (IIRC). This is in platform specific code only on macOS and should be fixed because the timer code on other platforms works differently.
Hmm, just reacting to the "(false) assumption in fltk"..
Perhaps I'm missing something, but hasn't it always been the
case
calling Fl::repeat_timeout() is only valid within
the timeout's callback?
The docs seem to have always been clear about this:
1.1.x docs: "You may only call
this method inside a timeout callback."
1.3.8 docs: "You may only call this method inside a timeout
callback."
1.4.x docs: "You may only call this method inside a
timeout callback of the same timer or at least a closely related
timer [..]"
I actually can't think of a valid reason to call it outside of
that context..?
> El 7 dic. 2021, a las 13:33, Manolo <manol...@gmail.com> escribió:
>
> I would sggest you run your program under a debugger and make sure the pointer you transmit
> as 3rg argument to Fl::repeat_timeout() remains valid until the moment when the timeout runs.
>
I debugged the program with printfs and found out that the dangling pointer is not the one as parameter to repeat_timeout (which is "this" of the class), but the current_timer->timer one. It seems there’s a running issue with the list of mac_timers and their timing to be ready to be called on repeat_timeout, leading them to be not initialized. I am unsure of this Fl_Cocoa_Screen_Driver.cxx code as it seems to be running on one thread but do things that several threads would do.
void Fl_Cocoa_Screen_Driver::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
{
if (!current_timer) {
add_timeout(time, cb, data);
return;
}
//////////////////////// ADDED and fixes my crashes, but I consider this a hack and not a true solution.
if ( current_timer->timer == nullptr ) {
return;
}
That you get current_timer->timer == nullptr most probably means that delete_timer()has been called before repeat_timeout() was called.
This means that the control did not stay continuously inside your callback function,but was returned to cocoa at some point by your callback, in contradiction to what is required to use repeat_timeout().
No, it actually meant that a stray thread on my side was calling Fl::remove_timeout, breaking both the contract with fltk (of not calling things outside the main thread) and breaking Fl::repeat_timeout.
Thanks, Manolo. Your advice is always helpful.