Search code examples
cunixsleepgetchar

Why some function could reduce sleep(n) into sleep(0)?


I have a very strange problem in C. A function from a proprietary library reduces sleep(n) to sleep(0).

My code looks like:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>  /*sleep() */

int main(int argc, char** argv){
   //...
   AStreamEngine.init();
   AStreamEngine.setCodec(3);

   AStreamEngine.start(); //problematic function

   printf("a");
   sleep(100);
   printf("b");
   return 0;
}

If the problematic function is commented out, then printing "a" follows by printing "b" after 100 sec. But if isn't commented out, "ab" is printed. So the program ends very quickly and I cannot notice if the engine works.

I found that:

  1. if I replace sleep() by getchar() the engine works correctly.
  2. if I put active waiting by a for-loop then it also works.

Does anyone have any idea why happens? And how to fix (bypass) this feature/bug? I don't want use getchar and active waiting.

Update: I don't have source of the library. I have only binary .so file.

Base on responces I add a below code add end:

struct timespec to_sleep = { 1, 0 }; 
int ret = nanosleep(&to_sleep,&to_sleep);
printf("%d\n",ret);
if(ret == -1){
    printf(" break sleep : %d %s", errno,strerror(errno));
}

And I get output:

-1
break sleep : 4 Interrupted system callc

Now I try to bypass by thread.


Solution

  • As rightly said by Jack, usleep and sleep can be interrupted by the delivery of signals (E.g presence of ioctl, read, write function calls).

    One of the smart way to avoid this issue is to use nanosleep. Like sleep and usleep, nanosleep can also be interrupted by the delivery of signals but the difference is, its second argument tells you how much time is remaining.

    You can use this argument to make sure your code sleeps for the specified amount of time. Replace your sleep and usleep function with a while loop containing nanosleep. Following is the example usage,

    struct timespec to_sleep = { 1, 0 }; // Sleep for 1 second
    while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)); 
    

    Off course this solutions is not suitable for the application where exact amount sleep is required but it is very useful in the cases where minimum delay is required before executing next function.