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
#endif
#if defined(OF_HAVE_SOCKETS)
	OFKernelEventObserver *_kernelEventObserver;
	OFMutableDictionary *_readQueues;
#elif defined(OF_HAVE_THREADS)
	OFCondition *_condition;
#endif
	volatile bool _running;
}

/*!
 * @brief Returns the main run loop.
 *
 * @return The main run loop
 */







|







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 _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
- (void)addTimer: (OFTimer*)timer;

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








/*!
 * @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







>
>
>
>
>
>
>








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
	} else
		assert(0);
}
#endif

- (void)run
{


	_running = true;




	for (;;) {
		void *pool;
		OFDate *now;
		OFTimer *timer;
		OFDate *nextTimer;

		if (!_running)
			break;

		pool = objc_autoreleasePoolPush();
		now = [OFDate date];

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

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

				[_timersQueue removeListObject: listObject];


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

		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 (timeout > 0) {


#if defined(OF_HAVE_SOCKETS)
				[_kernelEventObserver
				    observeForTimeInterval: timeout];
#elif defined(OF_HAVE_THREADS)
				[_condition lock];
				[_condition waitForTimeInterval: timeout];
				[_condition unlock];
#else
				[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.
			 */
#if defined(OF_HAVE_SOCKETS)
			[_kernelEventObserver observe];
#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition wait];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: 86400];
#endif
		}






		objc_autoreleasePoolPop(pool);
	}
}

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







>
>
|
>
|
>
>

|
|
<


|
<
|
<
<


|
|

|
|

|
|
|
|
|

|
>

|
|
|

|
|
|


|
|
>













|
|
>
>
|
>
>
>
>
>

|
>
>

|
|

|
|
|

|

<


|
|
|











>
>
>
>
>







|









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];
}

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

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

		OFDate *nextTimer;

		for (;;) {

			OFTimer *timer;



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

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

					[_timersQueue removeListObject:
					    listObject];

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

			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 || 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)
				timeout = 0;

#if defined(OF_HAVE_SOCKETS)
			[_kernelEventObserver
			    observeForTimeInterval: timeout];
#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition waitForTimeInterval: timeout];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: timeout];
#endif

		} else {
			/*
			 * 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
{
	_stop = true;
#if defined(OF_HAVE_SOCKETS)
	[_kernelEventObserver cancel];
#elif defined(OF_HAVE_THREADS)
	[_condition lock];
	[_condition signal];
	[_condition unlock];
#endif
}
@end