This is the scenario: I want to add an observer to monitor events & when an event is triggered & processed, I wait for the result in callback block, if result is fine, I do other task. If wait timeout, I just print error message.
I use semaphore to achieve the above thing with the following simple code:
-(void)waitForResultThenDoOtherTask {
BOOL shouldPrintErr = NO;
// I create a semaphore
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// I have an observer with a callback, the callback is triggered when event is observed & result is passed to callback
[self addObserver:myObserver withCallback:callback];
id callback = ^(BOOL result) {
// if result is YES, I signal semaphore, otherwise, set shouldPrintErr flag to YES
if (result) {
dispatch_semaphore_signal(semaphore);
} else {
shouldPrintErr = YES;
}
}
// wait until timeout
dispatch_time_t timeOut = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC));
dispatch_semaphore_wait(semaphore, timeOut);
if (shouldPrintErr) {
NSLog(@"TIME OUT!!!");
} else {
// do other task
[self doOtherTask];
}
}
I call the above function in another class like this:
// 1st call
[object waitForEventThenDoOtherTask];
// this function delete local files (in another thread)
[self deleteLocalFileInAnotherThread];
// 2nd call
[object waitForEventThenDoOtherTask];
The 1st call works fine, when event is triggered and result
is YES
, semaphore gets the signal and waiting stops, doOtherTask
is called, everything works as expected.
But for the 2nd call, when event is triggered, result
is YES
, semaphore gets signal, but the code is still waiting until timeout, then timeout error is printed.
Why? Why the 2nd time call code still waiting for semaphore even though semaphore gets the signal? What could be the possible reason in this context? And how to make the 2nd call work as expected as well?
===== UPDATE: I found the reason, but how to fix? ====
I realize that the callback get called multiple times, which means the same semaphore has been signaled multiple times. I think that is the reason for my problem. But, how to get rid of this problem? What is the solution then?