@@ -146,8 +146,9 @@ @interface GCDAsyncUdpSocket ()
146
146
id delegate;
147
147
dispatch_queue_t delegateQueue;
148
148
149
- GCDAsyncUdpSocketReceiveFilterBlock filterBlock;
150
- dispatch_queue_t filterQueue;
149
+ GCDAsyncUdpSocketReceiveFilterBlock receiveFilterBlock;
150
+ dispatch_queue_t receiveFilterQueue;
151
+ BOOL receiveFilterAsync;
151
152
152
153
uint32_t flags;
153
154
uint16_t config;
@@ -3921,33 +3922,35 @@ - (void)pauseReceiving
3921
3922
dispatch_async (socketQueue, block);
3922
3923
}
3923
3924
3924
- - (void )setReceiveFilter : (GCDAsyncUdpSocketReceiveFilterBlock)inFilterBlock withQueue : (dispatch_queue_t )inFilterQueue
3925
+ - (void )setReceiveFilter : (GCDAsyncUdpSocketReceiveFilterBlock)filterBlock withQueue : (dispatch_queue_t )filterQueue
3925
3926
{
3926
- GCDAsyncUdpSocketReceiveFilterBlock newFilterBlock;
3927
- dispatch_queue_t newFilterQueue;
3927
+ [self setReceiveFilter: filterBlock withQueue: filterQueue isAsynchronous: YES ];
3928
+ }
3929
+
3930
+ - (void )setReceiveFilter : (GCDAsyncUdpSocketReceiveFilterBlock)filterBlock
3931
+ withQueue : (dispatch_queue_t )filterQueue
3932
+ isAsynchronous : (BOOL )isAsynchronous
3933
+ {
3934
+ GCDAsyncUdpSocketReceiveFilterBlock newFilterBlock = NULL ;
3935
+ dispatch_queue_t newFilterQueue = NULL ;
3928
3936
3929
- if (inFilterBlock )
3937
+ if (filterBlock )
3930
3938
{
3931
- NSAssert (inFilterQueue , @" Must provide a dispatch_queue in which to run the filter block." );
3939
+ NSAssert (filterQueue , @" Must provide a dispatch_queue in which to run the filter block." );
3932
3940
3933
- newFilterBlock = [inFilterBlock copy ];
3934
- newFilterQueue = inFilterQueue ;
3941
+ newFilterBlock = [filterBlock copy ];
3942
+ newFilterQueue = filterQueue ;
3935
3943
dispatch_retain (newFilterQueue);
3936
3944
}
3937
- else
3938
- {
3939
- newFilterBlock = NULL ;
3940
- newFilterQueue = NULL ;
3941
- }
3942
3945
3943
3946
dispatch_block_t block = ^{
3944
3947
3948
+ if (receiveFilterQueue)
3949
+ dispatch_release (receiveFilterQueue);
3945
3950
3946
- if (filterQueue)
3947
- dispatch_release (filterQueue);
3948
-
3949
- filterBlock = newFilterBlock;
3950
- filterQueue = newFilterQueue;
3951
+ receiveFilterBlock = newFilterBlock;
3952
+ receiveFilterQueue = newFilterQueue;
3953
+ receiveFilterAsync = isAsynchronous;
3951
3954
};
3952
3955
3953
3956
if (dispatch_get_current_queue () == socketQueue)
@@ -4116,7 +4119,8 @@ - (void)doReceive
4116
4119
4117
4120
4118
4121
BOOL waitingForSocket = NO ;
4119
- BOOL ignoredDueToAddress = NO ;
4122
+ BOOL notifiedDelegate = NO ;
4123
+ BOOL ignored = NO ;
4120
4124
4121
4125
NSError *error = nil ;
4122
4126
@@ -4136,60 +4140,78 @@ - (void)doReceive
4136
4140
if (flags & kDidConnect )
4137
4141
{
4138
4142
if (addr4 && ![self isConnectedToAddress4: addr4])
4139
- ignoredDueToAddress = YES ;
4143
+ ignored = YES ;
4140
4144
if (addr6 && ![self isConnectedToAddress6: addr6])
4141
- ignoredDueToAddress = YES ;
4145
+ ignored = YES ;
4142
4146
}
4143
4147
4144
4148
NSData *addr = (addr4 != nil ) ? addr4 : addr6;
4145
4149
4146
- if (!ignoredDueToAddress )
4150
+ if (!ignored )
4147
4151
{
4148
- if (filterBlock && filterQueue )
4152
+ if (receiveFilterBlock && receiveFilterQueue )
4149
4153
{
4150
4154
// Run data through filter, and if approved, notify delegate
4151
- pendingFilterOperations++;
4152
4155
4153
- dispatch_async (filterQueue, ^{ @autoreleasepool {
4154
-
4155
- id filterContext = nil ;
4156
- BOOL allowed = filterBlock (data, addr, &filterContext);
4157
-
4158
- // Transition back to socketQueue to get the current delegate / delegateQueue
4159
-
4160
- dispatch_async (socketQueue, ^{ @autoreleasepool {
4161
-
4162
- pendingFilterOperations--;
4156
+ __block id filterContext = nil ;
4157
+ __block BOOL allowed = NO ;
4158
+
4159
+ if (receiveFilterAsync)
4160
+ {
4161
+ pendingFilterOperations++;
4162
+ dispatch_async (receiveFilterQueue, ^{ @autoreleasepool {
4163
4163
4164
- if (allowed)
4165
- {
4166
- [self notifyDidReceiveData: data fromAddress: addr withFilterContext: filterContext];
4167
- }
4164
+ allowed = receiveFilterBlock (data, addr, &filterContext);
4168
4165
4169
- if (flags & kReceiveOnce )
4170
- {
4166
+ // Transition back to socketQueue to get the current delegate / delegateQueue
4167
+ dispatch_async (socketQueue, ^{ @autoreleasepool {
4168
+
4169
+ pendingFilterOperations--;
4170
+
4171
4171
if (allowed)
4172
4172
{
4173
- // The delegate has been notified,
4174
- // so our receive once operation has completed.
4175
- flags &= ~kReceiveOnce ;
4173
+ [self notifyDidReceiveData: data fromAddress: addr withFilterContext: filterContext];
4176
4174
}
4177
- else if (pendingFilterOperations == 0 )
4175
+
4176
+ if (flags & kReceiveOnce )
4178
4177
{
4179
- // All pending filter operations have completed,
4180
- // and none were allowed through.
4181
- // Our receive once operation hasn't completed yet.
4182
- [self doReceive ];
4178
+ if (allowed)
4179
+ {
4180
+ // The delegate has been notified,
4181
+ // so our receive once operation has completed.
4182
+ flags &= ~kReceiveOnce ;
4183
+ }
4184
+ else if (pendingFilterOperations == 0 )
4185
+ {
4186
+ // All pending filter operations have completed,
4187
+ // and none were allowed through.
4188
+ // Our receive once operation hasn't completed yet.
4189
+ [self doReceive ];
4190
+ }
4183
4191
}
4184
- }
4192
+ }});
4193
+ }});
4194
+ }
4195
+ else // if (!receiveFilterAsync)
4196
+ {
4197
+ dispatch_sync (receiveFilterQueue, ^{ @autoreleasepool {
4198
+
4199
+ allowed = receiveFilterBlock (data, addr, &filterContext);
4185
4200
}});
4186
4201
4187
- }});
4202
+ if (allowed) {
4203
+ [self notifyDidReceiveData: data fromAddress: addr withFilterContext: filterContext];
4204
+ notifiedDelegate = YES ;
4205
+ }
4206
+ else {
4207
+ ignored = YES ;
4208
+ }
4209
+ }
4188
4210
}
4189
- else
4211
+ else // if (!receiveFilterBlock || !receiveFilterQueue)
4190
4212
{
4191
- // Notify delegate
4192
4213
[self notifyDidReceiveData: data fromAddress: addr withFilterContext: nil ];
4214
+ notifiedDelegate = YES ;
4193
4215
}
4194
4216
}
4195
4217
}
@@ -4219,16 +4241,20 @@ - (void)doReceive
4219
4241
else
4220
4242
{
4221
4243
// One-at-a-time receive mode
4222
- if (ignoredDueToAddress)
4223
- {
4224
- [self doReceive ];
4225
- }
4226
- else if (pendingFilterOperations == 0 )
4244
+ if (notifiedDelegate)
4227
4245
{
4228
4246
// The delegate has been notified (no set filter).
4229
4247
// So our receive once operation has completed.
4230
4248
flags &= ~kReceiveOnce ;
4231
4249
}
4250
+ else if (ignored)
4251
+ {
4252
+ [self doReceive ];
4253
+ }
4254
+ else
4255
+ {
4256
+ // Waiting on asynchronous receive filter...
4257
+ }
4232
4258
}
4233
4259
}
4234
4260
}
0 commit comments