2 * app - zavai main window
4 * Copyright (C) 2009 Enrico Zini <enrico@enricozini.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 public interface Resource : Object {
27 * Shut down this resource.
29 * Normally one does nothing here, but it is important to give resources a
30 * chance to do cleanup when the program quits.
32 * This can be used for tasks like closing the tags on a GPX track,
33 * releasing a FSO resource, restoring mixer settings and so on.
35 public abstract void shutdown();
38 public abstract class Service : Object, Resource {
39 public string name { get; construct; }
43 get { return _started; }
44 set { _started = value; }
47 public signal void toggled(bool new_state);
49 protected class Request
51 public string requestor;
53 public Request(string requestor)
55 this.requestor = requestor;
60 protected List<Request> requests;
66 zavai.registry.register(this);
69 public void shutdown()
74 /// Activate the service
75 protected virtual void start()
79 zavai.log.info("Service " + name + " started\n");
85 /// Deactivate the service
86 protected virtual void stop()
90 zavai.log.info("Service " + name + " stopped\n");
97 Request a resource using the given ID.
99 * If it is the first time the resource is requested, start it and
100 * return true. Else, take note of the request and return false.
102 * If a resource is requested multiple times with the same ID, it will
103 * need to be released multiple times with that ID.
105 public bool request(string id)
107 bool res = (requests == null);
109 for (weak List<Request> i = requests; i != null; i = i.next)
110 if (i.data.requestor == id)
117 requests.prepend(new Request(id));
123 * Release a resource using the given ID.
125 * If after the call nothing is requesting the resource, stop it and
126 * return true. Else, take note of the release and return false.
128 * If a resource is requested multiple times with the same ID, it will
129 * need to be released multiple times with that ID.
131 public bool release(string id)
133 weak List<Request> el = null;
134 for (weak List<Request> i = requests; i != null; i = i.next)
135 if (i.data.requestor == id)
144 requests.delete_link(el);
146 if (requests != null)
154 public abstract class ScriptService : Service
156 protected string script;
158 protected bool script_start()
161 zavai.config.find_and_run_script(name, "start");
164 zavai.log.error("Running " + name + " start: " + e.message);
169 protected bool script_stop()
172 zavai.config.find_and_run_script(name, "stop");
175 zavai.log.error("Running " + name + " stop: " + e.message);
180 protected bool script_status()
184 string script = zavai.config.find_script(name);
187 zavai.log.error("Hook " + name + " does not exist");
190 string command = script + " status";
192 int res = zavai.config.run_script_sync(command, out std_out, out std_err);
195 zavai.log.error("Running " + command + ": " + std_err);
198 } catch (SpawnError e) {
199 zavai.log.error("Running " + command + ": " + e.message);
205 return (std_out == "on");
209 public abstract class ScriptMonitorService : Service
211 protected Pid child_pid;
212 protected int child_watch_id;
214 ScriptMonitorService()
220 protected bool script_start()
222 string command = zavai.config.homedir + "/" + name + " pre";
224 // Then run our own script
225 zavai.config.run_script(command);
227 zavai.log.error("Running " + command + ": " + e.message);
231 command = zavai.config.homedir + "/" + name + " run";
232 zavai.log.info("Run program: " + command);
233 string[] args = command.split(" ");
236 Environment.get_home_dir(),
239 SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
242 } catch (SpawnError e) {
243 zavai.log.error("Running " + command + ": " + e.message);
247 // Add a child watch source to know when it ends
248 ChildWatch.add(child_pid, on_child);
253 protected bool script_stop()
255 Posix.kill((Posix.pid_t)child_pid, Posix.SIGTERM);
259 protected void on_child(Pid pid, int status)
261 zavai.log.info("Exited");
262 stderr.printf("STATUS %d\n", status);
263 Process.close_pid(pid);
265 string command = zavai.config.homedir + "/" + name + " post";
267 // Then run our own script
268 zavai.config.run_script(command);
270 zavai.log.error("Running " + command + ": " + e.message);
274 cleanup_after_script_stop();
279 protected virtual void cleanup_after_script_stop()
284 protected bool script_status()