ObjFW  Check-in [7fa1dc3f95]

Overview
Comment:OFTimer: Reschedule before executing the callback

This makes sure that a repeating timer which e.g. needs half a second to
execute, but has an interval of 1 second, is indeed called every second
and not every 1.5 seconds.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7fa1dc3f950030911fbf159e7000a29b331b1a2c6e66584a9e71763b4876c57f
User & Date: js on 2014-07-23 23:23:14
Other Links: manifest | tags
Context
2014-07-24
18:02
Warn if configure.ac is newer than configure check-in: 0ab38200a3 user: js tags: trunk
2014-07-23
23:23
OFTimer: Reschedule before executing the callback check-in: 7fa1dc3f95 user: js tags: trunk
23:09
threading: Prevent possible division by zero check-in: 90f2f05c2c user: js tags: trunk
Changes

Modified src/OFTimer.m from [3ae679cd77] to [775d16e831].

350
351
352
353
354
355
356





357










358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
	timer = (OFTimer*)object;

	return [_fireDate compare: timer->_fireDate];
}

- (void)fire
{





	OF_ENSURE(_arguments <= 2);











#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif
		switch (_arguments) {
		case 0:
			[_target performSelector: _selector];
			break;
		case 1:
			[_target performSelector: _selector
				      withObject: _object1];
			break;
		case 2:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

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

	if (_repeats && _valid) {
		OFDate *old = _fireDate;
		_fireDate = [[OFDate alloc]
		    initWithTimeIntervalSinceNow: _interval];
		[old release];

		[[OFRunLoop currentRunLoop] addTimer: self];
	} else
		[self invalidate];
}

- (OFDate*)fireDate
{
	OF_GETTER(_fireDate, true)
}








>
>
>
>
>

>
>
>
>
>
>
>
>
>
>








|


|
|


|
|
|
















<
<
<
<
<
|
<
<
<







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406





407



408
409
410
411
412
413
414
	timer = (OFTimer*)object;

	return [_fireDate compare: timer->_fireDate];
}

- (void)fire
{
	void *pool = objc_autoreleasePoolPush();
	id target = [[_target retain] autorelease];
	id object1 = [[_object1 retain] autorelease];
	id object2 = [[_object2 retain] autorelease];

	OF_ENSURE(_arguments <= 2);

	if (_repeats && _valid) {
		OFDate *old = _fireDate;
		_fireDate = [[OFDate alloc]
		    initWithTimeIntervalSinceNow: _interval];
		[old release];

		[[OFRunLoop currentRunLoop] addTimer: self];
	} else
		[self invalidate];

#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif
		switch (_arguments) {
		case 0:
			[target performSelector: _selector];
			break;
		case 1:
			[target performSelector: _selector
				     withObject: object1];
			break;
		case 2:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

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






	objc_autoreleasePoolPop(pool);



}

- (OFDate*)fireDate
{
	OF_GETTER(_fireDate, true)
}

427
428
429
430
431
432
433


434


435
436
437
438
439
440
441
}

- (void)invalidate
{
	_valid = false;

	[_target release];


	_target = nil;


}

- (bool)isValid
{
	return _valid;
}








>
>

>
>







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
}

- (void)invalidate
{
	_valid = false;

	[_target release];
	[_object1 release];
	[_object2 release];
	_target = nil;
	_object1 = nil;
	_object2 = nil;
}

- (bool)isValid
{
	return _valid;
}