| File: | _build/../src/reaper.cc |
| Warning: | line 182, column 25 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* |
| 2 | * Copyright (C) 2002 Red Hat, Inc. |
| 3 | * |
| 4 | * This library is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU Lesser General Public |
| 6 | * License as published by the Free Software Foundation; either |
| 7 | * version 2.1 of the License, or (at your option) any later version. |
| 8 | * |
| 9 | * This library is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 | * Lesser General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU Lesser General Public |
| 15 | * License along with this library; if not, write to the Free Software |
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 17 | */ |
| 18 | |
| 19 | #include "config.h" |
| 20 | |
| 21 | #include "debug.h" |
| 22 | #include "reaper.hh" |
| 23 | |
| 24 | struct _BteReaper { |
| 25 | GObject parent_instance; |
| 26 | }; |
| 27 | |
| 28 | struct _BteReaperClass { |
| 29 | GObjectClass parent_class; |
| 30 | }; |
| 31 | typedef struct _BteReaperClass BteReaperClass; |
| 32 | |
| 33 | #define BTE_TYPE_REAPER(bte_reaper_get_type()) (bte_reaper_get_type()) |
| 34 | #define BTE_REAPER(obj)((((BteReaper*) (void *) ((obj))))) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BTE_TYPE_REAPER, BteReaper)(((BteReaper*) (void *) ((obj))))) |
| 35 | #define BTE_REAPER_CLASS(klass)((((BteReaperClass*) (void *) ((klass))))) (G_TYPE_CHECK_CLASS_CAST ((klass), BTE_TYPE_REAPER, BteReaperClass)(((BteReaperClass*) (void *) ((klass))))) |
| 36 | #define BTE_IS_REAPER(obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (obj)); GType __t = ((bte_reaper_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst ->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BTE_TYPE_REAPER)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (obj)); GType __t = ((bte_reaper_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst ->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) |
| 37 | #define BTE_IS_REAPER_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass )); GType __t = ((bte_reaper_get_type())); gboolean __r; if ( !__class) __r = (0); else if (__class->g_type == __t) __r = (!(0)); else __r = g_type_check_class_is_a (__class, __t); __r ; })))) (G_TYPE_CHECK_CLASS_TYPE ((klass), BTE_TYPE_REAPER)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass )); GType __t = ((bte_reaper_get_type())); gboolean __r; if ( !__class) __r = (0); else if (__class->g_type == __t) __r = (!(0)); else __r = g_type_check_class_is_a (__class, __t); __r ; })))) |
| 38 | #define BTE_REAPER_GET_CLASS(obj)((((BteReaperClass*) (((GTypeInstance*) ((obj)))->g_class) ))) (G_TYPE_INSTANCE_GET_CLASS ((obj), BTE_TYPE_REAPER, BteReaperClass)(((BteReaperClass*) (((GTypeInstance*) ((obj)))->g_class)) )) |
| 39 | |
| 40 | static GType bte_reaper_get_type(void); |
| 41 | |
| 42 | G_DEFINE_TYPE(BteReaper, bte_reaper, G_TYPE_OBJECT)static void bte_reaper_init (BteReaper *self); static void bte_reaper_class_init (BteReaperClass *klass); static GType bte_reaper_get_type_once (void); static gpointer bte_reaper_parent_class = __null; static gint BteReaper_private_offset; static void bte_reaper_class_intern_init (gpointer klass) { bte_reaper_parent_class = g_type_class_peek_parent (klass); if (BteReaper_private_offset != 0) g_type_class_adjust_private_offset (klass, &BteReaper_private_offset); bte_reaper_class_init ((BteReaperClass*) klass); } __attribute__ ((__unused__)) static inline gpointer bte_reaper_get_instance_private (BteReaper * self) { return (((gpointer) ((guint8*) (self) + (glong) (BteReaper_private_offset )))); } GType bte_reaper_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); typename std::remove_reference<decltype (*(&static_g_define_type_id ))>::type gapg_temp_newval; typename std::remove_reference <decltype ((&static_g_define_type_id))>::type gapg_temp_atomic = (&static_g_define_type_id); __atomic_load (gapg_temp_atomic , &gapg_temp_newval, 5); gapg_temp_newval; })) && g_once_init_enter_pointer (&static_g_define_type_id)); } )) ) { GType g_define_type_id = bte_reaper_get_type_once (); ( __extension__ ({ static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id ), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id ; } [[gnu::noinline]] static GType bte_reaper_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("BteReaper" ), sizeof (BteReaperClass), (GClassInitFunc)(void (*)(void)) bte_reaper_class_intern_init , sizeof (BteReaper), (GInstanceInitFunc)(void (*)(void)) bte_reaper_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } |
| 43 | |
| 44 | static BteReaper *singleton_reaper = nullptr; |
| 45 | |
| 46 | static void |
| 47 | bte_reaper_child_watch_cb(GPid pid, |
| 48 | int status, |
| 49 | gpointer data) |
| 50 | { |
| 51 | _bte_debug_print(BTE_DEBUG_SIGNALS,do { } while(0) |
| 52 | "Reaper emitting child-exited signal.\n")do { } while(0); |
| 53 | g_signal_emit_by_name(data, "child-exited", pid, status); |
| 54 | g_spawn_close_pid (pid); |
| 55 | } |
| 56 | |
| 57 | /* |
| 58 | * bte_reaper_add_child: |
| 59 | * @pid: the ID of a child process which will be monitored |
| 60 | * |
| 61 | * Ensures that child-exited signals will be emitted when @pid exits. |
| 62 | */ |
| 63 | void |
| 64 | bte_reaper_add_child(GPid pid) |
| 65 | { |
| 66 | g_child_watch_add_full(G_PRIORITY_LOW300, |
| 67 | pid, |
| 68 | bte_reaper_child_watch_cb, |
| 69 | bte_reaper_ref(), |
| 70 | (GDestroyNotify)g_object_unref); |
| 71 | } |
| 72 | |
| 73 | static void |
| 74 | bte_reaper_init(BteReaper *reaper) |
| 75 | { |
| 76 | } |
| 77 | |
| 78 | static GObject* |
| 79 | bte_reaper_constructor (GType type, |
| 80 | guint n_construct_properties, |
| 81 | GObjectConstructParam *construct_properties) |
| 82 | { |
| 83 | if (singleton_reaper) { |
| 84 | return (GObject*)g_object_ref (singleton_reaper)((typename std::remove_reference<decltype (singleton_reaper )>::type) (g_object_ref) (singleton_reaper)); |
| 85 | } else { |
| 86 | GObject *obj; |
| 87 | obj = G_OBJECT_CLASS (bte_reaper_parent_class)((((GObjectClass*) (void *) ((bte_reaper_parent_class)))))->constructor (type, n_construct_properties, construct_properties); |
| 88 | singleton_reaper = BTE_REAPER (obj)((((BteReaper*) (void *) ((obj))))); |
| 89 | return obj; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | |
| 94 | static void |
| 95 | bte_reaper_finalize(GObject *reaper) |
| 96 | { |
| 97 | G_OBJECT_CLASS(bte_reaper_parent_class)((((GObjectClass*) (void *) ((bte_reaper_parent_class)))))->finalize(reaper); |
| 98 | singleton_reaper = nullptr; |
| 99 | } |
| 100 | |
| 101 | static void |
| 102 | bte_reaper_class_init(BteReaperClass *klass) |
| 103 | { |
| 104 | GObjectClass *gobject_class; |
| 105 | |
| 106 | /* |
| 107 | * BteReaper::child-exited: |
| 108 | * @btereaper: the object which received the signal |
| 109 | * @arg1: the process ID of the exited child |
| 110 | * @arg2: the status of the exited child, as returned by waitpid() |
| 111 | * |
| 112 | * Emitted when the #BteReaper object detects that a child of the |
| 113 | * current process has exited. |
| 114 | */ |
| 115 | g_signal_new(g_intern_static_string("child-exited"), |
| 116 | G_OBJECT_CLASS_TYPE(klass)((((GTypeClass*) (klass))->g_type)), |
| 117 | G_SIGNAL_RUN_LAST, |
| 118 | 0, |
| 119 | nullptr, |
| 120 | nullptr, |
| 121 | g_cclosure_marshal_generic, |
| 122 | G_TYPE_NONE((GType) ((1) << (2))), |
| 123 | 2, |
| 124 | G_TYPE_INT((GType) ((6) << (2))), G_TYPE_INT((GType) ((6) << (2)))); |
| 125 | |
| 126 | gobject_class = G_OBJECT_CLASS(klass)((((GObjectClass*) (void *) ((klass))))); |
| 127 | gobject_class->constructor = bte_reaper_constructor; |
| 128 | gobject_class->finalize = bte_reaper_finalize; |
| 129 | } |
| 130 | |
| 131 | /* |
| 132 | * bte_reaper_ref: |
| 133 | * |
| 134 | * Finds the address of the global #BteReaper object, creating the object if |
| 135 | * necessary. |
| 136 | * |
| 137 | * Returns: a reference to the global #BteReaper object, which |
| 138 | * must be unreffed when done with it |
| 139 | */ |
| 140 | BteReaper * |
| 141 | bte_reaper_ref(void) |
| 142 | { |
| 143 | return (BteReaper*)g_object_new(BTE_TYPE_REAPER(bte_reaper_get_type()), nullptr); |
| 144 | } |
| 145 | |
| 146 | #ifdef MAIN1 |
| 147 | |
| 148 | #include <unistd.h> |
| 149 | |
| 150 | GMainContext *context; |
| 151 | GMainLoop *loop; |
| 152 | pid_t child; |
| 153 | |
| 154 | static void |
| 155 | child_exited(GObject *object, int pid, int status, gpointer data) |
| 156 | { |
| 157 | g_print("[parent] Child with pid %d exited with code %d, " |
| 158 | "was waiting for %d.\n", pid, status, GPOINTER_TO_INT(data)((gint) (glong) (data))); |
| 159 | if (child == pid) { |
| 160 | g_print("[parent] Quitting.\n"); |
| 161 | g_main_loop_quit(loop); |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | int |
| 166 | main(int argc, char **argv) |
| 167 | { |
| 168 | BteReaper *reaper; |
| 169 | pid_t p, q; |
| 170 | |
| 171 | _bte_debug_init_bte_external_debug_init(); |
| 172 | |
| 173 | context = g_main_context_default(); |
| 174 | loop = g_main_loop_new(context, FALSE(0)); |
| 175 | reaper = bte_reaper_ref(); |
| 176 | |
| 177 | g_print("[parent] Forking1.\n"); |
| 178 | p = fork(); |
| 179 | switch (p) { |
| 180 | case -1: |
| 181 | g_print("[parent] Fork1 failed.\n"); |
| 182 | g_assert_not_reached()do { g_assertion_message_expr (((gchar*) 0), "../src/reaper.cc" , 182, ((const char*) (__PRETTY_FUNCTION__)), __null); } while (0); |
This statement is never executed | |
| 183 | break; |
| 184 | case 0: |
| 185 | g_print("[child1] Going to sleep.\n"); |
| 186 | sleep(10); |
| 187 | g_print("[child1] Quitting.\n"); |
| 188 | _exit(30); |
| 189 | break; |
| 190 | default: |
| 191 | g_print("[parent] Starting to wait for %d.\n", p); |
| 192 | bte_reaper_add_child(p); |
| 193 | child = p; |
| 194 | g_signal_connect(reaper,g_signal_connect_data ((reaper), ("child-exited"), (((GCallback ) (child_exited))), (((gpointer) (glong) (child))), __null, ( GConnectFlags) 0) |
| 195 | "child-exited",g_signal_connect_data ((reaper), ("child-exited"), (((GCallback ) (child_exited))), (((gpointer) (glong) (child))), __null, ( GConnectFlags) 0) |
| 196 | G_CALLBACK(child_exited),g_signal_connect_data ((reaper), ("child-exited"), (((GCallback ) (child_exited))), (((gpointer) (glong) (child))), __null, ( GConnectFlags) 0) |
| 197 | GINT_TO_POINTER(child))g_signal_connect_data ((reaper), ("child-exited"), (((GCallback ) (child_exited))), (((gpointer) (glong) (child))), __null, ( GConnectFlags) 0); |
| 198 | break; |
| 199 | } |
| 200 | |
| 201 | g_print("[parent] Forking2.\n"); |
| 202 | q = fork(); |
| 203 | switch (q) { |
| 204 | case -1: |
| 205 | g_print("[parent] Fork2 failed.\n"); |
| 206 | g_assert_not_reached()do { g_assertion_message_expr (((gchar*) 0), "../src/reaper.cc" , 206, ((const char*) (__PRETTY_FUNCTION__)), __null); } while (0); |
| 207 | break; |
| 208 | case 0: |
| 209 | g_print("[child2] Going to sleep.\n"); |
| 210 | sleep(5); |
| 211 | g_print("[child2] Quitting.\n"); |
| 212 | _exit(5); |
| 213 | break; |
| 214 | default: |
| 215 | g_print("[parent] Not waiting for %d.\n", q); |
| 216 | break; |
| 217 | } |
| 218 | |
| 219 | |
| 220 | g_main_loop_run(loop); |
| 221 | |
| 222 | g_object_unref(reaper); |
| 223 | |
| 224 | return 0; |
| 225 | } |
| 226 | #endif |