ObjFW  Check-in [ab9ad6e515]

Overview
Comment:observeWithTimeout: -> observeForTimeInterval:.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ab9ad6e5154d7170c4411476bd5af9f1becb4aebb2e395f3df65e40c88ef808b
User & Date: js on 2013-04-30 22:47:28
Other Links: manifest | tags
Context
2013-05-01
20:31
Fix -Wcast-align check for recent Clang versions. check-in: 874faa49a7 user: js tags: trunk
2013-04-30
22:47
observeWithTimeout: -> observeForTimeInterval:. check-in: ab9ad6e515 user: js tags: trunk
22:36
Add -[OFCondition waitForTimeInterval:]. check-in: 8d7f5db97e user: js tags: trunk
Changes

Modified src/OFRunLoop.m from [76c781112c] to [fcdc461826].

670
671
672
673
674
675
676
677

678
679
680
681
682
683
684

		/* Watch for stream events until the next timer is due */
		if (nextTimer != nil) {
			double timeout = [nextTimer timeIntervalSinceNow];

			if (timeout > 0)
#ifdef OF_HAVE_SOCKETS
				[_streamObserver observeWithTimeout: timeout];

#else
				[OFThread sleepForTimeInterval: timeout];
#endif
		} else {
			/*
			 * No more timers: Just watch for streams until we get
			 * an event. If a timer is added by another thread, it







|
>







670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

		/* Watch for stream events until the next timer is due */
		if (nextTimer != nil) {
			double timeout = [nextTimer timeIntervalSinceNow];

			if (timeout > 0)
#ifdef OF_HAVE_SOCKETS
				[_streamObserver
				    observeForTimeInterval: timeout];
#else
				[OFThread sleepForTimeInterval: timeout];
#endif
		} else {
			/*
			 * No more timers: Just watch for streams until we get
			 * an event. If a timer is added by another thread, it

Modified src/OFStreamObserver.h from [7fc7495bc7] to [968a82ac04].

27
28
29
30
31
32
33

34
35
36
37
38
39
40
@class OFStream;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFDataArray;
#ifdef OF_HAVE_THREADS
@class OFMutex;
#endif


/*!
 * @brief A protocol that needs to be implemented by delegates for
 *	  OFStreamObserver.
 */
@protocol OFStreamObserverDelegate <OFObject>
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS







>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@class OFStream;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFDataArray;
#ifdef OF_HAVE_THREADS
@class OFMutex;
#endif
@class OFDate;

/*!
 * @brief A protocol that needs to be implemented by delegates for
 *	  OFStreamObserver.
 */
@protocol OFStreamObserverDelegate <OFObject>
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
170
171
172
173
174
175
176
177
178
179









180
181
182
183
184
185
186
187
 */
- (void)observe;

/*!
 * @brief Observes all streams until an event happens on a stream or the
 *	  timeout is reached.
 *
 * @param timeout The time to wait for an event, in seconds
 * @return A boolean whether events occurred during the timeinterval
 */









- (bool)observeWithTimeout: (double)timeout;

/*!
 * @brief Cancels the currently blocking observe call.
 *
 * This is automatically done when a new stream is added or removed by another
 * thread, but in some circumstances, it might be desirable for a thread to
 * manually stop the observe running in another thread.







|


>
>
>
>
>
>
>
>
>
|







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
 */
- (void)observe;

/*!
 * @brief Observes all streams until an event happens on a stream or the
 *	  timeout is reached.
 *
 * @param timeInterval The time to wait for an event, in seconds
 * @return A boolean whether events occurred during the timeinterval
 */
- (bool)observeForTimeInterval: (double)timeInterval;

/*!
 * @brief Observes all streams until an event happens on a stream or the
 *	  timeout is reached.
 *
 * @param date The until which to observe
 * @return A boolean whether events occurred until the specified date
 */
- (bool)observeUntilDate: (OFDate*)date;

/*!
 * @brief Cancels the currently blocking observe call.
 *
 * This is automatically done when a new stream is added or removed by another
 * thread, but in some circumstances, it might be desirable for a thread to
 * manually stop the observe running in another thread.

Modified src/OFStreamObserver.m from [14f367ec0c] to [4b5320c792].

31
32
33
34
35
36
37

38
39
40
41
42
43
44
#import "OFDataArray.h"
#ifdef _WIN32
# import "OFTCPSocket.h"
#endif
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif


#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#ifdef HAVE_POLL_H
# import "OFStreamObserver_poll.h"
#endif







>







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#import "OFDataArray.h"
#ifdef _WIN32
# import "OFTCPSocket.h"
#endif
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif
#import "OFDate.h"

#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#ifdef HAVE_POLL_H
# import "OFStreamObserver_poll.h"
#endif
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380





381
382
383
384
385
386
387
		[_mutex unlock];
#endif
	}
}

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

- (bool)observeWithTimeout: (double)timeout
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}






- (void)cancel
{
#ifndef _WIN32
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr*)&_cancelAddr,







|


|




>
>
>
>
>







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
		[_mutex unlock];
#endif
	}
}

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

- (bool)observeForTimeInterval: (double)timeInterval
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (bool)observeUntilDate: (OFDate*)date
{
	return [self observeForTimeInterval: [date timeIntervalSinceNow]];
}

- (void)cancel
{
#ifndef _WIN32
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr*)&_cancelAddr,

Modified src/OFStreamObserver_kqueue.m from [ac3c9446ae] to [0df0a2e4f0].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"


#include <unistd.h>
#include <errno.h>

#include <assert.h>

#include <sys/types.h>
#include <sys/event.h>







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <math.h>
#include <unistd.h>
#include <errno.h>

#include <assert.h>

#include <sys/types.h>
#include <sys/event.h>
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
{
	struct kevent event;

	EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
	[_changeList addItem: &event];
}

- (bool)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	struct timespec timespec;
	struct kevent eventList[EVENTLIST_SIZE];
	int i, events, realEvents = 0;

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

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return true;
	}

	objc_autoreleasePoolPop(pool);

	events = kevent(_kernelQueue, [_changeList items],
	    (int)[_changeList count], eventList, EVENTLIST_SIZE,
	    (timeout == -1 ? NULL : &timespec));

	if (events < 0)
		return false;

	[_changeList removeAllItems];

	if (events == 0)







|


|



|
|












|







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
{
	struct kevent event;

	EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
	[_changeList addItem: &event];
}

- (bool)observeForTimeInterval: (double)timeInterval
{
	void *pool = objc_autoreleasePoolPush();
	struct timespec timeout;
	struct kevent eventList[EVENTLIST_SIZE];
	int i, events, realEvents = 0;

	timeout.tv_sec = (time_t)timeInterval;
	timeout.tv_nsec = lrint((timeInterval - timeout.tv_sec) * 1000000000);

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return true;
	}

	objc_autoreleasePoolPop(pool);

	events = kevent(_kernelQueue, [_changeList items],
	    (int)[_changeList count], eventList, EVENTLIST_SIZE,
	    (timeInterval == -1 ? NULL : &timeout));

	if (events < 0)
		return false;

	[_changeList removeAllItems];

	if (events == 0)

Modified src/OFStreamObserver_poll.m from [684851fd9c] to [da5230bc72].

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

- (void)OF_removeFileDescriptorForWriting: (int)fd
{
	[self OF_removeFileDescriptor: fd
			   withEvents: POLLOUT];
}

- (bool)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	struct pollfd *FDs;
	size_t i, nFDs, realEvents = 0;

	[self OF_processQueue];








|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

- (void)OF_removeFileDescriptorForWriting: (int)fd
{
	[self OF_removeFileDescriptor: fd
			   withEvents: POLLOUT];
}

- (bool)observeForTimeInterval: (double)timeInterval
{
	void *pool = objc_autoreleasePoolPush();
	struct pollfd *FDs;
	size_t i, nFDs, realEvents = 0;

	[self OF_processQueue];

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

#ifdef OPEN_MAX
	if (nFDs > OPEN_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#endif

	if (poll(FDs, (nfds_t)nFDs,
	    (int)(timeout != -1 ? timeout * 1000 : -1)) < 1)
		return false;

	for (i = 0; i < nFDs; i++) {
		pool = objc_autoreleasePoolPush();

		if (FDs[i].revents & POLLIN) {
			if (FDs[i].fd == _cancelFD[0]) {







|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

#ifdef OPEN_MAX
	if (nFDs > OPEN_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#endif

	if (poll(FDs, (nfds_t)nFDs,
	    (int)(timeInterval != -1 ? timeInterval * 1000 : -1)) < 1)
		return false;

	for (i = 0; i < nFDs; i++) {
		pool = objc_autoreleasePoolPush();

		if (FDs[i].revents & POLLIN) {
			if (FDs[i].fd == _cancelFD[0]) {

Modified src/OFStreamObserver_select.m from [0d55873c55] to [855b79f521].

15
16
17
18
19
20
21

22
23
24
25
26
27
28
 */

#include "config.h"

#define __NO_EXT_QNX

#include <string.h>

#include <unistd.h>

#include <sys/time.h>

#import "OFStreamObserver_select.h"
#import "OFStream.h"
#import "OFArray.h"







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 */

#include "config.h"

#define __NO_EXT_QNX

#include <string.h>
#include <math.h>
#include <unistd.h>

#include <sys/time.h>

#import "OFStreamObserver_select.h"
#import "OFStream.h"
#import "OFArray.h"
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{
	FD_CLR(fd, &_writeFDs);

	if (!FD_ISSET(fd, &_readFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (bool)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	OFStream **objects;
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
	struct timeval time;
	size_t i, count, realEvents = 0;

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return true;







|






|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
{
	FD_CLR(fd, &_writeFDs);

	if (!FD_ISSET(fd, &_readFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (bool)observeForTimeInterval: (double)timeInterval
{
	void *pool = objc_autoreleasePoolPush();
	OFStream **objects;
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
	struct timeval timeout;
	size_t i, count, realEvents = 0;

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return true;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

	/*
	 * We cast to int before assigning to tv_usec in order to avoid a
	 * warning with Apple GCC on PPC. POSIX defines this as suseconds_t,
	 * however, this is not available on Win32. As an int should always
	 * satisfy the required range, we just cast to int.
	 */
	time.tv_sec = (time_t)timeout;
	time.tv_usec = (int)((timeout - time.tv_sec) * 1000);

	if (select((int)_maxFD + 1, &readFDs, &writeFDs, &exceptFDs,
	    (timeout != -1 ? &time : NULL)) < 1)
		return false;

	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;
#ifndef _WIN32
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
#else







|
|


|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

	/*
	 * We cast to int before assigning to tv_usec in order to avoid a
	 * warning with Apple GCC on PPC. POSIX defines this as suseconds_t,
	 * however, this is not available on Win32. As an int should always
	 * satisfy the required range, we just cast to int.
	 */
	timeout.tv_sec = (time_t)timeInterval;
	timeout.tv_usec = (int)lrint((timeInterval - timeout.tv_sec) * 1000);

	if (select((int)_maxFD + 1, &readFDs, &writeFDs, &exceptFDs,
	    (timeInterval != -1 ? &timeout : NULL)) < 1)
		return false;

	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;
#ifndef _WIN32
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
#else