2
* Permission is hereby granted, free of charge, to any person obtaining
3
* a copy of this software and associated documentation files (the
4
* "Software"), to deal in the Software without restriction, including
5
* without limitation the rights to use, copy, modify, merge, publish,
6
* distribute, sublicense, and/or sell copies of the Software, and to
7
* permit persons to whom the Software is furnished to do so, subject to
8
* the following conditions:
10
* The above copyright notice and this permission notice shall be
11
* included in all copies or substantial portions of the Software.
13
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
* Jackson Harper (jackson@ximian.com)
25
* Copyright 2007-2008 Novell, Inc. (http://www.novell.com)
28
* shutdown-manager.cpp: When shutdown is signaled, the shutdown manager
29
* will wait until everything (image capture) is done
30
* before it will actually shutdown the app.
42
#include <dbus/dbus-glib.h>
45
#include "shutdown-manager.h"
48
#define DRT_AGSERVER_SERVICE "mono.moonlight.agserver"
49
#define DRT_AGSERVER_PATH "/mono/moonlight/agserver"
50
#define DRT_AGSERVER_INTERFACE "mono.moonlight.agserver.IAgserver"
53
#define TIMEOUT_INTERVAL 10000
55
static GMutex* shutdown_mutex = NULL;
56
static GCond* shutdown_cond = NULL;
57
static gint wait_count = 0;
59
static void execute_shutdown (ShockerScriptableControlObject *shocker);
60
static gboolean attempt_clean_shutdown (gpointer data);
63
shutdown_manager_init ()
66
shutdown_mutex = g_mutex_new ();
67
shutdown_cond = g_cond_new ();
71
shutdown_manager_shutdown ()
75
g_mutex_free (shutdown_mutex);
76
g_cond_free (shutdown_cond);
80
shutdown_manager_wait_increment ()
82
g_assert (shutdown_mutex);
83
g_assert (shutdown_cond);
85
g_mutex_lock (shutdown_mutex);
89
g_mutex_unlock (shutdown_mutex);
93
shutdown_manager_wait_decrement ()
95
g_assert (shutdown_mutex);
96
g_assert (shutdown_cond);
98
g_mutex_lock (shutdown_mutex);
102
g_cond_signal (shutdown_cond);
104
g_mutex_unlock (shutdown_mutex);
108
shutdown_manager_wait ()
110
g_assert (shutdown_mutex);
111
g_assert (shutdown_cond);
113
while (wait_count > 0)
114
g_cond_wait (shutdown_cond, shutdown_mutex);
118
execute_shutdown (ShockerScriptableControlObject *shocker)
120
char *dont_die = getenv ("MOONLIGHT_SHOCKER_DONT_DIE");
121
if (dont_die != NULL && dont_die [0] != 0)
126
DBusGConnection* connection;
127
GError* error = NULL;
130
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
132
g_warning ("Failed to open connection to bus: %s\n", error->message);
133
g_error_free (error);
136
DBusGProxy* dbus_proxy = dbus_g_proxy_new_for_name (connection,
137
DRT_AGSERVER_SERVICE,
139
DRT_AGSERVER_INTERFACE);
142
dbus_g_proxy_call_no_reply (dbus_proxy, "SignalShutdown", G_TYPE_INVALID, G_TYPE_INVALID);
144
// if (!dbus_g_proxy_call (dbus_proxy, "SignalShutdown", &error, G_TYPE_INVALID, G_TYPE_INVALID)) {
145
// g_warning ("unable to make signal shutdown call: %s\n", error->message);
150
if (gtk_main_level ()) {
151
// We are running inside the embedded agviewer, so we can use gtk to signal shutdown
154
// This block never actually gets called, since firefox is also using gtk_main.
160
attempt_clean_shutdown (gpointer data)
162
ShockerScriptableControlObject *shocker = (ShockerScriptableControlObject *) data;
163
char *dont_die = getenv ("MOONLIGHT_SHOCKER_DONT_DIE");
164
if (dont_die != NULL && dont_die [0] != 0)
167
g_assert (shutdown_mutex);
168
g_assert (shutdown_cond);
170
bool ready_for_shutdown = false;
172
g_mutex_lock (shutdown_mutex);
174
ready_for_shutdown = true;
175
g_mutex_unlock (shutdown_mutex);
177
if (ready_for_shutdown) {
178
execute_shutdown (shocker);
186
shutdown_manager_queue_shutdown (ShockerScriptableControlObject* shocker)
188
g_assert (shutdown_mutex);
189
g_assert (shutdown_cond);
192
return execute_shutdown (shocker);
194
if (!g_timeout_add (TIMEOUT_INTERVAL, attempt_clean_shutdown, shocker)) {
195
g_error ("Unable to create timeout for queued shutdown, executing immediate shutdown.");
196
execute_shutdown (shocker);