feisty meow concerns codebase 2.140
hoople_service.cpp
Go to the documentation of this file.
1
2// Name : hoople_service
3// Author : Chris Koeritz
5// Copyright (c) 2000-$now By Author. This program is free software; you can
6// redistribute it and/or modify it under the terms of the GNU General Public
7// License as published by the Free Software Foundation:
8// http://www.gnu.org/licenses/gpl.html
9// or under the terms of the GNU Library license:
10// http://www.gnu.org/licenses/lgpl.html
11// at your preference. Those licenses describe your legal rights to this
12// software, and no other rights or warranties apply.
13// Please send updates for this code to: fred@gruntose.com -- Thanks, fred.
15
16#include "hoople_service.h"
17
18#include <basis/array.h>
19#include <basis/mutex.h>
20#include <filesystem/filename.h>
25#include <structures/set.h>
27#include <timely/time_control.h>
28#include <timely/time_stamp.h>
29#include <timely/timer_driver.h>
30
31#include <signal.h>
32
33using namespace basis;
34using namespace filesystem;
35using namespace loggers;
36using namespace processes;
37using namespace structures;
38using namespace timely;
39
40//#define DEBUG_HOOPLE_SERVICE
41 // uncomment for noisy version.
42
43#undef LOG
44#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
45
46namespace application {
47
49
50SAFE_STATIC(astring, hoople_service::_app_name, )
51
52bool &hoople_service::_defunct() { static bool _defu = false; return _defu; }
53
54bool &hoople_service::_saw_interrupt()
55{ static bool _saw = false; return _saw; }
56
57int &hoople_service::_timer_period() { static int _tim = 0; return _tim; }
58
60
61static hoople_service *_global_hoople_service = NULL_POINTER;
62 // this static object is set by the setup() method. it should only come
63 // into existence once during a program's lifetime.
64
68
70{
72 if (_global_hoople_service) {
73 program_wide_timer().zap_timer(_global_hoople_service);
74 }
75}
76
77void hoople_service::handle_startup() { /* nothing for base class. */ }
78
79void hoople_service::handle_shutdown() { /* nothing for base class. */ }
80
81void hoople_service::handle_timer() { /* nothing for base class. */ }
82
83void hoople_service::handle_timer_callback()
84{
85 // don't invoke the user's timer unless the object is still alive.
86 if (!is_defunct()) handle_timer();
87}
88
93
95{
96 FUNCDEF("close_application");
98 process_control querier;
99
100 // lookup process ids of apps.
101 bool got_list = querier.query_processes(procs);
102 if (!got_list) {
103 LOG(astring("couldn't get process list."));
104 return false;
105 }
106 int_set pids;
107 got_list = querier.find_process_in_list(procs, app_name, pids);
108 if (!got_list) {
109 LOG(astring("couldn't find process in the list of active ones."));
110 return true;
111 }
112
113 // zap all of them using our signal.
114 for (int i = 0; i < pids.length(); i++) {
115//hmmm: would linux be better served with sigterm instead, like we used to do for windoze?
116//#ifndef _MSC_VER
117 kill(pids[i], SIGHUP);
118//#else
120// raise(SIGTERM);
121//#endif
122//hmmm: check results...
123 }
124
125 return true;
126}
127
129{
130 _saw_interrupt() = true; // save the status.
131 if (_global_hoople_service) {
132 _global_hoople_service->close_this_program();
133 }
134}
135
137{
138 _defunct() = true;
139}
140
141bool hoople_service::setup(const astring &app_name, int timer_period)
142{
143//hmmm: make sure not already initted.
144
145 // simple initializations first...
146 _timer_period() = timer_period;
147 _app_name() = app_name;
148
149 _global_hoople_service = this;
150
151 // setup signal handler for HUP signal. this is the one used to tell us
152 // to leave.
153//#ifndef _MSC_VER
154 signal(SIGHUP, handle_OS_signal);
155//#endif
156
157 // setup a handler for interrupt (e.g. ctrl-C) also.
158 signal(SIGINT, handle_OS_signal);
159//#ifdef _MSC_VER
160// signal(SIGBREAK, handle_OS_signal);
161//#endif
162
163 return true;
164}
165
167 const astring &app_name, int timer_period)
168{
169#ifdef DEBUG_HOOPLE_SERVICE
170 FUNCDEF("launch_console");
171#endif
172 if (!alert.setup(app_name, timer_period)) return false;
173
174 alert.handle_startup(); // tell the program it has started up.
175
176 // start a timer if they requested one.
177 if (_timer_period()) {
178 program_wide_timer().set_timer(_timer_period(), &alert);
179 }
180
181#ifdef DEBUG_HOOPLE_SERVICE
182 time_stamp next_report(10 * SECOND_ms);
183#endif
184
185 while (!alert.is_defunct()) {
186#ifdef DEBUG_HOOPLE_SERVICE
187 if (time_stamp() >= next_report) {
188 printf("%s: shout out from my main thread yo.\n", _global_argv[0]);
189 next_report.reset(10 * SECOND_ms);
190 }
191#endif
193 }
194 alert.handle_shutdown();
195 return true;
196}
197
198/*
199#ifdef __WIN32__
200bool hoople_service::launch_event_loop(hoople_service &alert,
201 const astring &app_name, int timer_period)
202{
203 if (!alert.setup(app_name, timer_period)) return false;
204 alert.handle_startup();
205
206 if (timer_period)
207 program_wide_timer().set_timer(timer_period, this);
208
209 MSG msg;
210 msg.hwnd = 0; msg.message = 0; msg.wParam = 0; msg.lParam = 0;
211 while (!alert.is_defunct() && (GetMessage(&msg, NULL_POINTER, 0, 0)) {
212 TranslateMessage(&msg);
213 DispatchMessage(&msg);
214 }
215 alert.handle_shutdown();
216
217 return true;
218}
219#endif
220*/
221
222} //namespace.
223
#define LOG(s)
A platform-independent way to alert a program that it should shut down immediately.
virtual void handle_startup()
this function is called once the program has begun operation.
hoople_service()
constructor does very little; setup() is what begins operation.
static void make_defunct()
used by the derived class to mark that this object is about to exit.
virtual void handle_timer()
called periodically if a timer period was specified.
static void handle_OS_signal(int sig_id)
processes the signal from the OS when its time to shut down.
static bool launch_console(hoople_service &alert, const basis::astring &app_name, int timer_period=0)
this is used to begin execution of a console mode application.
static bool is_defunct()
returns true if the object has been marked as defunct.
bool setup(const basis::astring &app_name, int timer_period=0)
constructs a hoople_service for the "app_name" specified.
static void close_this_program()
causes this particular application to begin shutting down.
virtual void handle_shutdown()
called during the program's shutdown process.
static bool close_application(const basis::astring &app_name)
attempts to close the application named "app_name".
int length() const
Returns the current reported length of the allocated C array.
Definition array.h:115
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
Provides a bridge to the operating system for information on processes.
static bool find_process_in_list(const process_entry_array &processes, const basis::astring &app_name, structures::int_set &pids)
uses a pre-existing list of "processes" to search for the "app_name".
bool query_processes(process_entry_array &to_fill)
finds the processes that are running and drops them into "to_fill".
a handy class that implements an array of process entries.
A simple object that wraps a templated set of ints.
Definition set.h:156
static void sleep_ms(basis::un_int msec)
a system independent name for a forced snooze measured in milliseconds.
Represents a point in time relative to the operating system startup time.
Definition time_stamp.h:38
void reset()
sets the stamp time back to now.
#define formal(parameter)
This macro just eats what it's passed; it marks unused formal parameters.
Definition definitions.h:48
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition enhance_cpp.h:54
Implements an application lock to ensure only one is running at once.
char ** _global_argv
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
const int SECOND_ms
Number of milliseconds in a second.
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55
#include <time.h>
#define SAFE_STATIC(type, func_name, parms)
Statically defines a singleton object whose scope is the program's lifetime.
#define program_wide_timer()
provides access to the singleton timer_driver.