/*
 * signal-loop.m - use NSRunLoop as well as react on UNIX signals
 *
 * Author:  Michael Weber <michaelw@foldr.org>
 * Date:    2002-05-20
 * Version: 0.1
 */


#import <Foundation/Foundation.h>
#import <Foundation/NSRunLoop.h>
#import <Foundation/NSTimer.h>

#include <signal.h>

// boring callback object
@interface MyDelegate : NSObject
- (void) callee: (NSTimer *)timer;
@end

@implementation MyDelegate
- (void) callee: (NSTimer *)timer
{
    NSLog(@"Timer called %@ with userInfo: %@", timer, [timer userInfo]);
}
@end



// global var to check that signal arrived
static volatile BOOL caughtSIGINT = NO;
// restarting signal handler
void
handle_SIGINT (int signum)
{
    void (*oldsig)(int);

    caughtSIGINT = YES;

    // only for SVID compatibility, not needed on BSD/GNU
    if ((oldsig = signal (signum, handle_SIGINT)) != handle_SIGINT) {
        // someone else registered in the mean time, so we step down
        signal (signum, oldsig);
    }
}


int
main (int argc, char *argv[])
{
    signal (SIGHUP,  SIG_IGN);
    signal (SIGUSR1, SIG_IGN);
    signal (SIGUSR2, SIG_IGN);
    // NOTE:
    //
    //   don't use sigaction()'s SA_RESTART for this, since on SVR4
    //   select()/poll() gets restarted as well -> we'd never see the
    //   signal.
    signal (SIGINT,  handle_SIGINT);

    CREATE_AUTORELEASE_POOL(pool);

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    MyDelegate *foo = [[[MyDelegate alloc] init] autorelease];

    NSLog (@"Starting");


    // some action to see that the loop really loops :)
    [[[NSTimer
          scheduledTimerWithTimeInterval: 5.0
          target: foo
          selector: @selector(callee:)
          userInfo: @"payload"
          repeats: YES ] autorelease] fire];

    //  instead of [runLoop run]; now do:
    BOOL isRunning;
    do {
        NSLog(@"looping");
        isRunning = [runLoop runMode: NSDefaultRunLoopMode
                             beforeDate: [NSDate distantFuture]];

        if (caughtSIGINT) {
            NSLog (@"caught SIGINT - exiting...");
            exit (1);
        }
    } while (isRunning);

    NSLog (@"Normal exit");

    RELEASE(pool);

    exit (0);
}