#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    48
    Rep Power
    2

    How to free memory after recieving a signal


    Functions whose address is passed to signal handlers have to be of type:

    void termination_handler(int signum)

    So how do I free memory and close files after receiving a signal?
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<signal.h>
    
    volatile sig_atomic_t interrupted = 0;
    volatile sig_atomic_t watchdog = 0;
    
    void handler ( int sig ) {
      if ( sig == SIGINT ) {
        if ( watchdog == 1 ) {
          const char *msg = "Locked up - bailing out\n";
          write(1,msg,strlen(msg));
          exit(1);
        }
        interrupted = 1;
        watchdog = 1;
        signal(SIGINT,handler);
      }
    }
    
    #define MIL (1000*1000)
    void getBusy ( ) {
      int k = 0;
      for ( int i = 0 ; i < 20 && !interrupted ; i++ ) {
        for ( int j = 0 ; j < 600 * MIL ; j++ ) {
          k += 1;
          if ( (j % (300 * MIL)) == 0 ) watchdog = 0;
        }
        printf("Result so far=%d, dog=%d\n", k, watchdog);
      }
    }
    
    int main(void)
    {
      signal(SIGINT,handler);
      getBusy();
      if ( interrupted ) {
        printf("Cleanup\n");
      }
      return 0;
    }
    The things you can call in a signal handler are restricted to certain system level calls.
    See "Async-signal-safe functions" in http://man7.org/linux/man-pages/man7/signal.7.html

    In the example, the watchdog provides a fine level of control to make sure the program is still running. If the program has locked up for some reason, the signal handler will be invoked (on the second SIGINT) with the watchdog set. At this point, all is lost so the only thing to do is bail out.

    Otherwise, the signal handler sets the interrupted flag, which is tested by the program at convenient places where an orderly exit is possible. Note that you could use setjmp() / longjmp() to return from a deeply nested function call without having to test the interrupted flag every step of the way.

    Once in main(), or wherever your main control loop is located, you can arrange the final resource cleanup.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    48
    Rep Power
    2
    I don't think you quit understood my question.
    I have allocate memory AN_ALLOCATED_STRING and I have stream MY_FILE.
    I don't care where in the program I'm interrupted but what I do want is for MY_FILE to be closed and AN_ALLOCATED_STRING to be freed.
    Now aside from making the stream and string global I don't see how I'm going to free and close them as I can't pass them to the function

    void termination_handler(int signum)

    because it only takes an int.
    If I wanted to pause and wait until I came to a convenient stopping place there's lots of info about that in the glibc reference manual.

    Also if I use longjmp to the end of my function or the beginning (In either case checking for an error,) would the state that I received the signal in still be there?
    In other words, would the variable AN_ALLOCATED_STRING still be pointing to the allocated memory?
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    So make them global and be done with it.

    Except your program would be broken if you did.
    Neither fclose() nor free() are on the async safe function list, so you can't call either of them from a signal handler.

    So the only think you can really do is acknowledge the signal and perform an orderly exit from your program as I showed.

    Or you just call exit() from your signal handler, and let the OS deal with the file closure and memory cleanup (which it will do).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    48
    Rep Power
    2
    I did not think that the OS would do that, Thanks.

IMN logo majestic logo threadwatch logo seochat tools logo