Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Timer API #277

Merged
merged 10 commits into from
Apr 19, 2018
Merged

Add Timer API #277

merged 10 commits into from
Apr 19, 2018

Conversation

cody271
Copy link
Contributor

@cody271 cody271 commented Aug 19, 2017

First attempt at a basic timer API for libui. Still working on Windows implementation.

@andlabs
Copy link
Owner

andlabs commented Aug 20, 2017

Thanks! This predicts what I was going to do eventually; good job.

Are you sure the TimerDelegate objects on the Mac code will be properly released when the timer is stopped and/or invalidated?

Thinking aloud section:

I was planning on using SetTimer() on the utility window for the Windows version of this, though that would tie us to milliseconds (and IIRC we are limited to a guarantee of 15ms frequencies. (Of course, higher precision timing should probably use a thread, but IDK... Windows timers are complicated and I'm not sure what most people will be asking for.)

In the utflib-and-attrstr branch, I ahve this:

// uiForEach represents the return value from one of libui's various ForEach functions.
_UI_ENUM(uiForEach) {
        uiForEachContinue,
        uiForEachStop,
};

I wonder if this can be reused with some name changes somehow... Of course, the only other functions that could use that would be the uiWindowClosing() and uiOnShouldQuit() handlers.

@cody271
Copy link
Contributor Author

cody271 commented Aug 20, 2017

Mac

Are you sure the TimerDelegate objects on the Mac code will be properly released when the timer is stopped and/or invalidated?

Yes, from NSTimer documentation:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
target
The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to target until it (the timer) is invalidated.

Windows

Its not clear whether SetTimer() with no window handle is reliable, or if you really need a hidden window and custom window class. See this ancient wxWidgets bug: #6070.

From MSDN:

If no window handle is specified in the call to SetTimer, the application that created the timer must monitor its message queue for WM_TIMER messages and dispatch them to the appropriate window. If you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER.

(Also I wouldn't worry about higher precision timing at all, as you said, should probably use a thread!)

@andlabs
Copy link
Owner

andlabs commented Aug 20, 2017

Mac: ah, in that case then there is still a leak, as scheduledTimerWithTimeInterval: would retain its own reference (since it's a strong reference), and libui doesn't use ARC (yet?), so uiTimer()'s initial reference isn't released when the local variable it uses goes out of scope.

Windows: I don't mean "no window handle", I mean using the utility window (see windows/utilwin.cpp). What I need to check up on is how to deal with timer IDs, if those will even be needed.

@cody271
Copy link
Contributor Author

cody271 commented Aug 21, 2017

Mac

Whoops, no ARC! The leak should be fixed now.

Windows

I just pushed my first attempt at using SetTimer() with the utility window handle and a map of timer IDs.. still needs work.

@andlabs
Copy link
Owner

andlabs commented Aug 21, 2017

I'll check the Windows documentation later and see if (and how) this can be improved.

I was just reading the NSTimer documentation (for some unrelated reason) and I just realized something else we're overlooking:

By contrast, a repeating timer fires and then reschedules itself on the same run loop. A repeating timer always schedules itself based on the scheduled firing time, as opposed to the actual firing time. For example, if a timer is scheduled to fire at a particular time and every 5 seconds after that, the scheduled firing time will always fall on the original 5-second time intervals, even if the actual firing time gets delayed. If the firing time is delayed so far that it passes one or more of the scheduled firing times, the timer is fired only once for that time period; the timer is then rescheduled, after firing, for the next scheduled firing time in the future.

If one of the other systems doesn't turn out to work like this, then we'll have programs that work slightly differently on different toolkits... Though again, this is just a documentation check, and uiTimer()'s documentation will need to note this as well.

@cody271
Copy link
Contributor Author

cody271 commented Aug 23, 2017

If I'm understanding correctly, the most common scenario for a timer to be delayed like that would be to block the main UI thread for a significant period of time?? A situation that's always a bug in the application code..

Agreed we need to maintain the most consistent behavior across different toolkits as possible, and to document where those differences are unavoidable. The least "leaky abstraction" we can manage!

@cody271
Copy link
Contributor Author

cody271 commented Aug 25, 2017

So with my last two commits, the Windows code should now be on par with the other platforms.

Any other issues with uiTimer() that need to be resolved?

@andlabs
Copy link
Owner

andlabs commented Aug 25, 2017

Timer IDs are pointer-sized, so we can get away with using the pointer to the timer metadata struct itself as an ID; should probably consider doing that instead. I can do that myself if you don't already have an idea of how to do so by the time I get back to this.

Still trying to figure out repeating timer intervals though. I have a solution for GTK+, but not for Windows; MSDN isn't particularly helpful about this...

Note to self: note that the uiTimer() callback must not call uiMainStep().

@cody271
Copy link
Contributor Author

cody271 commented Aug 26, 2017

Timer IDs are pointer-sized, so we can get away with using the pointer to the timer metadata struct itself as an ID

Great idea, done!

Still trying to figure out repeating timer intervals though. I have a solution for GTK+, but not for Windows; MSDN isn't particularly helpful about this...

What is the GTK+ solution?

Copy link
Owner

@andlabs andlabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another partial review.

The answer to what to do about GTK+ is in my IRC logs; I'll get them out later and finish the review then.

darwin/main.m Outdated
{
self = [super init];
if (self) {
f = callback;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always qualify ivars with self->.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, will do.

@@ -31,8 +31,14 @@ if(NOT WIN32)
target_link_libraries(cpp-multithread pthread)
endif()

_add_example(timer
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if the timer example should be merged with the cpp-multithread example...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya timer was forked from cpp-multithread, trivial changes.

Merge them in what way? Single example program with a command-line switch??

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single program with a button to choose whether to use a thread or uiTimer().

darwin/main.m Outdated
@@ -237,3 +237,44 @@ void uiQueueMain(void (*f)(void *data), void *data)
// the signature of f matches dispatch_function_t
dispatch_async_f(dispatch_get_main_queue(), data, f);
}

@interface TimerDelegate : NSObject {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also you might as well make this change now as I'm going to be making this change throughout libui at some point in the near future anyway: rename the class uiprivTimerDelegate. I know it makes code a bit less nice to read, but unless I move everything (except the public API) to C++ it's either reserve the uipriv prefix for private functions that get exposed to a public namespace (which includes all Objective-C classes) or keep the crazy cmake static library hacks that don't work. :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uipriv prefix works fine, will do. A bit verbose but totally unambiguous.

What cmake hacks are you referring to?

Copy link
Owner

@andlabs andlabs Mar 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The symbol stripping stuff on the GTK+ and macOS CMakeLists.txt and the resource file copying on Windows. Both have to do with quirks of static libraries, and the former is resolved by ensuring the namespace isn't polluted. (The latter is caused by a different issue, but the same problem applies.)

I only bring this up now because I already started doing this with utflib-and-attrstr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh the _handle_static macro??

Definitely want to get rid of that, breaks the build on OpenBSD! (#229)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the more reason to fix this! =P

unix/main.c Outdated
if((*(t->f))(t->data))
return TRUE;
else {
g_free(t);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest using uiNew() and uiFree() for these, for consistency. (I now wonder if I need to keep these around anyway...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vote we keep uiNew() and uiFree(). Very useful for debugging, especially across the different platforms.

Also uiQueueMain() doesn't use them.. should it too? uiTimer() GTK+ implementation is based on it.

Copy link
Owner

@andlabs andlabs Mar 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uiQueueMain() doesn't use it because it is specifically intended for use across threads. Are you suggesting uiTimer() should also be usable across threads? Currently uiQueueMain() is the only function allowed to be used by other threads, and uiAlloc() and friends are not thread safe (by virtue of needing explicit initialization and deinitialization).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No no, you're right. Nevermind!

In fact maybe uiQueueMain() should be more clearly documented as the only function in the API that isn't UI thread only.

@andlabs
Copy link
Owner

andlabs commented Mar 25, 2018

Notes from my browser history:

https://blogs.msdn.microsoft.com/oldnewthing/20141205-00/?p=43463
https://blogs.msdn.microsoft.com/oldnewthing/20081016-00/?p=20543
https://blogs.msdn.microsoft.com/oldnewthing/20150928-00/?p=91501 (starting from the comment that starts "I think one thing that really tells what is meant to happen")

I don't think this has anything to do with this patch, but I'm putting it here anyway just for documentation purposes.

@andlabs
Copy link
Owner

andlabs commented Apr 14, 2018

I'm at the point where I'd like to merge this; would you mind addressing the existing review comments so I can do so? Thanks!

mischnic referenced this pull request in parro-it/libui-node Apr 15, 2018
{
UINT_PTR timer;

timer = (UINT_PTR) new TimerHandler(f, data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you can use a pointer to an arbitrary structure here?
From what I understood of the win32 docs, if you give it both an hWnd and a nIDEvent arguments, the function expect it to point to an existing timer id linked to that window.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timer IDs are pointer-sized, so we can get away with using the pointer to the timer metadata struct itself as an ID; should probably consider doing that instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed that comment... that's really an interesting design.

@andlabs
Copy link
Owner

andlabs commented Apr 16, 2018

Oh I completely forgot about the timer IRC log stuff; disregard that other comment. I'll bring it out in a bit.

@andlabs
Copy link
Owner

andlabs commented Apr 16, 2018

Okay, here's the full IRC log:

[2017-08-24T13:40:47-0400] <andlabs> question
[2017-08-24T13:41:03-0400] <andlabs> from Apple's docs
[2017-08-24T13:41:04-0400] <andlabs>     By contrast, a repeating timer fires and then reschedules itself on the same run loop. A repeating timer always schedules itself based on the scheduled firing time, as opposed to the actual firing time. For example, if a timer is scheduled to fire at a particular time and every 5 seconds after that, the scheduled firing time will always fall on the original 5-second time intervals, even if the actual firing time gets delayed. If the
[2017-08-24T13:41:04-0400] <andlabs>  firing time is delayed so far that it passes one or more of the scheduled firing times, the timer is fired only once for that time period; the timer is then rescheduled, after firing, for the next scheduled firing time in the future.
[2017-08-24T13:41:20-0400] <andlabs> from GLib's docs
[2017-08-24T13:41:21-0400] <andlabs> Sets a function to be called at regular intervals, with the default priority, G_PRIORITY_DEFAULT. The function is called repeatedly until it returns FALSE, at which point the timeout is automatically destroyed and the function will not be called again. The first call to the function will be at the end of the first interval .
[2017-08-24T13:41:21-0400] <andlabs> Note that timeout functions may be delayed, due to the processing of other event sources. Thus they should not be relied on for precise timing. After each call to the timeout function, the time of the next timeout is recalculated based on the current time and the given interval (it does not try to 'catch up' time lost in delays).
[2017-08-24T13:41:44-0400] <andlabs> so is GLib behaving the opposite of the Apple timer API? or identical to?
[2017-08-24T13:44:24-0400] <baedert> From that text I understand that they behave differently
[2017-08-24T13:45:49-0400] <andlabs> yeah, that's what I was thinking, but I'm not fully sure from GLib's text
[2017-08-24T13:46:37-0400] wozgeass (wozgeass@187.235.238.180) joined the channel
[2017-08-24T13:47:01-0400] keithp (keithp@home.keithp.com) left IRC (Ping timeout: 186 seconds)
[2017-08-24T13:47:16-0400] <juliushaertl> mclasen: csoriano patch has been updated ;)
[2017-08-24T13:47:44-0400] wozgeass (wozgeass@187.235.238.180) left IRC (Quit: wozgeass)
[2017-08-24T13:48:27-0400] keithp (keithp@home.keithp.com) joined the channel
[2017-08-24T13:49:02-0400] <andlabs> (and at least it's not MSDN, which is vague and inconsistent)
[2017-08-24T13:51:18-0400] oholy (oholy@rozhledna-5.chrudim.net) left IRC (Quit: oholy)
[2017-08-24T13:51:38-0400] oholy (oholy@rozhledna-5.chrudim.net) joined the channel
[2017-08-24T14:00:49-0400] oholy (oholy@rozhledna-5.chrudim.net) left IRC (Quit: oholy)
[2017-08-24T14:01:09-0400] oholy (oholy@rozhledna-5.chrudim.net) joined the channel
[2017-08-24T14:01:16-0400] wozgeass (wozgeass@187.235.238.180) joined the channel
[2017-08-24T14:02:26-0400] <~Company> andlabs: glib schedules based on firing time
[2017-08-24T14:02:45-0400] wozgeass (wozgeass@187.235.238.180) left IRC (Quit: wozgeass)
[2017-08-24T14:03:17-0400] <~Company> andlabs: if you have a g_timeout with 100ms and it fires at 125ms, it'll schedule the next one at 225ms
[2017-08-24T14:03:57-0400] <~Company> andlabs: this has the positive side effect that if your timeout function takes 150ms to finish, you will not accumulate late timers
[2017-08-24T14:05:01-0400] <~Company> ie at 100ms we run the timer, which takes 150ms, so at 250ms we run the timer for 200ms which takes 150ms so at 400ms we run the timer for 300ms which takes 150ms so at 550ms we run the timer for 400ms which...
[2017-08-24T14:05:56-0400] <~Company> instead at 100ms we run the timer which takes 150ms then at 250ms we schedule the next one at 350ms which then runs and takes until 500ms which then schedules the next at 600ms
[2017-08-24T14:06:18-0400] oholy (oholy@rozhledna-5.chrudim.net) left IRC (Quit: oholy)
[2017-08-24T14:06:37-0400] oholy (oholy@rozhledna-5.chrudim.net) joined the channel
[2017-08-24T14:08:18-0400] <halfline> if i could make one backward-incompatible change for glib, it would be to make timeouts always one shot and get rid of the boolean return value
[2017-08-24T14:08:24-0400] wozgeass (wozgeass@187.235.238.180) joined the channel
[2017-08-24T14:08:27-0400] feaneron (feaneron@186.203.198.47) left IRC (Connection reset by peer)
[2017-08-24T14:08:29-0400] rendar (I@host155-49-dynamic.16-79-r.retail.telecomitalia.it) left IRC (Quit: std::lower_bound + std::less_equal *works* with a vector without duplicates!)
[2017-08-24T14:09:42-0400] <andlabs> now I'm even more confused :D
[2017-08-24T14:12:26-0400] <halfline> andlabs: when scheduling a timer, glib always tries to use the number the user put.  even if it was late last time.
[2017-08-24T14:12:45-0400] <halfline> it doesn't deduct the time the callback took, or its tardiness last time around
[2017-08-24T14:13:03-0400] oholy (oholy@rozhledna-5.chrudim.net) left IRC (Ping timeout: 187 seconds)
[2017-08-24T14:13:12-0400] <andlabs> ok
[2017-08-24T14:13:14-0400] <halfline> when it reschedules the timer it always schedules for N milliseconds in the future, where N was passed in when the timer was first created
[2017-08-24T14:13:50-0400] <andlabs> and OS X will always schdule N after the callback was started
[2017-08-24T14:14:03-0400] <andlabs> or at least that's what it does with autorepeating timers
[2017-08-24T14:14:17-0400] <andlabs> I could imitate GLib's behavior by just making a new timer each time
[2017-08-24T14:14:31-0400] <baedert> I thought it will always schedule it to fire at start_time+i*N?
[2017-08-24T14:15:21-0400] <owen> andlabs: to emulate GLib's behavior, you'd create a new timer *before* the work of the timer
[2017-08-24T14:16:30-0400] <baedert> So now I'm also confused
[2017-08-24T14:17:03-0400] <owen> baedert: the docs that andlabs quoted are slightly wrong
[2017-08-24T14:17:21-0400] <andlabs> which docs
[2017-08-24T14:17:24-0400] <owen> After each call to the timeout function, the time of the next timeout is recalculated based on the current time and the given interval (it does not try to 'catch up' time lost in delays).
[2017-08-24T14:17:34-0400] <andlabs> oh
[2017-08-24T14:17:35-0400] <owen> That should be *Before* each call
[2017-08-24T14:17:44-0400] wozgeass (wozgeass@187.235.238.180) left IRC (Quit: wozgeass)
[2017-08-24T14:17:46-0400] <andlabs> I'm reading the glib 2.40 docs as that's my target version
[2017-08-24T14:18:11-0400] <@mclasen> baedert: yes, they behave differently
[2017-08-24T14:18:16-0400] <owen> andlabs: they've been wrong since at least 2.0, I'm pretty sure
[2017-08-24T14:19:25-0400] wozgeass (wozgeass@187.235.238.180) joined the channel
[2017-08-24T14:19:58-0400] <andlabs> so I guess I'll just take owen's word for it then
[2017-08-24T14:20:07-0400] <andlabs> of course that still leaves the confusion of Windows's timer code
[2017-08-24T14:25:00-0400] wozgeass (wozgeass@187.235.238.180) left IRC (Ping timeout: 186 seconds)
[2017-08-24T14:25:17-0400] <owen> history - the "Before each call" behavior was there since main loop was landed in glib in 1998. The docs have been wrong since they were added in 2000.
[2017-08-24T14:33:31-0400] <halfline> wait what
[2017-08-24T14:34:06-0400] <andlabs> awesome
[2017-08-24T14:34:15-0400] <halfline> owen: you're saying if i have timeout set to repeat every 500 millseconds that has a callback that sleeps for 500 milliseconds the timeout will constantly fire?
[2017-08-24T14:34:32-0400] <owen> halfline: yes
[2017-08-24T14:34:50-0400] • halfline: boggles
[2017-08-24T14:35:45-0400] <owen> And if you have two timeouts set to repeat every 500 ms, that sleep for 250 ms, I think they will also constantly fire (making the s/After/Before/ not quite right)
[2017-08-24T14:36:15-0400] <owen> well, actually, no, probably not.
[2017-08-24T14:36:28-0400] <owen> s/probably not/it depends/
[2017-08-24T14:38:16-0400] <owen> if they fire together on the same iteration of the main loop, then they will be scheduled for 500 ms after the start of the first firing
[2017-08-24T14:38:18-0400] dboles (daniel@97e629cb.skybroadband.com) joined the channel
[2017-08-24T14:38:25-0400] xjuan (xjuan@host156.186-108-159.telecom.net.ar) left IRC (Connection reset by peer)
[2017-08-24T14:38:48-0400] muhannad (muhannad@95.184.43.65) left IRC (Ping timeout: 185 seconds)
[2017-08-24T14:39:19-0400] <halfline> so it does
[2017-08-24T14:39:20-0400] <halfline>   if (again)•
[2017-08-24T14:39:20-0400] <halfline>     g_timeout_set_expiration (timeout_source, g_source_get_time (source));•
[2017-08-24T14:39:47-0400] <halfline> where g_source_time is g_get_monotonic_time() the first time it's called
[2017-08-24T14:39:55-0400] <halfline> and cached for this itereation of the main loop
[2017-08-24T14:40:37-0400] <owen> halfline: yeah, you are right that it could depend on whether naything else called g_source_get_time() before
[2017-08-24T14:41:27-0400] rtcm (rmatos@81.89.53.61.host.vnet.sk) joined the channel
[2017-08-24T14:41:53-0400] alexp (alex@host-92-7-146-187.as43234.net) joined the channel
[2017-08-24T14:41:53-0400] rtcm (rmatos@81.89.53.61.host.vnet.sk) left the channel
[2017-08-24T14:42:00-0400] <halfline> oh actually g_main_context_prepare updates it too
[2017-08-24T14:42:24-0400] <bugbot> dboles.src@gmail.com marked bug 779682 as a duplicate of unknown bug.
[2017-08-24T14:42:24-0400] <bugbot> Bug https://bugzilla.gnome.org/show_bug.cgi?id=779682 Widget: Other, normal, gtk-bugs, RESOLVED DUPLICATE, Expander content not focusable after dialog open
[2017-08-24T14:42:35-0400] <halfline> which is good since otherwise, the first source and subsequent sources would get different scheduling behaviors !
[2017-08-24T14:43:20-0400] <halfline> anyway bottom line, recurring timeouts considered harmful
[2017-08-24T14:43:41-0400] <halfline> if you need to timeout again just do it manually, it's not really any more code
[2017-08-24T14:43:48-0400] <halfline> and the semantics are a lot clearer
[2017-08-24T14:43:59-0400] pmike (miguel@62.48.190.46) left IRC (Quit: pmike)
[2017-08-24T14:44:15-0400] <dboles> I needed a recurring timeout once and instead just schedule them all up-front at the appropriate multiple of the interval
[2017-08-24T14:44:54-0400] <dboles> Trying to make the handler 'reconnect' itself led to only the 1st one occurring at the right interval, then all the rest getting concertina'd together. never figured that out
[2017-08-24T14:46:03-0400] <halfline> you knew how many times you needed to recur up front ?
[2017-08-24T14:47:07-0400] <dboles> yeah
[2017-08-24T14:48:47-0400] bastianilso (bastianils@188.114.188.238) joined the channel
[2017-08-24T14:49:04-0400] <dboles> but how often does that really happen :)

Make of this what you will.

@cody271
Copy link
Contributor Author

cody271 commented Apr 16, 2018

Interesting .. but I'm just going to ignore that for now honestly. Unless someone shows me a real application that breaks with that difference in behavior, it is out of scope for this PR.

@cody271
Copy link
Contributor Author

cody271 commented Apr 17, 2018

@andlabs Okay, uiTimer() all done!

@andlabs
Copy link
Owner

andlabs commented Apr 19, 2018

While it may be out of scope for the initial implementation, it is not out of scope in general; I'll probably just make it a TODO for the documentation. Until then, will review now. Want to get this and the uiDatePicker stuff at least in before I continue symbol name cleanup.

@andlabs
Copy link
Owner

andlabs commented Apr 19, 2018

Most of my remaining comments are just stylistic nits and things related to the renaming, so I might as well just take care of them myself and take the load off you. Thanks a lot for doing this, and also for the uiDatePicker stuff! I do appreciate it!

@andlabs andlabs merged commit 85a4c6d into andlabs:master Apr 19, 2018
@cody271
Copy link
Contributor Author

cody271 commented Apr 19, 2018

@andlabs You moved uiNew()/uiFree() to uiprivNew()/uiprivFree() before this was merged !

The build is currently broken.

@andlabs
Copy link
Owner

andlabs commented Apr 19, 2018

Should be fixed now; that was partially what I was referring to above =P

@cody271
Copy link
Contributor Author

cody271 commented Apr 19, 2018

Confirmed. The build is passing now!
I just reviewed your stylistic changes and TODOs for uiTimer(). Looks good to me.

(Also- Its weird that GitHub markdown does not recognize @ usernames in the README..)

@cody271 cody271 deleted the timer branch April 19, 2018 01:22
@msink
Copy link
Contributor

msink commented Jun 21, 2018

It crashes on exit:

$ gdb timer.exe
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from timer.exe...(no debugging symbols found)...done.
(gdb) r
Starting program: F:\src\kotlin-libui\build\konan\bin\mingw_x64\timer.exe
[New Thread 9936.0x2e78]
warning: [libui] F:\src\kotlin-libui\libui\windows\alloc.cpp:25:uninitAlloc() You have a bug: Some data was leaked; either you left a uiControl lying around or there's a bug in libui itself. Leaked data:
0x71af40 uiprivTimer


Program received signal SIGTRAP, Trace/breakpoint trap.
0x000007fefcf531f3 in KERNELBASE!DebugBreak ()
   from C:\Windows\system32\KernelBase.dll

How to correctly free timer?

@parro-it
Copy link
Contributor

If I correctly understand the API, you have to return false from your callback in order to stop & free a timer.

@andlabs
Copy link
Owner

andlabs commented Jun 21, 2018

Yes, that is correct. Please file this as a separate issue; it's an issue with the example programs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants