ObjFW  Diff

Differences From Artifact [6b846b58a6]:

To Artifact [51c5bb3274]:


1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


20
21
22
23
24
25
26

-
+

















-
-







/*
 * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>
 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <stdlib.h>

#include <assert.h>

#import "OFTimer.h"
#import "OFTimer+Private.h"
#import "OFDate.h"
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#ifdef OF_HAVE_THREADS
# import "OFCondition.h"
483
484
485
486
487
488
489
490
491


492
493
494
495
496
497
498
481
482
483
484
485
486
487


488
489
490
491
492
493
494
495
496







-
-
+
+








- (void)dealloc
{
	/*
	 * The run loop references the timer, so it should never be deallocated
	 * if it is still in a run loop.
	 */
	assert(_inRunLoop == nil);
	assert(_inRunLoopMode == nil);
	OFAssert(_inRunLoop == nil);
	OFAssert(_inRunLoopMode == nil);

	[_fireDate release];
	[_target release];
	[_object1 release];
	[_object2 release];
	[_object3 release];
	[_object4 release];
521
522
523
524
525
526
527
528
529

530
531
532
533



534
535
536
537
538


539
540
541
542

543
544
545
546
547
548



549
550
551


552
553
554
555




556
557
558
559
560










561
562
563
564
565
566
567
568
569

570
571
572


573
574
575
576
577



578
579
580
581
582
583




584
585
586
587
588
589
590





591
592
593
594
595
596



597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
519
520
521
522
523
524
525
526

527
528



529
530
531



532

533
534
535



536


537



538
539
540
541


542
543
544



545
546
547
548
549




550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570

571
572
573
574



575
576
577
578
579




580
581
582
583
584
585





586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608


609
610
611
612
613
614
615








-
+

-
-
-
+
+
+
-
-
-

-
+
+

-
-
-
+
-
-

-
-
-
+
+
+

-
-
+
+

-
-
-
+
+
+
+

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








-
+


-
+
+


-
-
-
+
+
+


-
-
-
-
+
+
+
+


-
-
-
-
-
+
+
+
+
+






+
+
+









-
-








	_inRunLoop = [runLoop retain];
	[oldInRunLoop release];

	_inRunLoopMode = [mode copy];
	[oldInRunLoopMode release];
}

- (void)fire
- (void)of_reschedule
{
	void *pool = objc_autoreleasePoolPush();
	id target = [[_target retain] autorelease];
	id object1 = [[_object1 retain] autorelease];
	long long missedIntervals;
	OFTimeInterval newFireDate;
	OFRunLoop *runLoop;
	id object2 = [[_object2 retain] autorelease];
	id object3 = [[_object3 retain] autorelease];
	id object4 = [[_object4 retain] autorelease];

	OFEnsure(_arguments <= 4);
	if (!_repeats || !_valid)
		return;

	if (_repeats && _valid) {
		int64_t missedIntervals =
		    -_fireDate.timeIntervalSinceNow / _interval;
	missedIntervals = -_fireDate.timeIntervalSinceNow / _interval;
		OFTimeInterval newFireDate;
		OFRunLoop *runLoop;

		/* In case the clock was changed backwards */
		if (missedIntervals < 0)
			missedIntervals = 0;
	/* In case the clock was changed backwards */
	if (missedIntervals < 0)
		missedIntervals = 0;

		newFireDate = _fireDate.timeIntervalSince1970 +
		    (missedIntervals + 1) * _interval;
	newFireDate = _fireDate.timeIntervalSince1970 +
	    (missedIntervals + 1) * _interval;

		[_fireDate release];
		_fireDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970: newFireDate];
	[_fireDate release];
	_fireDate = nil;
	_fireDate = [[OFDate alloc]
	    initWithTimeIntervalSince1970: newFireDate];

		runLoop = [OFRunLoop currentRunLoop];
		[runLoop addTimer: self forMode: runLoop.currentMode];
	} else
		[self invalidate];
	runLoop = [OFRunLoop currentRunLoop];
	[runLoop addTimer: self forMode: runLoop.currentMode];
}

- (void)fire
{
	OFEnsure(_arguments <= 4);

	if (!_valid)
		return;

#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif
		switch (_arguments) {
		case 0:
			[target performSelector: _selector];
			[_target performSelector: _selector];
			break;
		case 1:
			[target performSelector: _selector withObject: object1];
			[_target performSelector: _selector
				      withObject: _object1];
			break;
		case 2:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2];
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2];
			break;
		case 3:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2
				     withObject: object3];
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2
				      withObject: _object3];
			break;
		case 4:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2
				     withObject: object3
				     withObject: object4];
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2
				      withObject: _object3
				      withObject: _object4];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

	if  (!_repeats)
		[self invalidate];

#ifdef OF_HAVE_THREADS
	[_condition lock];
	@try {
		_done = true;
		[_condition signal];
	} @finally {
		[_condition unlock];
	}
#endif

	objc_autoreleasePoolPop(pool);
}

- (OFDate *)fireDate
{
	return _fireDate;
}

633
634
635
636
637
638
639



640
641
642
643
644
645
646
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650







+
+
+







	}
}

- (void)invalidate
{
	_valid = false;

#ifdef OF_HAVE_BLOCKS
	[_block release];
#endif
	[_target release];
	[_object1 release];
	[_object2 release];
	[_object3 release];
	[_object4 release];

	_target = nil;