Author: lubosd
Date: Sun Apr 20 12:56:52 2014
New Revision: 37805
URL: http://svn.gna.org/viewcvs/gnustep?rev=37805&view=rev
Log:
* Source/CFRunLoop.c,
Tests/CFRunLoop/timers.m: CFRunLoop timer fixes and tests
Added:
libs/corebase/trunk/Tests/CFRunLoop/timers.m
Modified:
libs/corebase/trunk/ChangeLog
libs/corebase/trunk/Source/CFRunLoop.c
Modified: libs/corebase/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/corebase/trunk/ChangeLog?rev=37805&r1=37804&r2=37805&view=diff
==============================================================================
--- libs/corebase/trunk/ChangeLog (original)
+++ libs/corebase/trunk/ChangeLog Sun Apr 20 12:56:52 2014
@@ -1,3 +1,7 @@
+2014-04-20 Lubos Dolezel <[email protected]>
+ * Source/CFRunLoop.c,
+ Tests/CFRunLoop/timers.m: CFRunLoop timer fixes and tests
+
2014-04-18 Lubos Dolezel <[email protected]>
* Source/CFRunLoop.c,
Tests/CFRunLoop/source.m: CFRunLoop impl that passes the test
Modified: libs/corebase/trunk/Source/CFRunLoop.c
URL:
http://svn.gna.org/viewcvs/gnustep/libs/corebase/trunk/Source/CFRunLoop.c?rev=37805&r1=37804&r2=37805&view=diff
==============================================================================
--- libs/corebase/trunk/Source/CFRunLoop.c (original)
+++ libs/corebase/trunk/Source/CFRunLoop.c Sun Apr 20 12:56:52 2014
@@ -37,6 +37,7 @@
# include <unistd.h>
# include <fcntl.h>
# include <poll.h>
+# include <limits.h>
#endif
#ifdef HAVE_LIBDISPATCH
# include <dispatch/dispatch.h>
@@ -363,6 +364,8 @@
0, &kCFTypeDictionaryKeyCallBacks,
NULL);
+ CFSetAddValue(rl->_commonModes, kCFRunLoopDefaultMode);
+
pipe(rl->_wakeUpPipe);
fcntl(rl->_wakeUpPipe[0], F_SETFL, O_NONBLOCK);
fcntl(rl->_wakeUpPipe[1], F_SETFL, O_NONBLOCK);
@@ -415,7 +418,7 @@
do
{
code = CFRunLoopRunInMode (kCFRunLoopDefaultMode, DISTANT_FUTURE, false);
- } while (code != kCFRunLoopRunFinished || code != kCFRunLoopRunStopped);
+ } while (code != kCFRunLoopRunFinished && code != kCFRunLoopRunStopped);
}
static void
@@ -477,15 +480,12 @@
for (i = 0; i < count; i++)
{
CFRunLoopTimerRef timer = timers[i];
-
- if (timer->_nextFireDate < now)
+
+ if (timer->_isValid && (timer->_nextFireDate < now || fabs(now -
timer->_nextFireDate) < 0.001))
{
hadTimer = true;
timer->_callback(timer, timer->_context.info);
- }
-
- if (timer->_isValid)
- {
+
// Compute the next time
if (timer->_interval <= 0)
timer->_isValid = false;
@@ -697,6 +697,7 @@
if (nextTimer < DISTANT_FUTURE)
{
int delay = (int) ( (nextTimer - timeNow)*1000 );
+ // printf("(%f-%f)*1000=%d\n", nextTimer, timeNow, delay);
if (timeout == -1 || delay < timeout)
timeout = delay;
if (timeout < 0)
@@ -719,6 +720,7 @@
CFRunLoopNotifyObservers(rl, context, kCFRunLoopBeforeWaiting);
rl->_isWaiting = true;
+ // printf("poll: %d ms\n", timeout);
sourcesFired = poll(pfd, numSources, timeout);
rl->_isWaiting = false;
@@ -736,6 +738,7 @@
if (pfd[0].revents != 0)
{
int dummy;
+ // printf("loop woken up!\n");
// Remove everything from the notification pipe that woke us up
while (read(pfd[0].fd, &dummy, sizeof(dummy)) > 0);
@@ -749,9 +752,10 @@
}
#endif
- hadSource |= CFRunLoopProcessTimers(rl, timeNow, context);
- hadSource |= CFRunLoopProcessSourcesVersion0(rl, timeNow, context);
- }
+ }
+
+ hadSource |= CFRunLoopProcessTimers(rl, timeNow, context);
+ hadSource |= CFRunLoopProcessSourcesVersion0(rl, timeNow, context);
if (returnAfterSourceHandled && hadSource)
{
@@ -1421,11 +1425,13 @@
GSRunLoopContextRef context = GSRunLoopContextGet(rl, mode);
count = CFArrayGetCount(context->timers);
+ // printf("Current time: %f\n", CFAbsoluteTimeGetCurrent());
for (i = 0; i < count; i++)
{
CFRunLoopTimerRef timer = (CFRunLoopTimerRef)
CFArrayGetValueAtIndex(context->timers, i);
+ // printf("Timer %p valid:%d nextFireDate:%f\n", timer, timer->_isValid,
timer->_nextFireDate);
if (timer->_isValid)
{
if (timer->_nextFireDate < rv)
Added: libs/corebase/trunk/Tests/CFRunLoop/timers.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/corebase/trunk/Tests/CFRunLoop/timers.m?rev=37805&view=auto
==============================================================================
--- libs/corebase/trunk/Tests/CFRunLoop/timers.m (added)
+++ libs/corebase/trunk/Tests/CFRunLoop/timers.m Sun Apr 20 12:56:52 2014
@@ -0,0 +1,78 @@
+#include <CoreFoundation/CFRunLoop.h>
+
+#include "../CFTesting.h"
+#include <pthread.h>
+#include <unistd.h>
+
+int timesTimer1Fired = 0, timesTimer2Fired = 0;
+void timerCallback(CFRunLoopTimerRef timer, void *info);
+void timerCallback2(CFRunLoopTimerRef timer, void *info);
+void* createSecondTimerThread(void* p);
+
+int main()
+{
+ // Test plan:
+ // Create a repeated timer, check if it repeats and invalidate it after
2 repeats.
+ // Asynchronously, while the runloop is waiting, plan another,
singleshot timer
+ // to see, if the runloop reschedules correctly.
+ // After all timers are invalid, the runloop should exit.
+
+ CFRunLoopRef rl;
+ CFRunLoopTimerRef timer1;
+
+ rl = CFRunLoopGetMain ();
+ PASS_CF(rl != NULL, "Got main run loop.");
+
+ timer1 = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 1, 1,
+ 0, 0, timerCallback, NULL);
+
+ CFRunLoopAddTimer(rl, timer1, kCFRunLoopCommonModes);
+ CFRelease(timer1);
+
+ CFRunLoopRun();
+ PASS_CF(timesTimer1Fired == 2, "Timer 1 fired twice and loop exited");
+
+ return 0;
+}
+
+void timerCallback(CFRunLoopTimerRef timer, void *info)
+{
+ timesTimer1Fired++;
+
+ printf("Timer 1 fired...\n");
+
+ if (timesTimer1Fired == 1)
+ {
+ pthread_t thread;
+ pthread_create(&thread, NULL, createSecondTimerThread, NULL);
+
+ }
+ else if (timesTimer1Fired >= 2)
+ CFRunLoopTimerInvalidate(timer);
+}
+
+void timerCallback2(CFRunLoopTimerRef timer, void *info)
+{
+ printf("Timer 2 fired\n");
+ PASS_CF(timesTimer1Fired == 1, "Timer 2 fired while timer 1 fired only
once");
+
+ timesTimer2Fired++;
+
+ PASS_CF(timesTimer2Fired == 1, "Timer 2 fires only once");
+}
+
+void* createSecondTimerThread(void* p)
+{
+ CFRunLoopRef rl = CFRunLoopGetMain ();
+ CFRunLoopTimerRef timer2;
+
+ while (!CFRunLoopIsWaiting(rl))
+ usleep(10*1000);
+
+ timer2 = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 0.25,
0,
+ 0, 0, timerCallback2, NULL);
+ CFRunLoopAddTimer(rl, timer2, kCFRunLoopCommonModes);
+ CFRelease(timer2);
+
+ return NULL;
+}
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs