4 // Copyright (C) 2004 Novell, Inc.
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.
28 using System
.Threading
;
29 using System
.Collections
;
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
)
49 if (shutdownRequested
) {
53 if (workers
.Contains (o
))
54 refcount
= (int)workers
[o
];
56 workers
[o
] = refcount
;
57 workers_names
[o
] = name
;
60 Logger
.Log
.Debug ("worker added: name={0} refcount={1}", name
, refcount
);
65 public static bool WorkerStart (object o
)
67 return WorkerStart (o
, o
.ToString ());
70 public static void WorkerFinished (object o
)
73 if (!workers
.Contains (o
)) {
74 Logger
.Log
.Warn ("extra WorkerFinished called for {0}", o
);
78 int refcount
= (int)workers
[o
];
82 Logger
.Log
.Debug ("worker removed: name={0}", workers_names
[o
]);
84 workers_names
.Remove (o
);
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 ()
102 Logger
.Log
.Debug ("Calling BeginShutdown");
104 lock (shutdownLock
) {
105 if (shutdownRequested
)
107 shutdownRequested
= true;
111 Logger
.Log
.Debug ("Beginning shutdown event");
113 if (ShutdownEvent
!= null) {
116 } catch (Exception ex
) {
117 Logger
.Log
.Warn ("Caught unhandled exception during shutdown event");
118 Logger
.Log
.Warn (ex
);
123 Logger
.Log
.Debug ("Done with shutdown event");
127 lock (shutdownLock
) {
128 while (workers
.Count
> 0) {
130 Logger
.Log
.Debug ("({0}) Waiting for {1} worker{2}...",
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 ();