I am currently working on a program using IOBluetooth, and I need to have synchronous reads, i.e. I call the method, it writes the specified number of bytes to the port, then reads the given number and returns them. I currently have a complex system of NSThreads, NSLocks, and NSConditions, which, although it works, is very slow. In addition, after certain calls, I need to make sure that there is no extra data, so I would just flush the buffer, but with an asynchronous IOBluetooth callback, which is impossible - any thoughts on how to make sure that regardless of all the data received after Is a specific point the data received after this point?
I really did not deal with synchronization and multithreading of this type, since all the work that I have done so far uses synchronous calls, so I will be grateful for any thoughts on this issue.
Here's the callback for incoming data (the "incomingData" object is NSMutableData):
- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength { [dataLock lock]; NSData *data = [NSData dataWithBytes:dataPointer length:dataLength]; [incomingData appendData:data]; if (dataWaitCondition && [incomingData length] >= bytesToWaitFor) { [dataWaitCondition signal]; } [dataLock unlock]; [delegate bluetoothDataReceived]; }
And here is a method that waits until a given number of bytes is received before returning a data object (it is called from an alternative stream).
- (NSData *)waitForBytes:(int)numberOfBytes { bytesToWaitFor = numberOfBytes; [dataLock lock]; dataWaitCondition = [[NSCondition alloc] init]; [dataWaitCondition lock]; [dataLock unlock]; while ([incomingData length] < numberOfBytes) { [dataWaitCondition wait]; } [dataLock lock]; NSData *data = [incomingData copy]; [dataWaitCondition unlock]; dataWaitCondition = NULL; [dataLock unlock]; return data; }
source share