ObjFW  Check-in [13ea2fc8b1]

Overview
Comment:Async I/O: Pass a context.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 13ea2fc8b198591d25d9a454f0192db7cc36e90be8447008b5e2bfb49f3683f1
User & Date: js on 2012-10-30 18:50:15
Other Links: manifest | tags
Context
2012-10-30
22:16
OFArray: Optimize fast enumeration. check-in: 365e946d10 user: js tags: trunk
18:50
Async I/O: Pass a context. check-in: 13ea2fc8b1 user: js tags: trunk
2012-10-29
13:50
Increase library major version. check-in: ebed14967d user: js tags: trunk
Changes

Modified src/OFRunLoop.h from [3854375363] to [e9b5706f3a].

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







-
+
+




-
+
+



-
+
+


-
+
+







+ (OFRunLoop*)currentRunLoop;

+ (void)OF_setMainRunLoop;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector;
			selector: (SEL)selector
			 context: (id)context;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
		     exactLength: (size_t)length
			  target: (id)target
			selector: (SEL)selector;
			selector: (SEL)selector
			 context: (id)context;
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
			    encoding: (of_string_encoding_t)encoding
			      target: (id)target
			    selector: (SEL)selector;
			    selector: (SEL)selector
			     context: (id)context;
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)socket
			       target: (id)target
			     selector: (SEL)selector;
			     selector: (SEL)selector
			      context: (id)context;
#ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			   block: (of_stream_async_read_block_t)block;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer

Modified src/OFRunLoop.m from [5d7da15761] to [c937fefc13].

24
25
26
27
28
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
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
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
24
25
26
27
28
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
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
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







+
+
+
+
+
+
+
+
+
-
+




-
-






-
+




-
-






-
+



-
-






-
+


-
-






-
+



+
+
+
+
+
+
+
+
+











-











-











-







#import "OFDate.h"

#import "autorelease.h"
#import "macros.h"

static OFRunLoop *mainRunLoop = nil;

@interface OFRunLoop_QueueItem: OFObject
{
@public
	id target;
	SEL selector;
	id context;
}
@end

@interface OFRunLoop_ReadQueueItem: OFObject
@interface OFRunLoop_ReadQueueItem: OFRunLoop_QueueItem
{
@public
	void *buffer;
	size_t length;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_stream_async_read_block_t block;
#endif
}
@end

@interface OFRunLoop_ExactReadQueueItem: OFObject
@interface OFRunLoop_ExactReadQueueItem: OFRunLoop_QueueItem
{
@public
	void *buffer;
	size_t exactLength, readLength;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_stream_async_read_block_t block;
#endif
}
@end

@interface OFRunLoop_ReadLineQueueItem: OFObject
@interface OFRunLoop_ReadLineQueueItem: OFRunLoop_QueueItem
{
@public
	of_string_encoding_t encoding;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_stream_async_read_line_block_t block;
#endif
}
@end

@interface OFRunLoop_AcceptQueueItem: OFObject
@interface OFRunLoop_AcceptQueueItem: OFRunLoop_QueueItem
{
@public
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_tcpsocket_async_accept_block_t block;
#endif
}
@end

@implementation OFRunLoop_ReadQueueItem
@implementation OFRunLoop_QueueItem
- (void)dealloc
{
	[target release];
	[context release];

	[super dealloc];
}
@end

@implementation OFRunLoop_ReadQueueItem
- (void)dealloc
{
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif

	[super dealloc];
}
@end

@implementation OFRunLoop_ExactReadQueueItem
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif

	[super dealloc];
}
@end

@implementation OFRunLoop_ReadLineQueueItem
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif

	[super dealloc];
}
@end

@implementation OFRunLoop_AcceptQueueItem
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif

	[super dealloc];
}
@end
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
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
230
231
232
233
234
235







+






+








+






+







+





+






+




+







	objc_autoreleasePoolPop(pool);

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector
			 context: (id)context
{
	ADD(OFRunLoop_ReadQueueItem, {
		queueItem->buffer = buffer;
		queueItem->length = length;
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->context = [context retain];
	})
}

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
		     exactLength: (size_t)exactLength
			  target: (id)target
			selector: (SEL)selector
			 context: (id)context
{
	ADD(OFRunLoop_ExactReadQueueItem, {
		queueItem->buffer = buffer;
		queueItem->exactLength = exactLength;
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->context = [context retain];
	})
}

+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
			    encoding: (of_string_encoding_t)encoding
			      target: (id)target
			    selector: (SEL)selector
			     context: (id)context
{
	ADD(OFRunLoop_ReadLineQueueItem, {
		queueItem->encoding = encoding;
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->context = [context retain];
	})
}

+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
			       target: (id)target
			     selector: (SEL)selector
			      context: (id)context
{
	ADD(OFRunLoop_AcceptQueueItem, {
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->context = [context retain];
	})
}

#ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
329
330
331
332
333
334
335
336

337
338

339
340
341
342
343


344
345
346
347
348
349
350
344
345
346
347
348
349
350

351
352

353
354
355
356
357

358
359
360
361
362
363
364
365
366







-
+

-
+




-
+
+







					[streamObserver
					    removeStreamForReading: stream];
					[readQueues removeObjectForKey: stream];
				}
			}
		} else {
#endif
			BOOL (*func)(id, SEL, OFStream*, void*, size_t,
			BOOL (*func)(id, SEL, OFStream*, void*, size_t, id,
			    OFException*) = (BOOL(*)(id, SEL, OFStream*, void*,
			    size_t, OFException*))
			    size_t, id, OFException*))
			    [queueItem->target methodForSelector:
			    queueItem->selector];

			if (!func(queueItem->target, queueItem->selector,
			    stream, queueItem->buffer, length, exception)) {
			    stream, queueItem->buffer, length,
			    queueItem->context, exception)) {
				[queue removeListObject: listObject];

				if ([queue count] == 0) {
					[streamObserver
					    removeStreamForReading: stream];
					[readQueues removeObjectForKey: stream];
				}
386
387
388
389
390
391
392
393
394
395



396
397
398
399
400
401
402

403
404
405
406
407
408
409
402
403
404
405
406
407
408



409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425







-
-
-
+
+
+






-
+







						    stream];
						[readQueues
						    removeObjectForKey: stream];
					}
				}
			} else {
#endif
				BOOL (*func)(id, SEL, OFStream*, void*,
				    size_t, OFException*) = (BOOL(*)(id, SEL,
				    OFStream*, void*, size_t, OFException*))
				BOOL (*func)(id, SEL, OFStream*, void*, size_t,
				    id, OFException*) = (BOOL(*)(id, SEL,
				    OFStream*, void*, size_t, id, OFException*))
				    [queueItem->target
				    methodForSelector: queueItem->selector];

				if (func(queueItem->target,
				    queueItem->selector, stream,
				    queueItem->buffer, queueItem->readLength,
				    exception))
				    queueItem->context, exception))
					queueItem->readLength = 0;
				else {
					[queue removeListObject: listObject];

					if ([queue count] == 0) {
						[streamObserver
						    removeStreamForReading:
445
446
447
448
449
450
451
452
453


454
455
456
457
458
459

460
461
462
463
464
465
466
461
462
463
464
465
466
467


468
469
470
471
472
473
474

475
476
477
478
479
480
481
482







-
-
+
+





-
+







						[readQueues
						    removeObjectForKey: stream];
					}
				}
			} else {
#endif
				BOOL (*func)(id, SEL, OFStream*, OFString*,
				    OFException*) = (BOOL(*)(id, SEL, OFStream*,
				    OFString*, OFException*))
				    id, OFException*) = (BOOL(*)(id, SEL,
				    OFStream*, OFString*, id, OFException*))
				    [queueItem->target methodForSelector:
				    queueItem->selector];

				if (!func(queueItem->target,
				    queueItem->selector, stream, line,
				    exception)) {
				    queueItem->context, exception)) {
					[queue removeListObject: listObject];

					if ([queue count] == 0) {
						[streamObserver
						    removeStreamForReading:
						    stream];
						[readQueues
495
496
497
498
499
500
501
502

503
504

505
506
507
508
509


510
511
512
513
514
515
516
511
512
513
514
515
516
517

518
519

520
521
522
523
524

525
526
527
528
529
530
531
532
533







-
+

-
+




-
+
+







					    removeStreamForReading: stream];
					[readQueues removeObjectForKey: stream];
				}
			}
		} else {
#endif
			BOOL (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    OFException*) =
			    id, OFException*) =
			    (BOOL(*)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    OFException*))
			    id, OFException*))
			    [queueItem->target methodForSelector:
			    queueItem->selector];

			if (!func(queueItem->target, queueItem->selector,
			    (OFTCPSocket*)stream, newSocket, exception)) {
			    (OFTCPSocket*)stream, newSocket, queueItem->context,
			    exception)) {
				[queue removeListObject: listObject];

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

Modified src/OFStream.h from [c7b337bee8] to [3161b39141].

130
131
132
133
134
135
136
137


138
139
140
141
142


143
144
145
146
147
148
149
130
131
132
133
134
135
136

137
138
139
140
141
142

143
144
145
146
147
148
149
150
151







-
+
+




-
+
+







 *		 data has been received. If the method returns YES, it will be
 *		 called again with the same buffer and maximum length when more
 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return NO
 *		 from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception).
 *		   id context, OFException *exception).
 * @param context A context to pass when the target gets called
 */
- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector;
		   selector: (SEL)selector
		    context: (id)context;

/*!
 * @brief Asyncronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
 *
 * Unlike @ref asyncReadIntoBuffer:length:block, this method does not call the
 * method when less than the specified length has been read - instead, it waits
157
158
159
160
161
162
163
164


165
166
167
168
169


170
171
172
173
174
175
176
159
160
161
162
163
164
165

166
167
168
169
170
171

172
173
174
175
176
177
178
179
180







-
+
+




-
+
+







 *		 data has been received. If the method returns YES, it will be
 *		 called again with the same buffer and exact length when more
 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return NO
 *		 from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception).
 *		   id context, OFException *exception).
 * @param context A context to pass when the target gets called
 */
 - (void)asyncReadIntoBuffer: (void*)buffer
		 exactLength: (size_t)length
		      target: (id)target
		    selector: (SEL)selector;
		    selector: (SEL)selector
		     context: (id)context;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asyncronously reads <i>at most</i> size bytes from the stream into a
 *	  buffer.
 *
 * On network streams, this might read less than the specified number of bytes.
568
569
570
571
572
573
574
575

576

577
578
579


580
581
582
583
584
585
586
587
588
589
590
591
592

593

594
595
596
597


598
599
600
601
602
603
604
572
573
574
575
576
577
578

579
580
581
582
583

584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603

604
605
606
607
608
609
610
611
612







-
+

+


-
+
+












-
+

+



-
+
+







 *
 * @param target The target on which to call the selector when the data has
 *		 been received. If the method returns YES, it will be called
 *		 again when the next line has been received. If you want the
 *		 next method in the queue to handle the next line, you need to
 *		 return NO from the method
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, OFString *line,
 *		   BOOL (OFStream *stream, OFString *line, id context,
 *		   OFException *exception).
 * @param context A context to pass when the target gets called
 */
- (void)asyncReadLineWithTarget: (id)target
		       selector: (SEL)selector;
		       selector: (SEL)selector
			context: (id)context;

/*!
 * @brief Asyncronously reads with the specified encoding until a newline, \\0,
 *	  end of stream or an exception occurs.
 *
 * @param encoding The encoding used by the stream
 * @param target The target on which to call the selector when the data has
 *		 been received. If the method returns YES, it will be called
 *		 again when the next line has been received. If you want the
 *		 next method in the queue to handle the next line, you need to
 *		 return NO from the method
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, OFString *line,
 *		   BOOL (OFStream *stream, OFString *line, id context,
 *		   OFException *exception).
 * @param context A context to pass when the target gets called
 */
- (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding
			   target: (id)target
			 selector: (SEL)selector;
			 selector: (SEL)selector
			  context: (id)context;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asyncronously reads until a newline, \\0, end of stream or an
 *	  exception occurs.
 *
 * @param block The block to call when the data has been received.

Modified src/OFStream.m from [cea01024de] to [a2b4bab0bd].

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







+





-
+
+






+





-
+
+







					    length: length - readLength];
}

- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector
		    context: (id)context
{
	[OFRunLoop OF_addAsyncReadForStream: self
				     buffer: buffer
				     length: length
				     target: target
				   selector: selector];
				   selector: selector
				    context: context];
}

- (void)asyncReadIntoBuffer: (void*)buffer
		exactLength: (size_t)length
		     target: (id)target
		   selector: (SEL)selector
		    context: (id)context
{
	[OFRunLoop OF_addAsyncReadForStream: self
				     buffer: buffer
				exactLength: length
				     target: target
				   selector: selector];
				   selector: selector
				    context: context];
}

#ifdef OF_HAVE_BLOCKS
- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		      block: (of_stream_async_read_block_t)block
{
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
744
745
722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752
753







+



-
+
+





+




-
+
+







			return nil;

	return line;
}

- (void)asyncReadLineWithTarget: (id)target
		       selector: (SEL)selector
			context: (id)context
{
	return [self asyncReadLineWithEncoding: OF_STRING_ENCODING_UTF_8
					target: target
				      selector: selector];
				      selector: selector
				       context: context];
}

- (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding
			   target: (id)target
			 selector: (SEL)selector
			  context: (id)context
{
	[OFRunLoop OF_addAsyncReadLineForStream: self
				       encoding: encoding
					 target: target
				       selector: selector];
				       selector: selector
					context: context];
}

#ifdef OF_HAVE_BLOCKS
- (void)asyncReadLineWithBlock: (of_stream_async_read_line_block_t)block
{
	return [self asyncReadLineWithEncoding: OF_STRING_ENCODING_UTF_8
					 block: block];

Modified src/OFTCPSocket.h from [e5cbeb8df7] to [9d3bdeb531].

134
135
136
137
138
139
140
141



142
143
144
145
146


147
148
149
150
151
152
153
134
135
136
137
138
139
140

141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156







-
+
+
+




-
+
+







 * @brief Asyncronously connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 * @param target The target on which to call the selector once the connection
 *		 has been established
 * @param selector The selector to call on the target. The signature must be
 *		   void (OFTCPSocket *socket, OFException *exception).
 *		   void (OFTCPSocket *socket, id context,
 *		   OFException *exception).
 * @param context A context to pass when the target gets called
 */
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector;
		  selector: (SEL)selector
		   context: (id)context;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asyncronously connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
194
195
196
197
198
199
200
201


202
203
204


205
206
207
208
209
210
211
197
198
199
200
201
202
203

204
205
206
207

208
209
210
211
212
213
214
215
216







-
+
+


-
+
+







 *
 * @param target The target on which to execute the selector when a new
 *		 connection has been accepted. The method returns whether the
 *		 next incoming connection should be accepted by the specified
 *		 block as well.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFTCPSocket *socket, OFTCPSocket *acceptedSocket,
 *		   OFException *exception).
 *		   id context, OFException *exception).
 * @param context A context to pass when the target gets called
 */
- (void)asyncAcceptWithTarget: (id)target
		     selector: (SEL)selector;
		     selector: (SEL)selector
		      context: (id)context;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asyncronously accept 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

Modified src/OFTCPSocket.m from [c453a27f56] to [bb02552c53].

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
113
114
115

116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136







+








-
+
+
















+










+







	OFString *host;
	uint16_t port;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_tcpsocket_async_connect_block_t connectBlock;
#endif
	id context;
	OFException *exception;
}

- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector;
	      selector: (SEL)selector
	       context: (id)context;
#ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		 block: (of_tcpsocket_async_connect_block_t)block;
#endif
@end

@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_
		target: (id)target_
	      selector: (SEL)selector_
	       context: (id)context_
{
	self = [super init];

	@try {
		sourceThread = [sourceThread_ retain];
		sock = [sock_ retain];
		host = [host_ copy];
		port = port_;
		target = [target_ retain];
		selector = selector_;
		context = [context_ retain];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







+














-
-
+
+


-
+







	[sourceThread release];
	[sock release];
	[host release];
	[target release];
#ifdef OF_HAVE_BLOCKS
	[connectBlock release];
#endif
	[context release];
	[exception release];

	[super dealloc];
}

- (void)didConnect
{
	[self join];

#ifdef OF_HAVE_BLOCKS
	if (connectBlock != NULL)
		connectBlock(sock, exception);
	else {
#endif
		void (*func)(id, SEL, OFTCPSocket*, OFException*) =
		    (void(*)(id, SEL, OFTCPSocket*, OFException*))[target
		void (*func)(id, SEL, OFTCPSocket*, id, OFException*) =
		    (void(*)(id, SEL, OFTCPSocket*, id, OFException*))[target
		    methodForSelector: selector];

		func(target, selector, sock, exception);
		func(target, selector, sock, context, exception);
#ifdef OF_HAVE_BLOCKS
	}
#endif
}

- (id)main
{
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438


439
440
441
442
443
444
445
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452







+









-
+
+







					port: destinationPort];
}

- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector
		   context: (id)context
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			  target: target
			selector: selector] autorelease] start];
			selector: selector
			 context: context] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

#ifdef OF_HAVE_BLOCKS
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
647
648
649
650
651
652
653

654
655
656
657


658
659
660
661
662
663
664
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673







+



-
+
+







	newSocket->sockAddrLen = addrLen;

	return newSocket;
}

- (void)asyncAcceptWithTarget: (id)target
		     selector: (SEL)selector
		      context: (id)context
{
	[OFRunLoop OF_addAsyncAcceptForTCPSocket: self
					  target: target
					selector: selector];
					selector: selector
					 context: context];
}

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