ObjFW  Check-in [0f44c12d9f]

Overview
Comment:Add -[OFRunLoop runUntilDate:]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0f44c12d9f58d2bdbbe4cea274366f974d466d47282d87f047f1d1158036a491
User & Date: js on 2016-02-10 22:25:02
Other Links: manifest | tags
Context
2016-02-21
10:36
OFRunLoop: Fix a missing deadline != nil check check-in: bb8753c099 user: js tags: trunk
2016-02-10
22:25
Add -[OFRunLoop runUntilDate:] check-in: 0f44c12d9f user: js tags: trunk
2016-02-07
20:34
Add lookup-asm-mips64-elf.S check-in: 68d4a17534 user: js tags: trunk
Changes

Modified src/OFRunLoop.h from [15bb75a7b1] to [65235ba79d].

48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







#endif
#if defined(OF_HAVE_SOCKETS)
	OFKernelEventObserver *_kernelEventObserver;
	OFMutableDictionary *_readQueues;
#elif defined(OF_HAVE_THREADS)
	OFCondition *_condition;
#endif
	volatile bool _running;
	volatile bool _stop;
}

/*!
 * @brief Returns the main run loop.
 *
 * @return The main run loop
 */
77
78
79
80
81
82
83







84
85
86
87
88
89
90
91
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98







+
+
+
+
+
+
+








- (void)addTimer: (OFTimer*)timer;

/*!
 * @brief Starts the run loop.
 */
- (void)run;

/*!
 * @brief Run the run loop until the specified deadline.
 *
 * @param deadline The date until which the run loop should run
 */
- (void)runUntilDate: (nullable OFDate*)deadline;

/*!
 * @brief Stops the run loop. If there is still an operation being executed, it
 *	  is finished before the run loop stops.
 */
- (void)stop;
@end

OF_ASSUME_NONNULL_END

Modified src/OFRunLoop.m from [1d17371e17] to [5f1e1fd3c7].

715
716
717
718
719
720
721


722
723





724
725
726


727
728
729
730

731
732

733
734
735
736
737
738


739
740
741


742
743
744
745
746
747





748
749


750
751
752
753



754
755
756
757



758
759
760
761



762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777










778
779



780
781
782


783
784
785
786



787
788

789
790
791
792
793
794
795



796
797
798
799
800
801
802
803
804
805
806





807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822
823
715
716
717
718
719
720
721
722
723


724
725
726
727
728
729


730
731

732
733

734


735


736
737


738
739
740


741
742
743





744
745
746
747
748
749

750
751
752



753
754
755
756



757
758
759
760
761


762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777



778
779
780
781
782
783
784
785
786
787
788

789
790
791
792


793
794
795



796
797
798
799

800
801

802
803



804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837
838
839







+
+
-
-
+
+
+
+
+

-
-
+
+
-


-
+
-
-
+
-
-


-
-
+
+

-
-
+
+

-
-
-
-
-
+
+
+
+
+

-
+
+

-
-
-
+
+
+

-
-
-
+
+
+


-
-
+
+
+













-
-
-
+
+
+
+
+
+
+
+
+
+

-
+
+
+

-
-
+
+

-
-
-
+
+
+

-
+

-


-
-
-
+
+
+











+
+
+
+
+







-
+









	} else
		assert(0);
}
#endif

- (void)run
{
	[self runUntilDate: nil];
}
	_running = true;


- (void)runUntilDate: (OFDate*)deadline
{
	_stop = false;

	for (;;) {
		void *pool;
		OFDate *now;
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;

		if (!_running)
		for (;;) {
			break;

			OFTimer *timer;
		pool = objc_autoreleasePoolPush();
		now = [OFDate date];

#ifdef OF_HAVE_THREADS
		[_timersQueueLock lock];
		@try {
			[_timersQueueLock lock];
			@try {
#endif
			of_list_object_t *listObject =
			    [_timersQueue firstListObject];
				of_list_object_t *listObject =
				    [_timersQueue firstListObject];

			if (listObject != NULL &&
			    [[listObject->object fireDate] compare: now] !=
			    OF_ORDERED_DESCENDING) {
				timer =
				    [[listObject->object retain] autorelease];
				if (listObject != NULL && [[listObject->object
				    fireDate] compare: now] !=
				    OF_ORDERED_DESCENDING) {
					timer = [[listObject->object
					    retain] autorelease];

				[_timersQueue removeListObject: listObject];
					[_timersQueue removeListObject:
					    listObject];

				[timer OF_setInRunLoop: nil];
			} else
				timer = nil;
					[timer OF_setInRunLoop: nil];
				} else
					break;
#ifdef OF_HAVE_THREADS
		} @finally {
			[_timersQueueLock unlock];
		}
			} @finally {
				[_timersQueueLock unlock];
			}
#endif

		if ([timer isValid])
			[timer fire];
			if ([timer isValid])
				[timer fire];
		}

#ifdef OF_HAVE_THREADS
		[_timersQueueLock lock];
		@try {
#endif
			nextTimer = [[_timersQueue firstObject] fireDate];
#ifdef OF_HAVE_THREADS
		} @finally {
			[_timersQueueLock unlock];
		}
#endif

		/* Watch for I/O events until the next timer is due */
		if (nextTimer != nil) {
			of_time_interval_t timeout =
			    [nextTimer timeIntervalSinceNow];
		if (nextTimer != nil || deadline != nil) {
			of_time_interval_t timeout;

			if (nextTimer != nil && deadline == nil)
				timeout = [nextTimer timeIntervalSinceNow];
			else if (nextTimer == nil && deadline != nil)
				timeout = [deadline timeIntervalSinceNow];
			else
				timeout = [[nextTimer earlierDate: deadline]
				    timeIntervalSinceNow];

			if (timeout > 0) {
			if (timeout < 0)
				timeout = 0;

#if defined(OF_HAVE_SOCKETS)
				[_kernelEventObserver
				    observeForTimeInterval: timeout];
			[_kernelEventObserver
			    observeForTimeInterval: timeout];
#elif defined(OF_HAVE_THREADS)
				[_condition lock];
				[_condition waitForTimeInterval: timeout];
				[_condition unlock];
			[_condition lock];
			[_condition waitForTimeInterval: timeout];
			[_condition unlock];
#else
				[OFThread sleepForTimeInterval: timeout];
			[OFThread sleepForTimeInterval: timeout];
#endif
			}
		} else {
			/*
			 * No more timers: Just watch for I/O until we get
			 * an event. If a timer is added by another thread, it
			 * cancels the observe.
			 * No more timers and no deadline: Just watch for I/O
			 * until we get an event. If a timer is added by
			 * another thread, it cancels the observe.
			 */
#if defined(OF_HAVE_SOCKETS)
			[_kernelEventObserver observe];
#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition wait];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: 86400];
#endif
		}

		if (_stop || [deadline compare: now] != OF_ORDERED_DESCENDING) {
			objc_autoreleasePoolPop(pool);
			break;
		}

		objc_autoreleasePoolPop(pool);
	}
}

- (void)stop
{
	_running = false;
	_stop = true;
#if defined(OF_HAVE_SOCKETS)
	[_kernelEventObserver cancel];
#elif defined(OF_HAVE_THREADS)
	[_condition lock];
	[_condition signal];
	[_condition unlock];
#endif
}
@end