diff --git a/src/main.c b/src/main.c index 03708fc8fe20684e6ee2d35efe02711ee3273711..aaf88fd3a698fe09bda115355e228463b724c2b9 100644 --- a/src/main.c +++ b/src/main.c @@ -153,62 +153,6 @@ shell_fonts_init (void) cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE); } -static void -shell_profiler_init (void) -{ - ShellGlobal *global; - GjsProfiler *profiler; - GjsContext *context; - const char *enabled; - const char *fd_str; - int fd = -1; - - /* Sysprof uses the "GJS_TRACE_FD=N" environment variable to connect GJS - * profiler data to the combined Sysprof capture. Since we are in control of - * the GjsContext, we need to proxy this FD across to the GJS profiler. - */ - - fd_str = g_getenv ("GJS_TRACE_FD"); - enabled = g_getenv ("GJS_ENABLE_PROFILER"); - if (fd_str == NULL || enabled == NULL) - return; - - global = shell_global_get (); - g_return_if_fail (global); - - context = _shell_global_get_gjs_context (global); - g_return_if_fail (context); - - profiler = gjs_context_get_profiler (context); - g_return_if_fail (profiler); - - if (fd_str) - { - fd = atoi (fd_str); - - if (fd > 2) - { - gjs_profiler_set_fd (profiler, fd); - gjs_profiler_start (profiler); - } - } -} - -static void -shell_profiler_shutdown (void) -{ - ShellGlobal *global; - GjsProfiler *profiler; - GjsContext *context; - - global = shell_global_get (); - context = _shell_global_get_gjs_context (global); - profiler = gjs_context_get_profiler (context); - - if (profiler) - gjs_profiler_stop (profiler); -} - static void malloc_statistics_callback (ShellPerfLog *perf_log, gpointer data) @@ -387,8 +331,7 @@ list_modes (const char *option_name, g_log_set_default_handler (shut_up, NULL); gtk_init_check (NULL, NULL); - _shell_global_init (NULL); - global = shell_global_get (); + global = _shell_global_set (g_object_new (SHELL_TYPE_GLOBAL, NULL)); context = _shell_global_get_gjs_context (global); shell_introspection_init (); @@ -398,7 +341,8 @@ list_modes (const char *option_name, if (!gjs_context_eval (context, script, -1, "
", &status, NULL)) g_message ("Retrieving list of available modes failed."); - g_object_unref (context); + _shell_global_destroy (global); + exit (status); } @@ -488,6 +432,7 @@ main (int argc, char **argv) { g_autoptr (MetaContext) context = NULL; GError *error = NULL; + ShellGlobal *global; int ecode = EXIT_SUCCESS; bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); @@ -539,7 +484,9 @@ main (int argc, char **argv) if (session_mode == NULL) session_mode = is_gdm_mode ? (char *)"gdm" : (char *)"user"; - _shell_global_init ("session-mode", session_mode, NULL); + global = _shell_global_set (g_object_new (SHELL_TYPE_GLOBAL, + "session-mode", session_mode, + NULL)); dump_gjs_stack_on_signal (SIGABRT); dump_gjs_stack_on_signal (SIGFPE); @@ -552,8 +499,6 @@ main (int argc, char **argv) dump_gjs_stack_on_signal (SIGSEGV); } - shell_profiler_init (); - if (meta_context_get_compositor_type (context) == META_COMPOSITOR_TYPE_WAYLAND) meta_context_raise_rlimit_nofile (context, NULL); @@ -571,11 +516,8 @@ main (int argc, char **argv) meta_context_destroy (g_steal_pointer (&context)); - shell_profiler_shutdown (); - g_debug ("Doing final cleanup"); - _shell_global_destroy_gjs_context (shell_global_get ()); - g_object_unref (shell_global_get ()); + _shell_global_destroy (global); return ecode; } diff --git a/src/run-js-test.c b/src/run-js-test.c index ba5e875e8736b2bb1147fc252e5d1d247e53f186..86157ff76650dfe01eb84dca29787568343f34b6 100644 --- a/src/run-js-test.c +++ b/src/run-js-test.c @@ -46,13 +46,13 @@ static GOptionEntry entries[] = { int main(int argc, char **argv) { - GOptionContext *context; - GError *error = NULL; + g_autoptr (GError) error = NULL; + g_autofree char *script = NULL; + g_autofree char *title = NULL; ShellGlobal *global; + GOptionContext *context; GjsContext *js_context; - char *script; const char *filename; - char *title; gsize len; int code; @@ -62,13 +62,14 @@ main(int argc, char **argv) g_option_context_set_ignore_unknown_options (context, TRUE); g_option_context_add_main_entries (context, entries, NULL); - if (!g_option_context_parse (context, &argc, &argv, &error)) + if (!g_option_context_parse (context, &argc, &argv, &error)) { g_error ("option parsing failed: %s", error->message); + g_clear_error (&error); + } setlocale (LC_ALL, ""); - _shell_global_init (NULL); - global = shell_global_get (); + global = _shell_global_set (g_object_new (SHELL_TYPE_GLOBAL, NULL)); js_context = _shell_global_get_gjs_context (global); /* prepare command line arguments */ @@ -76,7 +77,8 @@ main(int argc, char **argv) argc - 2, (const char**)argv + 2, &error)) { g_printerr ("Failed to defined ARGV: %s", error->message); - exit (1); + _shell_global_destroy (global); + return 1; } if (command != NULL) { @@ -88,31 +90,28 @@ main(int argc, char **argv) len = strlen (script); filename = ""; } else /*if (argc >= 2)*/ { - error = NULL; if (!g_file_get_contents (argv[1], &script, &len, &error)) { g_printerr ("%s\n", error->message); - exit (1); + _shell_global_destroy (global); + return 1; } filename = argv[1]; } title = g_filename_display_basename (filename); g_set_prgname (title); - g_free (title); /* evaluate the script */ error = NULL; if (!gjs_context_eval (js_context, script, len, filename, &code, &error)) { - g_free (script); g_printerr ("%s\n", error->message); - exit (1); } gjs_context_gc (js_context); gjs_context_gc (js_context); - g_object_unref (js_context); - g_free (script); - exit (code); + _shell_global_destroy (global); + + return code; } diff --git a/src/shell-global-private.h b/src/shell-global-private.h index 9969691cb47db09ae5c81f043cc609e80f4aa645..e2133489666487a4ccfcbb5d105a80bc4f6f0998 100644 --- a/src/shell-global-private.h +++ b/src/shell-global-private.h @@ -6,12 +6,12 @@ #include -void _shell_global_init (const char *first_property_name, - ...); +ShellGlobal *_shell_global_set (ShellGlobal *global); + void _shell_global_set_plugin (ShellGlobal *global, MetaPlugin *plugin); -void _shell_global_destroy_gjs_context (ShellGlobal *global); +void _shell_global_destroy (ShellGlobal *global); GjsContext *_shell_global_get_gjs_context (ShellGlobal *global); diff --git a/src/shell-global.c b/src/shell-global.c index efe1271b5a143c7eb7a1b3d29edce051087ffc9a..66d5e412fa888a2ab3bbb110ed7e6bcfc59b7827 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -353,6 +353,39 @@ switcheroo_vanished_cb (GDBusConnection *connection, g_object_notify_by_pspec (G_OBJECT (global), props[PROP_SWITCHEROO_CONTROL]); } +static void +shell_global_profiler_init (ShellGlobal *global) +{ + GjsProfiler *profiler; + const char *enabled; + const char *fd_str; + int fd = -1; + + /* Sysprof uses the "GJS_TRACE_FD=N" environment variable to connect GJS + * profiler data to the combined Sysprof capture. Since we are in control of + * the GjsContext, we need to proxy this FD across to the GJS profiler. + */ + + fd_str = g_getenv ("GJS_TRACE_FD"); + enabled = g_getenv ("GJS_ENABLE_PROFILER"); + if (fd_str == NULL || enabled == NULL) + return; + + profiler = gjs_context_get_profiler (global->js_context); + g_return_if_fail (profiler); + + if (fd_str) + { + fd = atoi (fd_str); + + if (fd > 2) + { + gjs_profiler_set_fd (profiler, fd); + gjs_profiler_start (profiler); + } + } +} + static void shell_global_init (ShellGlobal *global) { @@ -455,29 +488,39 @@ shell_global_init (ShellGlobal *global) switcheroo_vanished_cb, global, NULL); + + shell_global_profiler_init (global); } static void -shell_global_finalize (GObject *object) +shell_global_dispose (GObject *object) { ShellGlobal *global = SHELL_GLOBAL (object); g_clear_object (&global->js_context); - g_object_unref (global->settings); - - the_object = NULL; g_cancellable_cancel (global->switcheroo_cancellable); g_clear_object (&global->switcheroo_cancellable); + g_clear_object (&global->settings); g_clear_object (&global->userdatadir_path); g_clear_object (&global->runtime_state_path); + G_OBJECT_CLASS (shell_global_parent_class)->dispose (object); +} + +static void +shell_global_finalize (GObject *object) +{ + ShellGlobal *global = SHELL_GLOBAL (object); + + the_object = NULL; + g_free (global->session_mode); g_free (global->imagedir); g_free (global->userdatadir); - g_hash_table_unref (global->save_ops); + g_hash_table_destroy (global->save_ops); G_OBJECT_CLASS(shell_global_parent_class)->finalize (object); } @@ -489,6 +532,7 @@ shell_global_class_init (ShellGlobalClass *klass) gobject_class->get_property = shell_global_get_property; gobject_class->set_property = shell_global_set_property; + gobject_class->dispose = shell_global_dispose; gobject_class->finalize = shell_global_finalize; shell_global_signals[NOTIFY_ERROR] = @@ -645,34 +689,24 @@ shell_global_class_init (ShellGlobalClass *klass) } /* - * _shell_global_init: (skip) - * @first_property_name: the name of the first property - * @...: the value of the first property, followed optionally by more - * name/value pairs, followed by %NULL + * _shell_global_set: (skip) + * @global: the object to be used as global singleton * - * Initializes the shell global singleton with the construction-time - * properties. - * - * There are currently no such properties, so @first_property_name should - * always be %NULL. + * Set the shell global singleton. * * This call must be called before shell_global_get() and shouldn't be called * more than once. + * + * Return value: (transfer none): the singleton #ShellGlobal object */ -void -_shell_global_init (const char *first_property_name, - ...) +ShellGlobal * +_shell_global_set (ShellGlobal *global) { - va_list argument_list; + g_return_val_if_fail (the_object == NULL, the_object); - g_return_if_fail (the_object == NULL); - - va_start (argument_list, first_property_name); - the_object = SHELL_GLOBAL (g_object_new_valist (SHELL_TYPE_GLOBAL, - first_property_name, - argument_list)); - va_end (argument_list); + the_object = global; + return the_object; } /** @@ -689,17 +723,19 @@ shell_global_get (void) } /** - * _shell_global_destroy_gjs_context: (skip) + * _shell_global_destroy: (skip) * @self: global object * - * Destroys the GjsContext held by ShellGlobal, in order to break reference - * counting cycles. (The GjsContext holds a reference to ShellGlobal because - * it's available as window.global inside JS.) + * Destroys the #ShellGlobal, disposing child objects (such as the #GjsContext) + * in order to break reference counting cycles. + * The GjsContext holds a reference to ShellGlobal because it's available as + * window.global inside JS. */ void -_shell_global_destroy_gjs_context (ShellGlobal *self) +_shell_global_destroy (ShellGlobal *global) { - g_clear_object (&self->js_context); + g_object_run_dispose (G_OBJECT (global)); + g_object_unref (global); } static guint32 @@ -1290,7 +1326,7 @@ shell_global_notify_error (ShellGlobal *global, const char *msg, const char *details) { - g_signal_emit_by_name (global, "notify-error", msg, details); + g_signal_emit (global, shell_global_signals[NOTIFY_ERROR], 0, msg, details); } /**