/** * Finalizes the members of the DBusServer base class. * Chained up to by subclass finalizers. * * @param server the server. */ void _dbus_server_finalize_base (DBusServer *server) { /* We don't have the lock, but nobody should be accessing * concurrently since they don't have a ref */ #ifndef DBUS_DISABLE_CHECKS _dbus_assert (!server->have_server_lock); #endif _dbus_assert (server->disconnected); /* calls out to application code... */ _dbus_data_slot_list_free (&server->slot_list); dbus_server_set_new_connection_function (server, NULL, NULL, NULL); _dbus_watch_list_free (server->watches); _dbus_timeout_list_free (server->timeouts); _dbus_rmutex_free_at_location (&server->mutex); dbus_free (server->address); dbus_free_string_array (server->auth_mechanisms); _dbus_string_free (&server->guid_hex); }
/** * Decrement the reference count on the babysitter object. * When the reference count of the babysitter object reaches * zero, the babysitter is killed and the child that was being * babysat gets emancipated. * * @param sitter the babysitter */ void _dbus_babysitter_unref (DBusBabysitter *sitter) { _dbus_assert (sitter != NULL); _dbus_assert (sitter->refcount > 0); sitter->refcount -= 1; if (sitter->refcount == 0) { /* If we haven't forked other babysitters * since this babysitter and socket were * created then this close will cause the * babysitter to wake up from poll with * a hangup and then the babysitter will * quit itself. */ close_socket_to_babysitter (sitter); close_error_pipe_from_child (sitter); if (sitter->sitter_pid > 0) { int status; int ret; /* It's possible the babysitter died on its own above * from the close, or was killed randomly * by some other process, so first try to reap it */ ret = waitpid (sitter->sitter_pid, &status, WNOHANG); /* If we couldn't reap the child then kill it, and * try again */ if (ret == 0) kill (sitter->sitter_pid, SIGKILL); if (ret == 0) { do { ret = waitpid (sitter->sitter_pid, &status, 0); } while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR)); } if (ret < 0) { if (errno == ECHILD) _dbus_warn ("Babysitter process not available to be reaped; should not happen"); else _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s", errno, _dbus_strerror (errno)); } else { _dbus_verbose ("Reaped %ld, waiting for babysitter %ld\n", (long) ret, (long) sitter->sitter_pid); if (WIFEXITED (sitter->status)) _dbus_verbose ("Babysitter exited with status %d\n", WEXITSTATUS (sitter->status)); else if (WIFSIGNALED (sitter->status)) _dbus_verbose ("Babysitter received signal %d\n", WTERMSIG (sitter->status)); else _dbus_verbose ("Babysitter exited abnormally\n"); } sitter->sitter_pid = -1; } if (sitter->watches) _dbus_watch_list_free (sitter->watches); dbus_free (sitter->log_name); dbus_free (sitter); } }
/** * Decrement the reference count on the babysitter object. * * @param sitter the babysitter */ void _dbus_babysitter_unref (DBusBabysitter *sitter) { int i; PING(); _dbus_assert (sitter != NULL); _dbus_assert (sitter->refcount > 0); sitter->refcount -= 1; if (sitter->refcount == 0) { if (sitter->socket_to_babysitter != -1) { _dbus_close_socket (sitter->socket_to_babysitter, NULL); sitter->socket_to_babysitter = -1; } if (sitter->socket_to_main != -1) { _dbus_close_socket (sitter->socket_to_main, NULL); sitter->socket_to_main = -1; } PING(); if (sitter->argv != NULL) { for (i = 0; i < sitter->argc; i++) if (sitter->argv[i] != NULL) { dbus_free (sitter->argv[i]); sitter->argv[i] = NULL; } dbus_free (sitter->argv); sitter->argv = NULL; } if (sitter->envp != NULL) { char **e = sitter->envp; while (*e) dbus_free (*e++); dbus_free (sitter->envp); sitter->envp = NULL; } if (sitter->child_handle != NULL) { CloseHandle (sitter->child_handle); sitter->child_handle = NULL; } if (sitter->sitter_watch) { _dbus_watch_invalidate (sitter->sitter_watch); _dbus_watch_unref (sitter->sitter_watch); sitter->sitter_watch = NULL; } if (sitter->watches) _dbus_watch_list_free (sitter->watches); if (sitter->start_sync_event != NULL) { PING(); CloseHandle (sitter->start_sync_event); sitter->start_sync_event = NULL; } #ifdef DBUS_BUILD_TESTS if (sitter->end_sync_event != NULL) { CloseHandle (sitter->end_sync_event); sitter->end_sync_event = NULL; } #endif dbus_free (sitter->executable); dbus_free (sitter); } }
/** * Initializes the members of the DBusServer base class. * Chained up to by subclass constructors. * * @param server the server. * @param vtable the vtable for the subclass. * @param address the server's address * @returns #TRUE on success. */ dbus_bool_t _dbus_server_init_base (DBusServer *server, const DBusServerVTable *vtable, const DBusString *address) { server->vtable = vtable; #ifdef DBUS_DISABLE_ASSERT _dbus_atomic_inc (&server->refcount); #else { dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount); _dbus_assert (old_refcount == 0); } #endif server->address = NULL; server->watches = NULL; server->timeouts = NULL; server->published_address = FALSE; if (!_dbus_string_init (&server->guid_hex)) return FALSE; _dbus_generate_uuid (&server->guid); if (!_dbus_uuid_encode (&server->guid, &server->guid_hex)) goto failed; server->address = copy_address_with_guid_appended (address, &server->guid_hex); if (server->address == NULL) goto failed; _dbus_rmutex_new_at_location (&server->mutex); if (server->mutex == NULL) goto failed; server->watches = _dbus_watch_list_new (); if (server->watches == NULL) goto failed; server->timeouts = _dbus_timeout_list_new (); if (server->timeouts == NULL) goto failed; _dbus_data_slot_list_init (&server->slot_list); _dbus_verbose ("Initialized server on address %s\n", server->address); return TRUE; failed: _dbus_rmutex_free_at_location (&server->mutex); server->mutex = NULL; if (server->watches) { _dbus_watch_list_free (server->watches); server->watches = NULL; } if (server->timeouts) { _dbus_timeout_list_free (server->timeouts); server->timeouts = NULL; } if (server->address) { dbus_free (server->address); server->address = NULL; } _dbus_string_free (&server->guid_hex); return FALSE; }
/** * Initializes the members of the DBusServer base class. * Chained up to by subclass constructors. * * @param server the server. * @param vtable the vtable for the subclass. * @param address the server's address * @returns #TRUE on success. */ dbus_bool_t _dbus_server_init_base (DBusServer *server, const DBusServerVTable *vtable, const DBusString *address) { server->vtable = vtable; server->refcount.value = 1; server->address = NULL; server->watches = NULL; server->timeouts = NULL; if (!_dbus_string_init (&server->guid_hex)) return FALSE; _dbus_generate_uuid (&server->guid); if (!_dbus_uuid_encode (&server->guid, &server->guid_hex)) goto failed; server->address = copy_address_with_guid_appended (address, &server->guid_hex); if (server->address == NULL) goto failed; _dbus_mutex_new_at_location (&server->mutex); if (server->mutex == NULL) goto failed; server->watches = _dbus_watch_list_new (); if (server->watches == NULL) goto failed; server->timeouts = _dbus_timeout_list_new (); if (server->timeouts == NULL) goto failed; _dbus_data_slot_list_init (&server->slot_list); _dbus_verbose ("Initialized server on address %s\n", server->address); return TRUE; failed: _dbus_mutex_free_at_location (&server->mutex); server->mutex = NULL; if (server->watches) { _dbus_watch_list_free (server->watches); server->watches = NULL; } if (server->timeouts) { _dbus_timeout_list_free (server->timeouts); server->timeouts = NULL; } if (server->address) { dbus_free (server->address); server->address = NULL; } _dbus_string_free (&server->guid_hex); return FALSE; }