// ============================================================================
//
// = LIBRARY
// examples/NT_Service
//
// = FILENAME
// ntsvc.cpp
//
// = DESCRIPTION
// This is the implementation of the NT service. It beeps every 2
// seconds until the service is stopped.
//
// = AUTHOR
// Gonzalo Diethelm <gonzo@cs.wustl.edu>
// and Steve Huston <shuston@riverace.com>
//
// ============================================================================
// Schedule a timer every two seconds.
ACE_Time_Value tv (2, 0);
ACE_Reactor::instance ()->schedule_timer (this, 0, tv, tv);
}
// This method is called when the service gets a control request. It
// handles requests for stop and shutdown by calling terminate ().
// All others get handled by calling up to inherited::handle_control.
// This is just here to be the target of the notify from above... it
// doesn't do anything except aid on popping the reactor off its wait
// and causing a drop out of handle_events.
int
Service::handle_exception (ACE_HANDLE)
{
return 0;
}
// Beep every two seconds. This is what this NT service does...
// This is the main processing function for the Service. It sets up
// the initial configuration and runs the event loop until a shutdown
// request is received.
int
Service::svc (void)
{
ACE_DEBUG ((LM_DEBUG,
"Service::svc\n"));
// As an NT service, we come in here in a different thread than the
// one which created the reactor. So in order to do anything, we
// need to own the reactor. If we are not a service, report_status
// will return -1.
if (report_status (SERVICE_RUNNING) == 0)
reactor ()->owner (ACE_Thread::self ());
// ============================================================================
//
// = LIBRARY
// examples/NT_Service
//
// = FILENAME
// ntsvc.h
//
// = DESCRIPTION
// This is the definition of the sample NT Service class. This example
// only runs on Win32 platforms.
//
// = AUTHOR
// Gonzalo Diethelm and Steve Huston
//
// ============================================================================
class Service : public ACE_NT_Service
{
public:
Service (void);
virtual void handle_control (DWORD control_code);
// We override <handle_control> because it handles stop requests
// privately.
virtual int handle_exception (ACE_HANDLE h);
// We override <handle_exception> so a 'stop' control code can pop
// the reactor off of its wait.
virtual int svc (void);
// This is a virtual method inherited from ACE_NT_Service.
virtual int handle_timeout (const ACE_Time_Value& tv,
const void *arg = 0);
// Where the real work is done:
private:
typedef ACE_NT_Service inherited;
private:
int stop_;
};
// Define a singleton class as a way to insure that there's only one
// Service instance in the program, and to protect against access from
// multiple threads. The first reference to it at runtime creates it,
// and the ACE_Object_Manager deletes it at run-down.
// ============================================================================
//
// = LIBRARY
// examples/NT_Service
//
// = FILENAME
// main.cpp
//
// = DESCRIPTION
// This is the main program - it just hands control off to the
// process instance to figure out what to do. This program only
// runs on Win32.
//
// = AUTHOR
// Gonzalo Diethelm <gonzo@cs.wustl.edu>
// and Steve Huston <shuston@riverace.com>
//
// ============================================================================
#include "ace/Get_Opt.h"
#include "ntsvc.h"
// Default for the -i (install) option
#define DEFAULT_SERVICE_INIT_STARTUP SERVICE_AUTO_START
class Process
{
public:
Process (void);
~Process (void);
void
Process::print_usage_and_die (void)
{
ACE_DEBUG ((LM_INFO,
"Usage: %s"
" -in -r -s -k -tn -d\n"
" -i: Install this program as an NT service, with specified startup\n"
" -r: Remove this program from the Service Manager\n"
" -s: Start the service\n"
" -k: Kill the service\n"
" -t: Set startup for an existing service\n"
" -d: Debug; run as a regular application\n",
progname,
0));
ACE_OS::exit(1);
}
while ((c = get_opt ()) != -1)
switch (c)
{
case 'i':
opt_install = 1;
opt_startup = ACE_OS::atoi (get_opt.optarg);
if (opt_startup <= 0)
print_usage_and_die ();
break;
case 'r':
opt_remove = 1;
break;
case 's':
opt_start = 1;
break;
case 'k':
opt_kill = 1;
break;
case 't':
opt_type = 1;
opt_startup = ACE_OS::atoi (get_opt.optarg);
if (opt_startup <= 0)
print_usage_and_die ();
break;
case 'd':
opt_debug = 1;
break;
default:
// -i can also be given without a value - if so, it defaults
// to defined value.
if (ACE_OS::strcmp (get_opt.argv_[get_opt.optind-1], ACE_TEXT ("-i")) == 0)
{
opt_install = 1;
opt_startup = DEFAULT_SERVICE_INIT_STARTUP;
}
else
{
print_usage_and_die ();
}
break;
}
}
// Define a function to handle Ctrl+C to cleanly shut this down.