ObjFW  Check-in [5d8349a8f6]

Overview
Comment:Add -[OFTCPSocket asyncAcceptWithBlock:].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5d8349a8f602c07856f931a9ae2a2b267222a223432b55d68eb41a56ac76dc03
User & Date: js on 2012-09-16 10:19:49
Other Links: manifest | tags
Context
2012-09-16
11:45
Fix missing imports. check-in: 5a19a8a2a5 user: js tags: trunk
10:19
Add -[OFTCPSocket asyncAcceptWithBlock:]. check-in: 5d8349a8f6 user: js tags: trunk
2012-09-15
12:22
OFTCPSocket: Implement async connecting. check-in: 3b68656e8d user: js tags: trunk
Changes

Modified src/OFRunLoop.h from [2b4f887c3c] to [07aad9ab59].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFStream.h"
#import "OFStreamObserver.h"


@class OFSortedList;
@class OFTimer;
@class OFMutableDictionary;

/**
 * \brief A class providing a run loop for the application and its processes.







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFStream.h"
#import "OFStreamObserver.h"
#import "OFTCPSocket.h"

@class OFSortedList;
@class OFTimer;
@class OFMutableDictionary;

/**
 * \brief A class providing a run loop for the application and its processes.
54
55
56
57
58
59
60


61
62
63
64
65
66
67
+ (void)_addAsyncReadForStream: (OFStream*)stream
			buffer: (void*)buffer
			length: (size_t)length
			 block: (of_stream_async_read_block_t)block;
+ (void)_addAsyncReadLineForStream: (OFStream*)stream
			  encoding: (of_string_encoding_t)encoding
			     block: (of_stream_async_read_line_block_t)block;


#endif

/**
 * \brief Adds an OFTimer to the run loop.
 *
 * \param timer The timer to add
 */







>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
+ (void)_addAsyncReadForStream: (OFStream*)stream
			buffer: (void*)buffer
			length: (size_t)length
			 block: (of_stream_async_read_block_t)block;
+ (void)_addAsyncReadLineForStream: (OFStream*)stream
			  encoding: (of_string_encoding_t)encoding
			     block: (of_stream_async_read_line_block_t)block;
+ (void)_addAsyncAcceptForTCPSocket: (OFTCPSocket*)socket
			      block: (of_tcpsocket_async_accept_block_t)block;
#endif

/**
 * \brief Adds an OFTimer to the run loop.
 *
 * \param timer The timer to add
 */

Modified src/OFRunLoop.m from [5d28216a68] to [35be43bbba].

48
49
50
51
52
53
54








55
56
57
58
59
60
61
62
63
64
65
66
67
68
69











70
71
72
73
74
75
76
	of_stream_async_read_line_block_t block;
	of_string_encoding_t encoding;
}

@property (copy) of_stream_async_read_line_block_t block;
@property of_string_encoding_t encoding;
@end









@implementation OFRunLoop_ReadQueueItem
@synthesize buffer, length, block;

- (void)dealloc
{
	[block release];

	[super dealloc];
}
@end

@implementation OFRunLoop_ReadLineQueueItem
@synthesize block, encoding;












- (void)dealloc
{
	[block release];

	[super dealloc];
}
@end







>
>
>
>
>
>
>
>















>
>
>
>
>
>
>
>
>
>
>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
	of_stream_async_read_line_block_t block;
	of_string_encoding_t encoding;
}

@property (copy) of_stream_async_read_line_block_t block;
@property of_string_encoding_t encoding;
@end

@interface OFRunLoop_AcceptQueueItem: OFObject
{
	of_tcpsocket_async_accept_block_t block;
}

@property (copy) of_tcpsocket_async_accept_block_t block;
@end

@implementation OFRunLoop_ReadQueueItem
@synthesize buffer, length, block;

- (void)dealloc
{
	[block release];

	[super dealloc];
}
@end

@implementation OFRunLoop_ReadLineQueueItem
@synthesize block, encoding;

- (void)dealloc
{
	[block release];

	[super dealloc];
}
@end

@implementation OFRunLoop_AcceptQueueItem
@synthesize block;

- (void)dealloc
{
	[block release];

	[super dealloc];
}
@end
158
159
160
161
162
163
164
























165
166
167
168
169
170
171
	queueItem = [[[OFRunLoop_ReadLineQueueItem alloc] init] autorelease];
	[queueItem setBlock: block];
	[queueItem setEncoding: encoding];
	[queue appendObject: queueItem];

	objc_autoreleasePoolPop(pool);
}
























#endif

- init
{
	self = [super init];

	@try {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	queueItem = [[[OFRunLoop_ReadLineQueueItem alloc] init] autorelease];
	[queueItem setBlock: block];
	[queueItem setEncoding: encoding];
	[queue appendObject: queueItem];

	objc_autoreleasePoolPop(pool);
}

+ (void)_addAsyncAcceptForTCPSocket: (OFTCPSocket*)socket
			      block: (of_tcpsocket_async_accept_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFRunLoop *runLoop = [self currentRunLoop];
	OFList *queue = [runLoop->readQueues objectForKey: socket];
	OFRunLoop_AcceptQueueItem *queueItem;

	if (queue == nil) {
		queue = [OFList list];
		[runLoop->readQueues setObject: queue
					forKey: socket];
	}

	if ([queue count] == 0)
		[runLoop->streamObserver addStreamForReading: socket];

	queueItem = [[[OFRunLoop_AcceptQueueItem alloc] init] autorelease];
	[queueItem setBlock: block];
	[queue appendObject: queueItem];

	objc_autoreleasePoolPop(pool);
}
#endif

- init
{
	self = [super init];

	@try {
242
243
244
245
246
247
248













249
250
251
252
253
254
255

				if ([queue count] == 0) {
					[streamObserver
					    removeStreamForReading: stream];
					[readQueues removeObjectForKey: stream];
				}
			}













		}
	} else
		OF_ENSURE(0);
}
#endif

- (void)run







>
>
>
>
>
>
>
>
>
>
>
>
>







285
286
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

				if ([queue count] == 0) {
					[streamObserver
					    removeStreamForReading: stream];
					[readQueues removeObjectForKey: stream];
				}
			}
		}
	} else if ([listObject->object isKindOfClass:
	    [OFRunLoop_AcceptQueueItem class]]) {
		OFRunLoop_AcceptQueueItem *queueItem = listObject->object;
		OFTCPSocket *newSocket = [(OFTCPSocket*)stream accept];

		if (![queueItem block]((OFTCPSocket*)stream, newSocket)) {
			[queue removeListObject: listObject];

			if ([queue count] == 0) {
				[streamObserver removeStreamForReading: stream];
				[readQueues removeObjectForKey: stream];
			}
		}
	} else
		OF_ENSURE(0);
}
#endif

- (void)run

Modified src/OFTCPSocket.h from [3bab17e6ab] to [fc62eafd6e].

34
35
36
37
38
39
40

41
42
43
44
45
46
47
#endif

@class OFTCPSocket;
@class OFString;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_tcpsocket_async_connect_block_t)(OFTCPSocket*);

#endif

/**
 * \brief A class which provides functions to create and use TCP sockets.
 *
 * To connect to a server, create a socket and connect it.
 * To create a server, create a socket, bind it and listen on it.







>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#endif

@class OFTCPSocket;
@class OFString;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_tcpsocket_async_connect_block_t)(OFTCPSocket*);
typedef BOOL (^of_tcpsocket_async_accept_block_t)(OFTCPSocket*, OFTCPSocket*);
#endif

/**
 * \brief A class which provides functions to create and use TCP sockets.
 *
 * To connect to a server, create a socket and connect it.
 * To create a server, create a socket, bind it and listen on it.
167
168
169
170
171
172
173











174
175
176
177
178
179
180

/**
 * \brief Accept an incoming connection.
 *
 * \return An autoreleased OFTCPSocket for the accepted connection.
 */
- (OFTCPSocket*)accept;












/**
 * \brief Enable or disable keep alives for the connection.
 *
 * \param enable Whether to enable or disable keep alives for the connection
 */
- (void)setKeepAlivesEnabled: (BOOL)enable;







>
>
>
>
>
>
>
>
>
>
>







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

/**
 * \brief Accept an incoming connection.
 *
 * \return An autoreleased OFTCPSocket for the accepted connection.
 */
- (OFTCPSocket*)accept;

#ifdef OF_HAVE_BLOCKS
/**
 * \brief Asyncronously ccept an incoming connection.
 *
 * \param block The block to execute when a new connection has been accepted.
 *		Returns whether the next incoming connection should be accepted
 *		by the specified block as well.
 */
- (void)asyncAcceptWithBlock: (of_tcpsocket_async_accept_block_t)block;
#endif

/**
 * \brief Enable or disable keep alives for the connection.
 *
 * \param enable Whether to enable or disable keep alives for the connection
 */
- (void)setKeepAlivesEnabled: (BOOL)enable;

Modified src/OFTCPSocket.m from [d1ec2a4710] to [23c0b57231].

509
510
511
512
513
514
515








516
517
518
519
520
521
522

	newSocket->sock = newSock;
	newSocket->sockAddr = addr;
	newSocket->sockAddrLen = addrLen;

	return newSocket;
}









- (void)setKeepAlivesEnabled: (BOOL)enable
{
	int v = enable;

	if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
		@throw [OFSetOptionFailedException







>
>
>
>
>
>
>
>







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530

	newSocket->sock = newSock;
	newSocket->sockAddr = addr;
	newSocket->sockAddrLen = addrLen;

	return newSocket;
}

#ifdef OF_HAVE_BLOCKS
- (void)asyncAcceptWithBlock: (of_tcpsocket_async_accept_block_t)block
{
	[OFRunLoop _addAsyncAcceptForTCPSocket: self
					 block: block];
}
#endif

- (void)setKeepAlivesEnabled: (BOOL)enable
{
	int v = enable;

	if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
		@throw [OFSetOptionFailedException