Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I exit [NSRunLoop runUntilDate]?

I am writing an application which has to communicate with a device connected via USB. The app sends and receives data in turns from the device on a fixed timing. All Rx/Tx happens in a separate thread because otherwise the UI would be blocked. The basic structure looks basically like this. (autorelease pools and stuff omitted)

-(void)comThread:(id)arg {
  while(state == kIsConnected) {
    // let timers run
    [runLoop runUntilDate:[NSDate distantFuture]];
    // handle data
    if(rxTxState == kRx) {
      // do some stuff to pass data to upper layers
      rxTxState = kTx;
    }
    if(rxTxState == kTx) {
      // do some stuff to send data
      rxTimeoutTimer = [NSTimer scheduledTimer....];
    }
  } 
}

After sending data, the app waits for either data to be received or the rxTimeoutTimer to fire which leads to retransmission of the packet. The rx-operation works since the underlying layers use async system calls and calls a rx-handler which look basically like this.

-(void)receiveData:(NSData*)data{
  [rxQueue addObject:data];
  [rxTimeoutTimer invalidate];  // cancel timeout
}

Is there an (easy) way to make the [runLoop runUntilDate:] exit from receiveData:? The Apple docs say that removing all timer sources does not guarantee the RunLoop to exit. I read something about calling performSelector:onThread:... but it either did not work or I did not get the point.

Thanks.

like image 1000
insanelygreat Avatar asked Oct 24 '25 17:10

insanelygreat


2 Answers

CFRunLoopStop([runLoop getCFRunLoop]);
like image 116
kennytm Avatar answered Oct 26 '25 07:10

kennytm


The standard pattern is to run the runloop for some timeout period (e.g. 0.5 seconds), and then iterate until the task is accomplished:

while(state == kIsConnected) {
  while(!iterationDone) {
    [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
    //do other stufff
  }
}

-(void)receiveData:(NSData*)data{
  [rxQueue addObject:data];
  [rxTimeoutTimer invalidate];  // cancel timeout
  iterationDone = YES;
}
like image 40
Barry Wark Avatar answered Oct 26 '25 06:10

Barry Wark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!