/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : deleteTest.cc                                                 */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

class Test {

public:

  Test(const char *name);
  virtual ~Test();

  void run();

private:

  const char *_name;

  ////////////////////////////////////////////////////////////////////
  // signal handler
  static void signalHandler(int signalNo);

  ////////////////////////////////////////////////////////////////////
  // cleanup
  static void cleanup();

  ////////////////////////////////////////////////////////////////////
  // Points to most recently created Test object. There should only
  // be one of these per process.
  static Test *_theTestObject;
};


Test *Test::_theTestObject = 0;


Test::Test(const char *name)
{
  _name = strdup(name);

  // Keep track of the most recently created Test object, 
  // for cleanup on signal/exit
  _theTestObject = this;

  fprintf(stderr, 
	  "Test::Test() \"%s\" - _theTestObject=0x%x\n", name, _theTestObject);

  signal(SIGINT, Test::signalHandler);
  signal(SIGTERM, Test::signalHandler);
  signal(SIGQUIT, Test::signalHandler);
}



Test::~Test()
{
  fprintf(stderr, "Test::~Test()...\n");
  free((void *)_name);
  fprintf(stderr, "Test::~Test() - done\n");
}



void Test::signalHandler(int signalNo)
{
  fprintf(stderr, "Test::signalHandler() for task %s\n", 
	  _theTestObject->_name);

  Test::cleanup();

  fprintf(stderr, "Test::signalHandler() - done, now exit()\n");
  
  exit(1);
}


void Test::cleanup()
{
  fprintf(stderr, 
	  "Task::cleanup() - delete _theTestObject=0x%x (named %s)\n", 
	  _theTestObject, _theTestObject->_name);

  delete _theTestObject;

  _theTestObject = 0;

  fprintf(stderr, "Test::cleanup() - kill all processes in group\n");

  // Block SIGNINT handling, as we are about to send SIGINT to all
  // processes in group.
  signal(SIGINT, SIG_IGN);

  // Kill all processes in group
  kill(0, SIGINT);

  fprintf(stderr, "Test::cleanup() - done\n");
}



void Test::run()
{
  // Loop forever
  while (1) {
    fprintf(stderr, "running...\n");
    sleep(1);
  }
}



class MyTest : public Test {

public :

  MyTest();
  virtual ~MyTest();

protected:

  int _a;
};


MyTest::MyTest()
  : Test("myTest")
{
  _a = 1;
}


MyTest::~MyTest()
{
  fprintf(stderr, "MyTest::~MyTest()...\n");
  _a = 0;
  fprintf(stderr, "MyTest::~MyTest() - done\n");
}



int main(int argc, char **argv)
{
  MyTest *test = new MyTest();

  test->run();

  delete test;

  // Normal termination
  return 0;
}






