user1725145
user1725145

Reputation: 4042

How to implement a while loop with timeout?

I want to implement a while loop that exits either when a particular condition is met, or when a timer times out. If I just start the timer (to set an object variable on timeout), and then start the while loop (checking the object variable), it doesn't work, because the timer never times out.

I've tried 3 of the solutions suggested in How to wait for a thread to finish in Objective-C to make the loop run in a separate function on another thread, but they fail in various different ways. I have not yet managed to get a test run where the timer times out.

The simple implementation was

//object variable
BOOL m_readTimedOut;

- (void) someFunction
{
m_readTimedOut = NO;
float timeoutS = 0.1;

//Start the timer
SEL readTimeoutSelector = sel_registerName("onReadTimeout:");
    [NSTimer scheduledTimerWithTimeInterval:timeoutS
                                            target:self
                                            selector:readTimeoutSelector
                                            userInfo:nil
                                            repeats:NO];

int numBytesToRead = 1;
BOOL exit = NO;
int counter = 0;
    while ((counter < numBytesToRead) && (exit == NO))
    {

        @try
        {
            @synchronized (readBufferLock)
            {
                //m_readBuffer is an object variable that can be altered on another thread
                if ([m_readBuffer length] > 0)
                {
                    //Do stuff here
                    counter++;
                }
            } //end synchronised
        }
        @catch (NSException *exception)
        {
            //Log exception
        }

        if (counter == numBytesToRead || m_readTimedOut == YES)
        {
            exit = YES;
        }
    } //end while
}


- (void)onReadTimeout:(NSTimer *)timer
{
    NSLog(@"Read timer timed out");
    m_readTimedOut = YES;
}

Upvotes: 0

Views: 1368

Answers (1)

skaak
skaak

Reputation: 3018

Just a try on the timed exit only - how about

NSDate * start = [[NSDate alloc] init]; // When we started

while ( counter < something )
{
  // do stuff ...

  // Check time
  NSDate * now = [[NSDate alloc] init];

  // Been here more than 10s since start
  if ( [now timeIntervalSinceDate:start] > 10 )
  {
    // Timed exit
    break;
  }
}

Upvotes: 1

Related Questions