On 1/4/21 2:11 PM Gonzalo Garramuño wrote:
>
> El 4/1/21 a las 09:14, Albrecht Schlosser escribió:
>> On 1/4/21 12:48 PM Albrecht Schlosser wrote:
>>
>> Well, after thinking about it and looking closer at the backtrace you
>> (Gonzalo, the OP) posted it looks as if you're calling
>> Fl::repeat_timeout() twice *inside* the timer callback. In this case
>> Fl::has_timeout() would indeed return true after the first call ...
>
> Where did you see that in the stack trace? AFAICT, only once it is
> getting called in the stack trace.
Actually I don't see that it is really called twice. Sorry for the
confusion.
What I can see is only that Fl::repeat_timeout() is called from within a
timeout handler function from this part of the stack frame:
> #2 0x10479f8bb in Fl_Cocoa_Screen_Driver::repeat_timeout(double,
void (*)(void*), void*)+0x5b (mrv-dbg:x86_64+0x100e538bb)
> #3 0x1042d7c83 in mrv::ImageView::timeout() mrvImageView.cpp:3797
> #4 0x10430d4b8 in mrv::ImageView::handle_timeout()
mrvImageView.cpp:8082
> #5 0x1042aab9d in mrv::static_timeout(mrv::ImageView*)
mrvImageView.cpp:1675
> #6 0x10479f7d4 in do_timer(__CFRunLoopTimer*, void*)+0x34
(mrv-dbg:x86_64+0x100e537d4)
> #7 0x7fff204318fc in
__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__+0x13
(CoreFoundation:x86_64h+0x9a8fc)
I conclude that [supposedly the macOS specific FLTK function] do_timer()
calls your static timer callback mrv::static_timeout() which eventually
(indirectly) calls Fl_Cocoa_Screen_Driver::repeat_timeout() which
finally causes the issue.
The fact that you wrote that adding Fl::has_timeout() helped caused me
to *assume* that this was the second call and hence Fl::has_timeout()
would return true -- after the first call had added the same or a
similar timeout already.
> The only weird thing is that I have three timeouts. Two with the same
> user data but pointing to different functions and one with different
> function and different data.
This should be fine. Timer functions are (or at least should be, per
definition) distinguished by the combination of the function pointer and
the user data. userdata == NULL is a special case.
> These may be called independently at any
> time and in reality most of the time only the two with the same data are
> called at the same time but they go through different paths and
> different repeat_timeouts.
Note that if these timers are instantiated for the first time they
should be added with Fl::add_timeout() although Fl::repeat_timeout()
would also kinda work but, as documented, would result in undefined
behavior (which means: everything could happen, even a system crash).
You still did not answer my question *how exactly* adding
Fl::has_timeout() helped in your case. I think I asked this, but if not,
please answer now: For which return value (true or false) did you
subsequently call Fl::repeat_timeout()? And, BTW, since you are
obviously using the 'userdata' argument in your timers you should also
include it in the call to Fl::has_timeout(). So although this might be
obvious, please elaborate to make sure we're not "thinking in the wrong
direction".
>> Another question (wild guess): Do you call Fl::remove_timeout()
>> [correctly] in the scenario you described as "on the second run of a
>> movie that was removed and loaded again".
>>
> Yes, AFAIK.
OK, then we can rule this out.
That all said, I don't know and can't effectively check the macOS code
[3], hence I can't definitely say that the macOS implementation is 100%
correct. (Neither can I say this for any FLTK code, you know...) Maybe
you found a bug, but I don't take this for very probable.
Finally, there are still some things unclear to me, regarding the timer
callbacks as such: I'm not sure if it is (or should be) allowed to queue
two timer callbacks with the same callback function and the same
userdata argument. As far as I can tell off the top of my head this
*might* be possible/allowed and (if true) should not result in any timer
problems on the FLTK library side. This seems at least reasonable for
the Unix/Linux implementation which schedules and triggers timer
callbacks by itself but ISTR that Windows works different (using system
timers). I have no idea how the macOS implementation works...
I'm now curious and intend to look into this more deeply, but very
likely not today.
Thinking out loud: Assuming someone managed to add two identical timer
callbacks, i.e. with the same callback and userdata [1] and a similar
time it could happen that both timer events would be serviced in the
same run of the FLTK event loop, i.e. the second timer callback would
see [2] the previously queued timer callback from the first timer event.
Generally this would alway be the case, i.e. any timer callback would
see [2] the timer instance of the "other" timer that's still or already
active. Again, I'm not sure if this is allowed (i.e. documented to be
allowed) or a practical use at all. Needs some investigation and maybe
better documentation...
Footnotes:
[1] Note that userdata can be NULL which works like a wildcard in terms
of Fl::has_timeout()
[2] "see" in the sense that Fl::add_timeout() would return true.
[3] I'm not familiar with ObjC and I don't know the intrinsics of the
macOS specific system functions