ObjFW  Check-in [8c0d76f782]

Overview
Comment:of_time_interval_t -> OFTimeInterval
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | new-naming-convention
Files: files | file ages | folders
SHA3-256: 8c0d76f7824d4357563c8ddc3a13fb8c7fc8f0705eb3a7cf0255528ccaa60ff1
User & Date: js on 2021-04-17 00:51:42
Other Links: branch diff | manifest | tags
Context
2021-04-17
00:54
of_point_t -> OFPoint check-in: 3524409dd0 user: js tags: new-naming-convention
00:51
of_time_interval_t -> OFTimeInterval check-in: 8c0d76f782 user: js tags: new-naming-convention
00:44
of_range_t -> OFRange check-in: d975c53a43 user: js tags: new-naming-convention
Changes

Modified src/OFCondition.h from [7e6ce2a6b1] to [24d692e490].

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 *
 * @note Waiting might have been interrupted by a signal. It is thus recommended
 *	 to check the condition again after @ref waitForTimeInterval: returned!
 *
 * @param timeInterval The time interval until the timeout is reached
 * @return Whether the condition has been signaled
 */
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval;

#ifdef OF_AMIGAOS
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast, the timeout is reached or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param timeInterval The time interval until the timeout is reached
 * @param signalMask A pointer to a signal mask of Exec Signals to receive.
 *		     This is modified and set to the mask of signals received.
 * @return Whether the condition has been signaled or a signal received
 */
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
	       orExecSignal: (ULONG *)signalMask;
#endif

/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast or the timeout is reached.
 *







|













|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 *
 * @note Waiting might have been interrupted by a signal. It is thus recommended
 *	 to check the condition again after @ref waitForTimeInterval: returned!
 *
 * @param timeInterval The time interval until the timeout is reached
 * @return Whether the condition has been signaled
 */
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval;

#ifdef OF_AMIGAOS
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast, the timeout is reached or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param timeInterval The time interval until the timeout is reached
 * @param signalMask A pointer to a signal mask of Exec Signals to receive.
 *		     This is modified and set to the mask of signals received.
 * @return Whether the condition has been signaled or a signal received
 */
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval
	       orExecSignal: (ULONG *)signalMask;
#endif

/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast or the timeout is reached.
 *

Modified src/OFCondition.m from [a2bba1aee6] to [4b58a9908d].

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];
}
#endif

- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
{
	int error = of_condition_timed_wait(&_condition, &_mutex, timeInterval);

	if (error == ETIMEDOUT)
		return false;

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];

	return true;
}

#ifdef OF_AMIGAOS
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
	       orExecSignal: (ULONG *)signalMask
{
	int error = of_condition_timed_wait_or_signal(&_condition, &_mutex,
	    timeInterval, signalMask);

	if (error == ETIMEDOUT)
		return false;







|















|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];
}
#endif

- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval
{
	int error = of_condition_timed_wait(&_condition, &_mutex, timeInterval);

	if (error == ETIMEDOUT)
		return false;

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];

	return true;
}

#ifdef OF_AMIGAOS
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval
	       orExecSignal: (ULONG *)signalMask
{
	int error = of_condition_timed_wait_or_signal(&_condition, &_mutex,
	    timeInterval, signalMask);

	if (error == ETIMEDOUT)
		return false;

Modified src/OFDNSResolver.h from [c467730d8f] to [3856863be9].

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 */
@property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains;

/**
 * @brief The timeout, in seconds, after which the next name server should be
 *	  tried.
 */
@property (nonatomic) of_time_interval_t timeout;

/**
 * @brief The number of attempts before giving up to resolve a host.
 *
 * Trying all name servers once is considered a single attempt.
 */
@property (nonatomic) unsigned int maxAttempts;







|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 */
@property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains;

/**
 * @brief The timeout, in seconds, after which the next name server should be
 *	  tried.
 */
@property (nonatomic) OFTimeInterval timeout;

/**
 * @brief The number of attempts before giving up to resolve a host.
 *
 * Trying all name servers once is considered a single attempt.
 */
@property (nonatomic) unsigned int maxAttempts;
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
@property (nonatomic) bool usesTCP;

/**
 * @brief The interval in seconds in which the config should be reloaded.
 *
 * Setting this to 0 disables config reloading.
 */
@property (nonatomic) of_time_interval_t configReloadInterval;

/**
 * @brief Creates a new, autoreleased OFDNSResolver.
 */
+ (instancetype)resolver;

/**







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
@property (nonatomic) bool usesTCP;

/**
 * @brief The interval in seconds in which the config should be reloaded.
 *
 * Setting this to 0 disables config reloading.
 */
@property (nonatomic) OFTimeInterval configReloadInterval;

/**
 * @brief Creates a new, autoreleased OFDNSResolver.
 */
+ (instancetype)resolver;

/**

Modified src/OFDNSResolver.m from [536c83ec11] to [082cdf22b7].

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
- (void)setSearchDomains: (OFArray *)searchDomains
{
	OFArray *old = _settings->_searchDomains;
	_settings->_searchDomains = [searchDomains copy];
	[old release];
}

- (of_time_interval_t)timeout
{
	return _settings->_timeout;
}

- (void)setTimeout: (of_time_interval_t)timeout
{
	_settings->_timeout = timeout;
}

- (unsigned int)maxAttempts
{
	return _settings->_maxAttempts;







|




|







643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
- (void)setSearchDomains: (OFArray *)searchDomains
{
	OFArray *old = _settings->_searchDomains;
	_settings->_searchDomains = [searchDomains copy];
	[old release];
}

- (OFTimeInterval)timeout
{
	return _settings->_timeout;
}

- (void)setTimeout: (OFTimeInterval)timeout
{
	_settings->_timeout = timeout;
}

- (unsigned int)maxAttempts
{
	return _settings->_maxAttempts;
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
}

- (void)setUsesTCP: (bool)usesTCP
{
	_settings->_usesTCP = usesTCP;
}

- (of_time_interval_t)configReloadInterval
{
	return _settings->_configReloadInterval;
}

- (void)setConfigReloadInterval: (of_time_interval_t)configReloadInterval
{
	_settings->_configReloadInterval = configReloadInterval;
}

- (void)of_sendQueryForContext: (OFDNSResolverContext *)context
		   runLoopMode: (of_run_loop_mode_t)runLoopMode
{







|




|







685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
}

- (void)setUsesTCP: (bool)usesTCP
{
	_settings->_usesTCP = usesTCP;
}

- (OFTimeInterval)configReloadInterval
{
	return _settings->_configReloadInterval;
}

- (void)setConfigReloadInterval: (OFTimeInterval)configReloadInterval
{
	_settings->_configReloadInterval = configReloadInterval;
}

- (void)of_sendQueryForContext: (OFDNSResolverContext *)context
		   runLoopMode: (of_run_loop_mode_t)runLoopMode
{

Modified src/OFDNSResolverSettings.h from [f96b5d98db] to [e160ff7316].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
@public
	OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC(OFString *) *)
	    *_staticHosts;
	OFArray OF_GENERIC(OFString *) *_nameServers;
	OFString *_Nullable _localDomain;
	OFArray OF_GENERIC(OFString *) *_searchDomains;
	of_time_interval_t _timeout;
	unsigned int _maxAttempts, _minNumberOfDotsInAbsoluteName;
	bool _usesTCP;
	of_time_interval_t _configReloadInterval;
@protected
	OFDate *_lastConfigReload;
}

- (void)reload;
@end








|


|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
@public
	OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC(OFString *) *)
	    *_staticHosts;
	OFArray OF_GENERIC(OFString *) *_nameServers;
	OFString *_Nullable _localDomain;
	OFArray OF_GENERIC(OFString *) *_searchDomains;
	OFTimeInterval _timeout;
	unsigned int _maxAttempts, _minNumberOfDotsInAbsoluteName;
	bool _usesTCP;
	OFTimeInterval _configReloadInterval;
@protected
	OFDate *_lastConfigReload;
}

- (void)reload;
@end

Modified src/OFDate.h from [c0507d8eee] to [67980cebbc].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 */
#ifndef OF_DATE_M
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization,
    OFMessagePackRepresentation>
{
	of_time_interval_t _seconds;
}

#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFDate *distantFuture;
@property (class, readonly, nonatomic) OFDate *distantPast;
#endif








|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 */
#ifndef OF_DATE_M
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization,
    OFMessagePackRepresentation>
{
	OFTimeInterval _seconds;
}

#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFDate *distantFuture;
@property (class, readonly, nonatomic) OFDate *distantPast;
#endif

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 * @brief The day of the year of the date in local time.
 */
@property (readonly, nonatomic) unsigned short localDayOfYear;

/**
 * @brief The seconds since 1970-01-01T00:00:00Z.
 */
@property (readonly, nonatomic) of_time_interval_t timeIntervalSince1970;

/**
 * @brief The seconds the date is in the future.
 */
@property (readonly, nonatomic) of_time_interval_t timeIntervalSinceNow;

/**
 * @brief Creates a new OFDate with the current date and time.
 *
 * @return A new, autoreleased OFDate with the current date and time
 */
+ (instancetype)date;

/**
 * @brief Creates a new OFDate with the specified date and time since
 *	  1970-01-01T00:00:00Z.
 *
 * @param seconds The seconds since 1970-01-01T00:00:00Z
 * @return A new, autoreleased OFDate with the specified date and time
 */
+ (instancetype)dateWithTimeIntervalSince1970: (of_time_interval_t)seconds;

/**
 * @brief Creates a new OFDate with the specified date and time since now.
 *
 * @param seconds The seconds since now
 * @return A new, autoreleased OFDate with the specified date and time
 */
+ (instancetype)dateWithTimeIntervalSinceNow: (of_time_interval_t)seconds;

/**
 * @brief Creates a new OFDate with the specified string in the specified
 *	  format.
 *
 * The time zone used is UTC. See @ref dateWithLocalDateString:format: if you
 * want local time.







|




|















|







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 * @brief The day of the year of the date in local time.
 */
@property (readonly, nonatomic) unsigned short localDayOfYear;

/**
 * @brief The seconds since 1970-01-01T00:00:00Z.
 */
@property (readonly, nonatomic) OFTimeInterval timeIntervalSince1970;

/**
 * @brief The seconds the date is in the future.
 */
@property (readonly, nonatomic) OFTimeInterval timeIntervalSinceNow;

/**
 * @brief Creates a new OFDate with the current date and time.
 *
 * @return A new, autoreleased OFDate with the current date and time
 */
+ (instancetype)date;

/**
 * @brief Creates a new OFDate with the specified date and time since
 *	  1970-01-01T00:00:00Z.
 *
 * @param seconds The seconds since 1970-01-01T00:00:00Z
 * @return A new, autoreleased OFDate with the specified date and time
 */
+ (instancetype)dateWithTimeIntervalSince1970: (OFTimeInterval)seconds;

/**
 * @brief Creates a new OFDate with the specified date and time since now.
 *
 * @param seconds The seconds since now
 * @return A new, autoreleased OFDate with the specified date and time
 */
+ (instancetype)dateWithTimeIntervalSinceNow: (OFTimeInterval)seconds;

/**
 * @brief Creates a new OFDate with the specified string in the specified
 *	  format.
 *
 * The time zone used is UTC. See @ref dateWithLocalDateString:format: if you
 * want local time.
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/**
 * @brief Initializes an already allocated OFDate with the specified date and
 *	  time since 1970-01-01T00:00:00Z.
 *
 * @param seconds The seconds since 1970-01-01T00:00:00Z
 * @return An initialized OFDate with the specified date and time
 */
- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds
    OF_DESIGNATED_INITIALIZER;

/**
 * @brief Initializes an already allocated OFDate with the specified date and
 *	  time since now.
 *
 * @param seconds The seconds since now
 * @return An initialized OFDate with the specified date and time
 */
- (instancetype)initWithTimeIntervalSinceNow: (of_time_interval_t)seconds;

/**
 * @brief Initializes an already allocated OFDate with the specified string in
 *	  the specified format.
 *
 * The time zone used is UTC. If a time zone is specified anyway, an
 * OFInvalidFormatException is thrown. See @ref initWithLocalDateString:format:







|









|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/**
 * @brief Initializes an already allocated OFDate with the specified date and
 *	  time since 1970-01-01T00:00:00Z.
 *
 * @param seconds The seconds since 1970-01-01T00:00:00Z
 * @return An initialized OFDate with the specified date and time
 */
- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
    OF_DESIGNATED_INITIALIZER;

/**
 * @brief Initializes an already allocated OFDate with the specified date and
 *	  time since now.
 *
 * @param seconds The seconds since now
 * @return An initialized OFDate with the specified date and time
 */
- (instancetype)initWithTimeIntervalSinceNow: (OFTimeInterval)seconds;

/**
 * @brief Initializes an already allocated OFDate with the specified string in
 *	  the specified format.
 *
 * The time zone used is UTC. If a time zone is specified anyway, an
 * OFInvalidFormatException is thrown. See @ref initWithLocalDateString:format:
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

/**
 * @brief Returns the seconds the receiver is after the date.
 *
 * @param otherDate Date date to generate the difference with receiver
 * @return The seconds the receiver is after the date.
 */
- (of_time_interval_t)timeIntervalSinceDate: (OFDate *)otherDate;

/**
 * @brief Creates a new date with the specified time interval added.
 *
 * @param seconds The seconds after the date
 * @return A new, autoreleased OFDate
 */
- (OFDate *)dateByAddingTimeInterval: (of_time_interval_t)seconds;
@end

OF_ASSUME_NONNULL_END







|







|



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

/**
 * @brief Returns the seconds the receiver is after the date.
 *
 * @param otherDate Date date to generate the difference with receiver
 * @return The seconds the receiver is after the date.
 */
- (OFTimeInterval)timeIntervalSinceDate: (OFDate *)otherDate;

/**
 * @brief Creates a new date with the specified time interval added.
 *
 * @param seconds The seconds after the date
 * @return A new, autoreleased OFDate
 */
- (OFDate *)dateByAddingTimeInterval: (OFTimeInterval)seconds;
@end

OF_ASSUME_NONNULL_END

Modified src/OFDate.m from [40096ae6a3] to [5b10481bac].

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
static void
initDistantPast(void)
{
	distantPast = [[OFDateSingleton alloc]
	    initWithTimeIntervalSince1970: -62167219200.0];
}

static of_time_interval_t
now(void)
{
	struct timeval tv;
	of_time_interval_t seconds;

	OF_ENSURE(gettimeofday(&tv, NULL) == 0);

	seconds = tv.tv_sec;
	seconds += (of_time_interval_t)tv.tv_usec / 1000000;

	return seconds;
}

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
static OFMutex *mutex;







|



|




|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
static void
initDistantPast(void)
{
	distantPast = [[OFDateSingleton alloc]
	    initWithTimeIntervalSince1970: -62167219200.0];
}

static OFTimeInterval
now(void)
{
	struct timeval tv;
	OFTimeInterval seconds;

	OF_ENSURE(gettimeofday(&tv, NULL) == 0);

	seconds = tv.tv_sec;
	seconds += (OFTimeInterval)tv.tv_usec / 1000000;

	return seconds;
}

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
static OFMutex *mutex;
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

#ifdef OF_WINDOWS
static __time64_t (*func__mktime64)(struct tm *);
#endif

#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field)						\
	of_time_interval_t timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if (gmtime_r(&seconds, &tm) == NULL)				\
		@throw [OFOutOfRangeException exception];		\
									\
	return tm.field;
# define LOCALTIME_RET(field)						\
	of_time_interval_t timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if (localtime_r(&seconds, &tm) == NULL)				\
		@throw [OFOutOfRangeException exception];		\
									\
	return tm.field;
#else
# ifdef OF_HAVE_THREADS
#  define GMTIME_RET(field)						\
	of_time_interval_t timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	[mutex lock];							\
									\
	@try {								\
		if ((tm = gmtime(&seconds)) == NULL)			\
			@throw [OFOutOfRangeException exception];	\
									\
		return tm->field;					\
	} @finally {							\
		[mutex unlock];						\
	}
#  define LOCALTIME_RET(field)						\
	of_time_interval_t timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	[mutex lock];							\
									\
	@try {								\
		if ((tm = localtime(&seconds)) == NULL)			\
			@throw [OFOutOfRangeException exception];	\
									\
		return tm->field;					\
	} @finally {							\
		[mutex unlock];						\
	}
# else
#  define GMTIME_RET(field)						\
	of_time_interval_t timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if ((tm = gmtime(&seconds)) == NULL)				\
		@throw [OFOutOfRangeException exception];		\
									\
	return tm->field;
#  define LOCALTIME_RET(field)						\
	of_time_interval_t timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if ((tm = localtime(&seconds)) == NULL)				\







|











|













|

















|


















|











|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

#ifdef OF_WINDOWS
static __time64_t (*func__mktime64)(struct tm *);
#endif

#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field)						\
	OFTimeInterval timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if (gmtime_r(&seconds, &tm) == NULL)				\
		@throw [OFOutOfRangeException exception];		\
									\
	return tm.field;
# define LOCALTIME_RET(field)						\
	OFTimeInterval timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if (localtime_r(&seconds, &tm) == NULL)				\
		@throw [OFOutOfRangeException exception];		\
									\
	return tm.field;
#else
# ifdef OF_HAVE_THREADS
#  define GMTIME_RET(field)						\
	OFTimeInterval timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	[mutex lock];							\
									\
	@try {								\
		if ((tm = gmtime(&seconds)) == NULL)			\
			@throw [OFOutOfRangeException exception];	\
									\
		return tm->field;					\
	} @finally {							\
		[mutex unlock];						\
	}
#  define LOCALTIME_RET(field)						\
	OFTimeInterval timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	[mutex lock];							\
									\
	@try {								\
		if ((tm = localtime(&seconds)) == NULL)			\
			@throw [OFOutOfRangeException exception];	\
									\
		return tm->field;					\
	} @finally {							\
		[mutex unlock];						\
	}
# else
#  define GMTIME_RET(field)						\
	OFTimeInterval timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if ((tm = gmtime(&seconds)) == NULL)				\
		@throw [OFOutOfRangeException exception];		\
									\
	return tm->field;
#  define LOCALTIME_RET(field)						\
	OFTimeInterval timeInterval = self.timeIntervalSince1970;	\
	time_t seconds = (time_t)timeInterval;				\
	struct tm *tm;							\
									\
	if (seconds != trunc(timeInterval))				\
		@throw [OFOutOfRangeException exception];		\
									\
	if ((tm = localtime(&seconds)) == NULL)				\
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
@implementation OFDatePlaceholder
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
#endif
- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds
{
#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	uint64_t value;
#endif

	if (seconds == 0) {
		static of_once_t once = OF_ONCE_INIT;







|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
@implementation OFDatePlaceholder
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
#endif
- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
{
#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	uint64_t value;
#endif

	if (seconds == 0) {
		static of_once_t once = OF_ONCE_INIT;
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#ifdef __clang__
# pragma clang diagnostic pop
#endif
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@implementation OFTaggedPointerDate
- (of_time_interval_t)timeIntervalSince1970
{
	uint64_t value = (uint64_t)object_getTaggedPointerValue(self);

	value |= UINT64_C(4) << 60;

	return OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
	    value)));







|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#ifdef __clang__
# pragma clang diagnostic pop
#endif
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@implementation OFTaggedPointerDate
- (OFTimeInterval)timeIntervalSince1970
{
	uint64_t value = (uint64_t)object_getTaggedPointerValue(self);

	value |= UINT64_C(4) << 60;

	return OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
	    value)));
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
}

+ (instancetype)date
{
	return [[[self alloc] init] autorelease];
}

+ (instancetype)dateWithTimeIntervalSince1970: (of_time_interval_t)seconds
{
	return [[[self alloc]
	    initWithTimeIntervalSince1970: seconds] autorelease];
}

+ (instancetype)dateWithTimeIntervalSinceNow: (of_time_interval_t)seconds
{
	return [[[self alloc]
	    initWithTimeIntervalSinceNow: seconds] autorelease];
}

+ (instancetype)dateWithDateString: (OFString *)string
			    format: (OFString *)format







|





|







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
}

+ (instancetype)date
{
	return [[[self alloc] init] autorelease];
}

+ (instancetype)dateWithTimeIntervalSince1970: (OFTimeInterval)seconds
{
	return [[[self alloc]
	    initWithTimeIntervalSince1970: seconds] autorelease];
}

+ (instancetype)dateWithTimeIntervalSinceNow: (OFTimeInterval)seconds
{
	return [[[self alloc]
	    initWithTimeIntervalSinceNow: seconds] autorelease];
}

+ (instancetype)dateWithDateString: (OFString *)string
			    format: (OFString *)format
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
}

- (instancetype)init
{
	return [self initWithTimeIntervalSince1970: now()];
}

- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds
{
	self = [super init];

	_seconds = seconds;

	return self;
}

- (instancetype)initWithTimeIntervalSinceNow: (of_time_interval_t)seconds
{
	return [self initWithTimeIntervalSince1970: now() + seconds];
}

- (instancetype)initWithDateString: (OFString *)string
			    format: (OFString *)format
{







|








|







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
}

- (instancetype)init
{
	return [self initWithTimeIntervalSince1970: now()];
}

- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
{
	self = [super init];

	_seconds = seconds;

	return self;
}

- (instancetype)initWithTimeIntervalSinceNow: (OFTimeInterval)seconds
{
	return [self initWithTimeIntervalSince1970: now() + seconds];
}

- (instancetype)initWithDateString: (OFString *)string
			    format: (OFString *)format
{
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
	struct tm tm = { .tm_isdst = -1 };
	/*
	 * of_strptime() can never set this to SHRT_MAX, no matter what is
	 * passed to it, so this is a safe way to figure out if the date
	 * contains a time zone.
	 */
	short tz = SHRT_MAX;
	of_time_interval_t seconds;

	if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) !=
	    UTF8String + string.UTF8StringLength)
		@throw [OFInvalidFormatException exception];

	if (tz == SHRT_MAX) {
#ifdef OF_WINDOWS







|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
	struct tm tm = { .tm_isdst = -1 };
	/*
	 * of_strptime() can never set this to SHRT_MAX, no matter what is
	 * passed to it, so this is a safe way to figure out if the date
	 * contains a time zone.
	 */
	short tz = SHRT_MAX;
	OFTimeInterval seconds;

	if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) !=
	    UTF8String + string.UTF8StringLength)
		@throw [OFInvalidFormatException exception];

	if (tz == SHRT_MAX) {
#ifdef OF_WINDOWS
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
	objc_autoreleasePoolPop(pool);

	return [self initWithTimeIntervalSince1970: seconds];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	of_time_interval_t seconds;

	@try {
		void *pool = objc_autoreleasePoolPush();
		unsigned long long value;

		if (![element.name isEqual: @"OFDate"] ||
		    ![element.namespace isEqual: OF_SERIALIZATION_NS])







|







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
	objc_autoreleasePoolPop(pool);

	return [self initWithTimeIntervalSince1970: seconds];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	OFTimeInterval seconds;

	@try {
		void *pool = objc_autoreleasePoolPush();
		unsigned long long value;

		if (![element.name isEqual: @"OFDate"] ||
		    ![element.namespace isEqual: OF_SERIALIZATION_NS])
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615

	return [element autorelease];
}

- (OFData *)messagePackRepresentation
{
	void *pool = objc_autoreleasePoolPush();
	of_time_interval_t timeInterval = self.timeIntervalSince1970;
	int64_t seconds = (int64_t)timeInterval;
	uint32_t nanoseconds =
	    (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000000);
	OFData *ret;

	if (seconds >= 0 && seconds < 0x400000000) {
		if (seconds <= UINT32_MAX && nanoseconds == 0) {







|







601
602
603
604
605
606
607
608
609
610
611
612
613
614
615

	return [element autorelease];
}

- (OFData *)messagePackRepresentation
{
	void *pool = objc_autoreleasePoolPush();
	OFTimeInterval timeInterval = self.timeIntervalSince1970;
	int64_t seconds = (int64_t)timeInterval;
	uint32_t nanoseconds =
	    (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000000);
	OFData *ret;

	if (seconds >= 0 && seconds < 0x400000000) {
		if (seconds <= UINT32_MAX && nanoseconds == 0) {
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (unsigned long)microsecond
{
	of_time_interval_t timeInterval = self.timeIntervalSince1970;

	return (unsigned long)((timeInterval - trunc(timeInterval)) * 1000000);
}

- (unsigned char)second
{
	GMTIME_RET(tm_sec)







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (unsigned long)microsecond
{
	OFTimeInterval timeInterval = self.timeIntervalSince1970;

	return (unsigned long)((timeInterval - trunc(timeInterval)) * 1000000);
}

- (unsigned char)second
{
	GMTIME_RET(tm_sec)
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
{
	LOCALTIME_RET(tm_yday + 1)
}

- (OFString *)dateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
	of_time_interval_t timeInterval = self.timeIntervalSince1970;
	time_t seconds = (time_t)timeInterval;
	struct tm tm;
	size_t pageSize;
#ifndef OF_WINDOWS
	char *buffer;
#else
	wchar_t *buffer;







|







737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
{
	LOCALTIME_RET(tm_yday + 1)
}

- (OFString *)dateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
	OFTimeInterval timeInterval = self.timeIntervalSince1970;
	time_t seconds = (time_t)timeInterval;
	struct tm tm;
	size_t pageSize;
#ifndef OF_WINDOWS
	char *buffer;
#else
	wchar_t *buffer;
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

	return ret;
}

- (OFString *)localDateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
	of_time_interval_t timeInterval = self.timeIntervalSince1970;
	time_t seconds = (time_t)timeInterval;
	struct tm tm;
	size_t pageSize;
#ifndef OF_WINDOWS
	char *buffer;
#else
	wchar_t *buffer;







|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

	return ret;
}

- (OFString *)localDateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
	OFTimeInterval timeInterval = self.timeIntervalSince1970;
	time_t seconds = (time_t)timeInterval;
	struct tm tm;
	size_t pageSize;
#ifndef OF_WINDOWS
	char *buffer;
#else
	wchar_t *buffer;
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

	if ([self compare: otherDate] == OFOrderedAscending)
		return otherDate;

	return self;
}

- (of_time_interval_t)timeIntervalSince1970
{
	return _seconds;
}

- (of_time_interval_t)timeIntervalSinceDate: (OFDate *)otherDate
{
	return self.timeIntervalSince1970 - otherDate.timeIntervalSince1970;
}

- (of_time_interval_t)timeIntervalSinceNow
{
	struct timeval t;
	of_time_interval_t seconds;

	OF_ENSURE(gettimeofday(&t, NULL) == 0);

	seconds = t.tv_sec;
	seconds += (of_time_interval_t)t.tv_usec / 1000000;

	return self.timeIntervalSince1970 - seconds;
}

- (OFDate *)dateByAddingTimeInterval: (of_time_interval_t)seconds
{
	return [OFDate dateWithTimeIntervalSince1970:
	    self.timeIntervalSince1970 + seconds];
}
@end







|




|




|


|




|




|





876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

	if ([self compare: otherDate] == OFOrderedAscending)
		return otherDate;

	return self;
}

- (OFTimeInterval)timeIntervalSince1970
{
	return _seconds;
}

- (OFTimeInterval)timeIntervalSinceDate: (OFDate *)otherDate
{
	return self.timeIntervalSince1970 - otherDate.timeIntervalSince1970;
}

- (OFTimeInterval)timeIntervalSinceNow
{
	struct timeval t;
	OFTimeInterval seconds;

	OF_ENSURE(gettimeofday(&t, NULL) == 0);

	seconds = t.tv_sec;
	seconds += (OFTimeInterval)t.tv_usec / 1000000;

	return self.timeIntervalSince1970 - seconds;
}

- (OFDate *)dateByAddingTimeInterval: (OFTimeInterval)seconds
{
	return [OFDate dateWithTimeIntervalSince1970:
	    self.timeIntervalSince1970 + seconds];
}
@end

Modified src/OFEpollKernelEventObserver.m from [11ad156308] to [deb106197e].

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	[self of_removeObject: object
	       fileDescriptor: object.fileDescriptorForWriting
		       events: EPOLLOUT];

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	OFNull *nullObject = [OFNull null];
	struct epoll_event eventList[EVENTLIST_SIZE];
	int events;

	if ([self of_processReadBuffers])
		return;







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	[self of_removeObject: object
	       fileDescriptor: object.fileDescriptorForWriting
		       events: EPOLLOUT];

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (OFTimeInterval)timeInterval
{
	OFNull *nullObject = [OFNull null];
	struct epoll_event eventList[EVENTLIST_SIZE];
	int events;

	if ([self of_processReadBuffers])
		return;

Modified src/OFFileURLHandler.m from [db7a703dd2] to [26c778d535].

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# endif
#endif

#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
typedef struct {
	of_offset_t st_size;
	unsigned int st_mode;
	of_time_interval_t st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
#  define HAVE_STRUCT_STAT_ST_BIRTHTIME
	of_time_interval_t st_birthtime;
	DWORD fileAttributes;
# endif
} of_stat_t;
#elif defined(HAVE_STAT64)
typedef struct stat64 of_stat_t;
#else
typedef struct stat of_stat_t;







|


|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# endif
#endif

#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
typedef struct {
	of_offset_t st_size;
	unsigned int st_mode;
	OFTimeInterval st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
#  define HAVE_STRUCT_STAT_ST_BIRTHTIME
	OFTimeInterval st_birthtime;
	DWORD fileAttributes;
# endif
} of_stat_t;
#elif defined(HAVE_STAT64)
typedef struct stat64 of_stat_t;
#else
typedef struct stat of_stat_t;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
static int (*func__wutime64)(const wchar_t *, struct __utimbuf64 *);
static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD);
static WINAPI BOOLEAN (*func_CreateHardLinkW)(LPCWSTR, LPCWSTR,
    LPSECURITY_ATTRIBUTES);
#endif

#ifdef OF_WINDOWS
static of_time_interval_t
filetimeToTimeInterval(const FILETIME *filetime)
{
	return (double)((int64_t)filetime->dwHighDateTime << 32 |
	    filetime->dwLowDateTime) / 10000000.0 - 11644473600.0;
}

static int







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
static int (*func__wutime64)(const wchar_t *, struct __utimbuf64 *);
static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD);
static WINAPI BOOLEAN (*func_CreateHardLinkW)(LPCWSTR, LPCWSTR,
    LPSECURITY_ATTRIBUTES);
#endif

#ifdef OF_WINDOWS
static OFTimeInterval
filetimeToTimeInterval(const FILETIME *filetime)
{
	return (double)((int64_t)filetime->dwHighDateTime << 32 |
	    filetime->dwLowDateTime) / 10000000.0 - 11644473600.0;
}

static int
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#elif defined(OF_AMIGAOS)
	BPTR lock;
# ifdef OF_AMIGAOS4
	struct ExamineData *ed;
# else
	struct FileInfoBlock fib;
# endif
	of_time_interval_t timeInterval;
	struct Locale *locale;
	struct DateStamp *date;

	if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]],
	    SHARED_LOCK)) == 0)
		return retrieveError();








|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#elif defined(OF_AMIGAOS)
	BPTR lock;
# ifdef OF_AMIGAOS4
	struct ExamineData *ed;
# else
	struct FileInfoBlock fib;
# endif
	OFTimeInterval timeInterval;
	struct Locale *locale;
	struct DateStamp *date;

	if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]],
	    SHARED_LOCK)) == 0)
		return retrieveError();

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# ifdef OF_AMIGAOS4
	date = &ed->Date;
# else
	date = &fib.fib_Date;
# endif
	timeInterval += date->ds_Days * 86400.0;
	timeInterval += date->ds_Minute * 60.0;
	timeInterval += date->ds_Tick / (of_time_interval_t)TICKS_PER_SECOND;

	buffer->st_atime = buffer->st_mtime = buffer->st_ctime = timeInterval;

# ifdef OF_AMIGAOS4
	FreeDosObject(DOS_EXAMINEDATA, ed);
# endif








|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# ifdef OF_AMIGAOS4
	date = &ed->Date;
# else
	date = &fib.fib_Date;
# endif
	timeInterval += date->ds_Days * 86400.0;
	timeInterval += date->ds_Minute * 60.0;
	timeInterval += date->ds_Tick / (OFTimeInterval)TICKS_PER_SECOND;

	buffer->st_atime = buffer->st_mtime = buffer->st_ctime = timeInterval;

# ifdef OF_AMIGAOS4
	FreeDosObject(DOS_EXAMINEDATA, ed);
# endif

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
			    exceptionWithURL: URL
				  attributes: attributes
			     failedAttribute: attributeKey
				       errNo: errno];
	}
#elif defined(OF_AMIGAOS)
	/* AmigaOS does not support access time. */
	of_time_interval_t modificationTime =
	    modificationDate.timeIntervalSince1970;
	struct Locale *locale;
	struct DateStamp date;

	modificationTime -= 252460800;	/* 1978-01-01 */

	if (modificationTime < 0)







|







699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
			    exceptionWithURL: URL
				  attributes: attributes
			     failedAttribute: attributeKey
				       errNo: errno];
	}
#elif defined(OF_AMIGAOS)
	/* AmigaOS does not support access time. */
	OFTimeInterval modificationTime =
	    modificationDate.timeIntervalSince1970;
	struct Locale *locale;
	struct DateStamp date;

	modificationTime -= 252460800;	/* 1978-01-01 */

	if (modificationTime < 0)
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
# endif
		@throw [OFSetItemAttributesFailedException
		    exceptionWithURL: URL
			  attributes: attributes
		     failedAttribute: attributeKey
			       errNo: retrieveError()];
#else
	of_time_interval_t lastAccessTime =
	    lastAccessDate.timeIntervalSince1970;
	of_time_interval_t modificationTime =
	    modificationDate.timeIntervalSince1970;
	struct timeval times[2] = {
		{
			.tv_sec = (time_t)lastAccessTime,
			.tv_usec =
			    (int)((lastAccessTime - times[0].tv_sec) * 1000000)
		},







<
|
|







735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
# endif
		@throw [OFSetItemAttributesFailedException
		    exceptionWithURL: URL
			  attributes: attributes
		     failedAttribute: attributeKey
			       errNo: retrieveError()];
#else

	OFTimeInterval lastAccessTime = lastAccessDate.timeIntervalSince1970;
	OFTimeInterval modificationTime =
	    modificationDate.timeIntervalSince1970;
	struct timeval times[2] = {
		{
			.tv_sec = (time_t)lastAccessTime,
			.tv_usec =
			    (int)((lastAccessTime - times[0].tv_sec) * 1000000)
		},

Modified src/OFKernelEventObserver.h from [9a570d3d9f] to [3c8cfabf76].

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

/**
 * @brief Observes all objects until an event happens on an object or the
 *	  timeout is reached.
 *
 * @param timeInterval The time to wait for an event, in seconds
 */
- (void)observeForTimeInterval: (of_time_interval_t)timeInterval;

/**
 * @brief Observes all objects until an event happens on an object or the
 *	  specified date is reached.
 *
 * @param date The until which to observe
 */







|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

/**
 * @brief Observes all objects until an event happens on an object or the
 *	  timeout is reached.
 *
 * @param timeInterval The time to wait for an event, in seconds
 */
- (void)observeForTimeInterval: (OFTimeInterval)timeInterval;

/**
 * @brief Observes all objects until an event happens on an object or the
 *	  specified date is reached.
 *
 * @param date The until which to observe
 */

Modified src/OFKernelEventObserver.m from [9d77b8881b] to [4e64aadcfc].

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
}

- (void)observe
{
	[self observeForTimeInterval: -1];
}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)observeUntilDate: (OFDate *)date
{
	[self observeForTimeInterval: date.timeIntervalSinceNow];







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
}

- (void)observe
{
	[self observeForTimeInterval: -1];
}

- (void)observeForTimeInterval: (OFTimeInterval)timeInterval
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)observeUntilDate: (OFDate *)date
{
	[self observeForTimeInterval: date.timeIntervalSinceNow];

Modified src/OFKqueueKernelEventObserver.m from [8d97fca7a9] to [a1444efdc0].

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0)
		@throw [OFObserveFailedException exceptionWithObserver: self
								 errNo: errno];

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	struct timespec timeout;
	struct kevent eventList[EVENTLIST_SIZE];
	int events;

	if ([self of_processReadBuffers])
		return;







|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0)
		@throw [OFObserveFailedException exceptionWithObserver: self
								 errNo: errno];

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (OFTimeInterval)timeInterval
{
	struct timespec timeout;
	struct kevent eventList[EVENTLIST_SIZE];
	int events;

	if ([self of_processReadBuffers])
		return;

Modified src/OFObject.h from [51e30260c3] to [cae8b45bf8].

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

	return true;
}

/**
 * @brief A time interval in seconds.
 */
typedef double of_time_interval_t;

/**
 * @struct of_point_t OFObject.h ObjFW/OFObject.h
 *
 * @brief A point.
 */
struct OF_BOXABLE of_point_t {







|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

	return true;
}

/**
 * @brief A time interval in seconds.
 */
typedef double OFTimeInterval;

/**
 * @struct of_point_t OFObject.h ObjFW/OFObject.h
 *
 * @brief A point.
 */
struct OF_BOXABLE of_point_t {
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

/**
 * @brief Performs the specified selector after the specified delay.
 *
 * @param selector The selector to perform
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector with the specified object after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector with the specified objects after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector with the specified objects after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param object3 The third object that is passed to the method specified by the
 *		  selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector with the specified objects after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the







|












|















|


















|







819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

/**
 * @brief Performs the specified selector after the specified delay.
 *
 * @param selector The selector to perform
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector with the specified object after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector with the specified objects after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector with the specified objects after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param object3 The third object that is passed to the method specified by the
 *		  selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector with the specified objects after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (of_time_interval_t)delay;

# ifdef OF_HAVE_THREADS
/**
 * @brief Performs the specified selector on the specified thread.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector







|







889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (OFTimeInterval)delay;

# ifdef OF_HAVE_THREADS
/**
 * @brief Performs the specified selector on the specified thread.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified object after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param object3 The third object that is passed to the method specified by the
 *		  selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     afterDelay: (of_time_interval_t)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector







|














|

















|




















|







1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified object after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object1 The first object that is passed to the method specified by the
 *		  selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param object3 The third object that is passed to the method specified by the
 *		  selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     afterDelay: (OFTimeInterval)delay;

/**
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (of_time_interval_t)delay;
# endif

/**
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned false. It should return a target
 *	  to which the message should be forwarded.
 *







|







1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (OFTimeInterval)delay;
# endif

/**
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned false. It should return a target
 *	  to which the message should be forwarded.
 *

Modified src/OFObject.m from [ab465686e4] to [9719883ec1].

661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
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
	id (*imp)(id, SEL, id, id, id, id) =
	    (id (*)(id, SEL, id, id, id, id))objc_msgSend;
#endif

	return imp(self, selector, object1, object2, object3, object4);
}

- (void)performSelector: (SEL)selector afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1
					 object: object2
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1
					 object: object2
					 object: object3
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     withObject: (id)object4
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1







|













|















|

















|



















|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
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
	id (*imp)(id, SEL, id, id, id, id) =
	    (id (*)(id, SEL, id, id, id, id))objc_msgSend;
#endif

	return imp(self, selector, object1, object2, object3, object4);
}

- (void)performSelector: (SEL)selector afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1
					 object: object2
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1
					 object: object2
					 object: object3
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     withObject: (id)object4
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object1
							  object: object2
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object1
							  object: object2
							  object: object3
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     withObject: (id)object4
	     afterDelay: (of_time_interval_t)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object1







|














|
















|


















|




















|







953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object1
							  object: object2
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object1
							  object: object2
							  object: object3
							 repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     withObject: (id)object3
	     withObject: (id)object4
	     afterDelay: (OFTimeInterval)delay
{
	void *pool = objc_autoreleasePoolPush();

	[thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay
							  target: self
							selector: selector
							  object: object1

Modified src/OFPollKernelEventObserver.m from [f68dab1660] to [62bef4adc4].

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
- (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object
{
	removeObject(self, object, object.fileDescriptorForWriting, POLLOUT);

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	void *pool;
	struct pollfd *FDs;
	int events;
	size_t nFDs;

	if ([self of_processReadBuffers])







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
- (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object
{
	removeObject(self, object, object.fileDescriptorForWriting, POLLOUT);

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (OFTimeInterval)timeInterval
{
	void *pool;
	struct pollfd *FDs;
	int events;
	size_t nFDs;

	if ([self of_processReadBuffers])

Modified src/OFRunLoop.m from [7f4271f15a] to [ed582fb1a0].

1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
		} @finally {
			[state->_timersQueueMutex 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]







|







1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
		} @finally {
			[state->_timersQueueMutex unlock];
		}
#endif

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

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

Modified src/OFSelectKernelEventObserver.m from [3e6bc46edc] to [a83b51ae9b].

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#endif

	FD_CLR((of_socket_t)fd, &_writeFDs);

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	fd_set readFDs;
	fd_set writeFDs;
	struct timeval timeout;
	int events;
#ifdef OF_AMIGAOS
	BYTE cancelSignal;







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#endif

	FD_CLR((of_socket_t)fd, &_writeFDs);

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (OFTimeInterval)timeInterval
{
	fd_set readFDs;
	fd_set writeFDs;
	struct timeval timeout;
	int events;
#ifdef OF_AMIGAOS
	BYTE cancelSignal;

Modified src/OFTarArchiveEntry.m from [9e0aa08280] to [d82e96c1dd].

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
		    header + 108, 8, ULONG_MAX);
		_GID = (unsigned long)octalValueFromBuffer(
		    header + 116, 8, ULONG_MAX);
		_size = (unsigned long long)octalValueFromBuffer(
		    header + 124, 12, ULLONG_MAX);
		_modificationDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970:
		    (of_time_interval_t)octalValueFromBuffer(
		    header + 136, 12, ULLONG_MAX)];
		_type = header[156];

		targetFileName = stringFromBuffer(header + 157, 100, encoding);
		if (targetFileName.length > 0)
			_targetFileName = [targetFileName copy];








|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
		    header + 108, 8, ULONG_MAX);
		_GID = (unsigned long)octalValueFromBuffer(
		    header + 116, 8, ULONG_MAX);
		_size = (unsigned long long)octalValueFromBuffer(
		    header + 124, 12, ULLONG_MAX);
		_modificationDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970:
		    (OFTimeInterval)octalValueFromBuffer(
		    header + 136, 12, ULLONG_MAX)];
		_type = header[156];

		targetFileName = stringFromBuffer(header + 157, 100, encoding);
		if (targetFileName.length > 0)
			_targetFileName = [targetFileName copy];

Modified src/OFThread.h from [f4a6bc3a11] to [ac920e666c].

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

/**
 * @brief Suspends execution of the current thread for the specified time
 *	  interval.
 *
 * @param timeInterval The number of seconds to sleep
 */
+ (void)sleepForTimeInterval: (of_time_interval_t)timeInterval;

/**
 * @brief Suspends execution of the current thread until the specified date.
 *
 * @param date The date to wait for
 */
+ (void)sleepUntilDate: (OFDate *)date;







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

/**
 * @brief Suspends execution of the current thread for the specified time
 *	  interval.
 *
 * @param timeInterval The number of seconds to sleep
 */
+ (void)sleepForTimeInterval: (OFTimeInterval)timeInterval;

/**
 * @brief Suspends execution of the current thread until the specified date.
 *
 * @param date The date to wait for
 */
+ (void)sleepUntilDate: (OFDate *)date;

Modified src/OFThread.m from [9da78353a7] to [304aef013f].

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
		DNSResolver = [[OFDNSResolver alloc] init];

	return DNSResolver;
# endif
}
#endif

+ (void)sleepForTimeInterval: (of_time_interval_t)timeInterval
{
	if (timeInterval < 0)
		return;

#if defined(OF_WINDOWS)
	if (timeInterval * 1000 > UINT_MAX)
		@throw [OFOutOfRangeException exception];







|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
		DNSResolver = [[OFDNSResolver alloc] init];

	return DNSResolver;
# endif
}
#endif

+ (void)sleepForTimeInterval: (OFTimeInterval)timeInterval
{
	if (timeInterval < 0)
		return;

#if defined(OF_WINDOWS)
	if (timeInterval * 1000 > UINT_MAX)
		@throw [OFOutOfRangeException exception];

Modified src/OFTimer.h from [90ec44afc7] to [b4310df08c].

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 *
 * @brief A class for creating and firing timers.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *_fireDate;
	of_time_interval_t _interval;
	id _target;
	id _Nullable _object1, _object2, _object3, _object4;
	SEL _selector;
	unsigned char _arguments;
	bool _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t _block;







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 *
 * @brief A class for creating and firing timers.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *_fireDate;
	OFTimeInterval _interval;
	id _target;
	id _Nullable _object1, _object2, _object3, _object4;
	SEL _selector;
	unsigned char _arguments;
	bool _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t _block;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
	of_run_loop_mode_t _Nullable _inRunLoopMode;
}

/**
 * @brief The time interval in which the timer will repeat, if it is a
 *	  repeating timer.
 */
@property (readonly, nonatomic) of_time_interval_t timeInterval;

/**
 * @brief Whether the timer is repeating.
 */
@property (readonly, nonatomic, getter=isRepeating) bool repeating;

/**







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
	of_run_loop_mode_t _Nullable _inRunLoopMode;
}

/**
 * @brief The time interval in which the timer will repeat, if it is a
 *	  repeating timer.
 */
@property (readonly, nonatomic) OFTimeInterval timeInterval;

/**
 * @brief Whether the timer is repeating.
 */
@property (readonly, nonatomic, getter=isRepeating) bool repeating;

/**
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
				       repeats: (bool)repeats;

/**
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object
				       repeats: (bool)repeats;

/**
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object1
					object: (nullable id)object2
				       repeats: (bool)repeats;

/**







|














|


















|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
				       repeats: (bool)repeats;

/**
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object
				       repeats: (bool)repeats;

/**
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object1
					object: (nullable id)object2
				       repeats: (bool)repeats;

/**
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object1
					object: (nullable id)object2
					object: (nullable id)object3
				       repeats: (bool)repeats;








|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object1
					object: (nullable id)object2
					object: (nullable id)object3
				       repeats: (bool)repeats;

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param object4 The fourth object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object1
					object: (nullable id)object2
					object: (nullable id)object3
					object: (nullable id)object4
				       repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/**
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
				       repeats: (bool)repeats
					 block: (of_timer_block_t)block;
#endif

/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			      repeats: (bool)repeats;

/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object
			      repeats: (bool)repeats;

/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object1
			       object: (nullable id)object2
			      repeats: (bool)repeats;

/**







|

















|













|














|


















|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param object4 The fourth object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (nullable id)object1
					object: (nullable id)object2
					object: (nullable id)object3
					object: (nullable id)object4
				       repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/**
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
				       repeats: (bool)repeats
					 block: (of_timer_block_t)block;
#endif

/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			      repeats: (bool)repeats;

/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object
			      repeats: (bool)repeats;

/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object1
			       object: (nullable id)object2
			      repeats: (bool)repeats;

/**
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object1
			       object: (nullable id)object2
			       object: (nullable id)object3
			      repeats: (bool)repeats;








|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object1
			       object: (nullable id)object2
			       object: (nullable id)object3
			      repeats: (bool)repeats;

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param object4 The fourth object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object1
			       object: (nullable id)object2
			       object: (nullable id)object3
			       object: (nullable id)object4
			      repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			      repeats: (bool)repeats
				block: (of_timer_block_t)block;
#endif

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			 repeats: (bool)repeats;

/**
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object
			 repeats: (bool)repeats;

/**
 * @brief Initializes an already allocated timer with the specified time







|

















|



















|


















|







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param object4 The fourth object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (nullable id)object1
			       object: (nullable id)object2
			       object: (nullable id)object3
			       object: (nullable id)object4
			      repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/**
 * @brief Creates a new timer with the specified time interval.
 *
 * @param timeInterval The time interval after which the timer should be fired
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			      repeats: (bool)repeats
				block: (of_timer_block_t)block;
#endif

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			 repeats: (bool)repeats;

/**
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object
			 repeats: (bool)repeats;

/**
 * @brief Initializes an already allocated timer with the specified time
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object1
			  object: (nullable id)object2
			 repeats: (bool)repeats;

/**







|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object1
			  object: (nullable id)object2
			 repeats: (bool)repeats;

/**
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
 *		  target
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object1
			  object: (nullable id)object2
			  object: (nullable id)object3
			 repeats: (bool)repeats;








|







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
 *		  target
 * @param object3 The third object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object1
			  object: (nullable id)object2
			  object: (nullable id)object3
			 repeats: (bool)repeats;

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
 *		  target
 * @param object4 The fourth object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object1
			  object: (nullable id)object2
			  object: (nullable id)object3
			  object: (nullable id)object4
			 repeats: (bool)repeats;







|







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
 *		  target
 * @param object4 The fourth object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (nullable id)object1
			  object: (nullable id)object2
			  object: (nullable id)object3
			  object: (nullable id)object4
			 repeats: (bool)repeats;
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			 repeats: (bool)repeats
			   block: (of_timer_block_t)block;
#endif

/**
 * @brief Compares the timer to another timer.
 *







|







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return An initialized timer
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			 repeats: (bool)repeats
			   block: (of_timer_block_t)block;
#endif

/**
 * @brief Compares the timer to another timer.
 *

Modified src/OFTimer.m from [d7ed3b965f] to [fc8cefbc96].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#endif

#import "OFInvalidArgumentException.h"

@implementation OFTimer
@synthesize timeInterval = _interval, repeating = _repeats, valid = _valid;

+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					    target: target
					  selector: selector
					   repeats: repeats] autorelease];

	[[OFRunLoop currentRunLoop] addTimer: timer];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];







|




















|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#endif

#import "OFInvalidArgumentException.h"

@implementation OFTimer
@synthesize timeInterval = _interval, repeating = _repeats, valid = _valid;

+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					    target: target
					  selector: selector
					   repeats: repeats] autorelease];

	[[OFRunLoop currentRunLoop] addTimer: timer];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
					object: (id)object3
				       repeats: (bool)repeats
{







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
					object: (id)object3
				       repeats: (bool)repeats
{
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
					object: (id)object3
					object: (id)object4
				       repeats: (bool)repeats







|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
					object: (id)object3
					object: (id)object4
				       repeats: (bool)repeats
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

#ifdef OF_HAVE_BLOCKS
+ (instancetype)scheduledTimerWithTimeInterval: (of_time_interval_t)timeInterval
				       repeats: (bool)repeats
					 block: (of_timer_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					   repeats: repeats
					     block: block] autorelease];

	[[OFRunLoop currentRunLoop] addTimer: timer];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}
#endif

+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					    target: target
					  selector: selector
					   repeats: repeats] autorelease];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					    target: target
					  selector: selector
					    object: object
					   repeats: repeats] autorelease];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();







|



















|


















|




















|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

#ifdef OF_HAVE_BLOCKS
+ (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval
				       repeats: (bool)repeats
					 block: (of_timer_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					   repeats: repeats
					     block: block] autorelease];

	[[OFRunLoop currentRunLoop] addTimer: timer];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}
#endif

+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					    target: target
					  selector: selector
					   repeats: repeats] autorelease];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
					    target: target
					  selector: selector
					    object: object
					   repeats: repeats] autorelease];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			       object: (id)object3
			      repeats: (bool)repeats
{







|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			       object: (id)object3
			      repeats: (bool)repeats
{
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			       object: (id)object3
			       object: (id)object4
			      repeats: (bool)repeats







|







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			       object: (id)object3
			       object: (id)object4
			      repeats: (bool)repeats
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

#ifdef OF_HAVE_BLOCKS
+ (instancetype)timerWithTimeInterval: (of_time_interval_t)timeInterval
			      repeats: (bool)repeats
				block: (of_timer_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval







|







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

#ifdef OF_HAVE_BLOCKS
+ (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval
			      repeats: (bool)repeats
				block: (of_timer_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: timeInterval
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)of_initWithFireDate: (OFDate *)fireDate
			   interval: (of_time_interval_t)interval
			     target: (id)target
			   selector: (SEL)selector
			     object: (id)object1
			     object: (id)object2
			     object: (id)object3
			     object: (id)object4
			  arguments: (unsigned char)arguments







|







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)of_initWithFireDate: (OFDate *)fireDate
			   interval: (OFTimeInterval)interval
			     target: (id)target
			   selector: (SEL)selector
			     object: (id)object1
			     object: (id)object2
			     object: (id)object3
			     object: (id)object4
			  arguments: (unsigned char)arguments
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
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
		@throw e;
	}

	return self;
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: nil
				  object: nil
				  object: nil
				  object: nil
			       arguments: 0
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object
				  object: nil
				  object: nil
				  object: nil
			       arguments: 1
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object1
			  object: (id)object2
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
				  object: nil
				  object: nil
			       arguments: 2
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object1
			  object: (id)object2
			  object: (id)object3
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
				  object: object3
				  object: nil
			       arguments: 3
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object1
			  object: (id)object2
			  object: (id)object3
			  object: (id)object4
			 repeats: (bool)repeats







|

















|


















|



















|




















|







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
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
		@throw e;
	}

	return self;
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: nil
				  object: nil
				  object: nil
				  object: nil
			       arguments: 0
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object
				  object: nil
				  object: nil
				  object: nil
			       arguments: 1
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object1
			  object: (id)object2
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
				  object: nil
				  object: nil
			       arguments: 2
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object1
			  object: (id)object2
			  object: (id)object3
			 repeats: (bool)repeats
{
	return [self of_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
				  object: object3
				  object: nil
			       arguments: 3
				 repeats: repeats];
}

- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			  target: (id)target
			selector: (SEL)selector
			  object: (id)object1
			  object: (id)object2
			  object: (id)object3
			  object: (id)object4
			 repeats: (bool)repeats
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
				  object: object4
			       arguments: 4
				 repeats: repeats];
}

#ifdef OF_HAVE_BLOCKS
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			 repeats: (bool)repeats
			   block: (of_timer_block_t)block
{
	self = [super init];

	@try {
		_fireDate = [fireDate retain];







|







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
				  object: object4
			       arguments: 4
				 repeats: repeats];
}

#ifdef OF_HAVE_BLOCKS
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (OFTimeInterval)interval
			 repeats: (bool)repeats
			   block: (of_timer_block_t)block
{
	self = [super init];

	@try {
		_fireDate = [fireDate retain];
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
	id object4 = [[_object4 retain] autorelease];

	OF_ENSURE(_arguments <= 4);

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

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

		newFireDate = _fireDate.timeIntervalSince1970 +







|







536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
	id object4 = [[_object4 retain] autorelease];

	OF_ENSURE(_arguments <= 4);

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

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

		newFireDate = _fireDate.timeIntervalSince1970 +

Modified src/condition.h from [61428a9c46] to [0d9f4192a1].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "platform.h"

#if !defined(OF_HAVE_THREADS) || \
    (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No conditions available!
#endif

/* For of_time_interval_t */
#import "OFObject.h"

#import "mutex.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_cond_t of_condition_t;







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "platform.h"

#if !defined(OF_HAVE_THREADS) || \
    (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No conditions available!
#endif

/* For OFTimeInterval */
#import "OFObject.h"

#import "mutex.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_cond_t of_condition_t;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
extern "C" {
#endif
extern int of_condition_new(of_condition_t *condition);
extern int of_condition_signal(of_condition_t *condition);
extern int of_condition_broadcast(of_condition_t *condition);
extern int of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern int of_condition_timed_wait(of_condition_t *condition,
    of_mutex_t *mutex, of_time_interval_t timeout);
#ifdef OF_AMIGAOS
extern int of_condition_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, ULONG *signalMask);
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, of_time_interval_t timeout, ULONG *signalMask);
#endif
extern int of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif







|




|





51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
extern "C" {
#endif
extern int of_condition_new(of_condition_t *condition);
extern int of_condition_signal(of_condition_t *condition);
extern int of_condition_broadcast(of_condition_t *condition);
extern int of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern int of_condition_timed_wait(of_condition_t *condition,
    of_mutex_t *mutex, OFTimeInterval timeout);
#ifdef OF_AMIGAOS
extern int of_condition_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, ULONG *signalMask);
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, OFTimeInterval timeout, ULONG *signalMask);
#endif
extern int of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif

Modified src/platform/amiga/condition.m from [fd8eb39931] to [dc620431f9].

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	Permit();

	return error;
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
	ULONG signalMask = 0;

	return of_condition_timed_wait_or_signal(condition, mutex, timeout,
	    &signalMask);
}

int
of_condition_timed_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout, ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	struct MsgPort port = {
		.mp_Node = {







|









|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	Permit();

	return error;
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout)
{
	ULONG signalMask = 0;

	return of_condition_timed_wait_or_signal(condition, mutex, timeout,
	    &signalMask);
}

int
of_condition_timed_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout, ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	struct MsgPort port = {
		.mp_Node = {

Modified src/platform/posix/condition.m from [118d5cf68b] to [7ce4083f77].

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	return pthread_cond_wait(condition, mutex);
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
	struct timespec ts;

	ts.tv_sec = (time_t)timeout;
	ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000);

	return pthread_cond_timedwait(condition, mutex, &ts);







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	return pthread_cond_wait(condition, mutex);
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout)
{
	struct timespec ts;

	ts.tv_sec = (time_t)timeout;
	ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000);

	return pthread_cond_timedwait(condition, mutex, &ts);

Modified src/platform/windows/condition.m from [cc03ce6342] to [595cdc3d8b].

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
	default:
		OF_ENSURE(0);
	}
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
	int error;
	DWORD status;

	if ((error = of_mutex_unlock(mutex)) != 0)
		return error;








|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
	default:
		OF_ENSURE(0);
	}
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout)
{
	int error;
	DWORD status;

	if ((error = of_mutex_unlock(mutex)) != 0)
		return error;