Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Shutdown.cs
blob968676e75e5aec0bc8aaa5c0afe939b999038d49
1 //
2 // Shutdown.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Threading;
29 using System.Collections;
30 using Beagle.Util;
32 namespace Beagle.Daemon {
34 public class Shutdown {
36 static public bool Debug = false;
38 static object shutdownLock = new object ();
39 static Hashtable workers = new Hashtable ();
40 static Hashtable workers_names = new Hashtable ();
41 static bool shutdownRequested = false;
43 public delegate void ShutdownHandler ();
44 public static event ShutdownHandler ShutdownEvent;
46 public static bool WorkerStart (object o, string name)
48 lock (shutdownLock) {
49 if (shutdownRequested) {
50 return false;
52 int refcount = 0;
53 if (workers.Contains (o))
54 refcount = (int)workers[o];
55 ++refcount;
56 workers[o] = refcount;
57 workers_names[o] = name;
59 if (Debug)
60 Logger.Log.Debug ("worker added: name={0} refcount={1}", name, refcount);
62 return true;
65 public static bool WorkerStart (object o)
67 return WorkerStart (o, o.ToString ());
70 public static void WorkerFinished (object o)
72 lock (shutdownLock) {
73 if (!workers.Contains (o)) {
74 Logger.Log.Warn ("extra WorkerFinished called for {0}", o);
75 return;
78 int refcount = (int)workers[o];
79 --refcount;
80 if (refcount == 0) {
81 if (Debug)
82 Logger.Log.Debug ("worker removed: name={0}", workers_names[o]);
83 workers.Remove (o);
84 workers_names.Remove (o);
85 } else {
86 if (Debug)
87 Logger.Log.Debug ("worker finished: name={0} refcount={1}", workers_names[o], refcount);
88 workers[o] = refcount;
91 Monitor.Pulse (shutdownLock);
95 static public bool ShutdownRequested {
96 get { return shutdownRequested; }
99 static public void BeginShutdown ()
101 if (Debug)
102 Logger.Log.Debug ("Calling BeginShutdown");
104 lock (shutdownLock) {
105 if (shutdownRequested)
106 return;
107 shutdownRequested = true;
110 if (Debug)
111 Logger.Log.Debug ("Beginning shutdown event");
113 if (ShutdownEvent != null) {
114 try {
115 ShutdownEvent ();
116 } catch (Exception ex) {
117 Logger.Log.Warn ("Caught unhandled exception during shutdown event");
118 Logger.Log.Warn (ex);
122 if (Debug)
123 Logger.Log.Debug ("Done with shutdown event");
125 int count = 0;
127 lock (shutdownLock) {
128 while (workers.Count > 0) {
129 ++count;
130 Logger.Log.Debug ("({0}) Waiting for {1} worker{2}...",
131 count,
132 workers.Count,
133 workers.Count > 1 ? "s" : "");
134 foreach (object o in workers.Keys)
135 Logger.Log.Debug ("waiting for {0}", workers_names[o]);
136 Monitor.Wait (shutdownLock);
140 Logger.Log.Info ("Exiting");
141 Gtk.Application.Quit ();