[packagekit] packagekit: Branch 'master' - 3 commits
Richard Hughes
hughsient at kemper.freedesktop.org
Wed Feb 20 14:06:07 PST 2008
client/pk-console.c | 198 +++++++++++++++++++---------------------------
libpackagekit/pk-client.c | 11 ++
src/pk-backend.c | 4
src/pk-engine.c | 1
src/pk-main.c | 34 +++++++
5 files changed, 132 insertions(+), 116 deletions(-)
New commits:
commit 534c3c9a4747e88dd5eddad9c34d73440c866f96
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Feb 20 22:04:13 2008 +0000
unload nicely on ctrl-c - which includes closing down the backends
diff --git a/src/pk-backend.c b/src/pk-backend.c
index ff7f596..ce78678 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -912,6 +912,8 @@ pk_backend_finalize (GObject *object)
g_return_if_fail (PK_IS_BACKEND (object));
backend = PK_BACKEND (object);
+ pk_debug ("backend finalise");
+
g_object_unref (backend->priv->time);
g_object_unref (backend->priv->inhibit);
@@ -935,7 +937,7 @@ pk_backend_finalize (GObject *object)
if (backend->priv->handle != NULL) {
g_module_close (backend->priv->handle);
}
-
+ pk_debug ("parent_class->finalize");
G_OBJECT_CLASS (pk_backend_parent_class)->finalize (object);
}
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 98583d6..143eb4c 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -2843,6 +2843,7 @@ pk_engine_finalize (GObject *object)
engine = PK_ENGINE (object);
g_return_if_fail (engine->priv != NULL);
+ pk_debug ("engine finalise");
/* compulsory gobjects */
g_timer_destroy (engine->priv->timer);
diff --git a/src/pk-main.c b/src/pk-main.c
index 5b6693f..9c619ad 100644
--- a/src/pk-main.c
+++ b/src/pk-main.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <string.h>
+#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <glib.h>
@@ -37,6 +38,8 @@
#include "pk-interface.h"
static guint exit_idle_time;
+static PkEngine *engine = NULL;
+static PkBackend *backend = NULL;
/**
* pk_object_register:
@@ -132,6 +135,32 @@ pk_main_timeout_check_cb (PkEngine *engine)
}
/**
+ * pk_main_sigint_handler:
+ **/
+static void
+pk_main_sigint_handler (int sig)
+{
+ pk_debug ("Handling SIGINT");
+
+ /* restore default ASAP, as the finalisers might hang */
+ signal (SIGINT, SIG_DFL);
+
+ /* unlock the backend to call destroy - TODO: we shouldn't have to do this! */
+ pk_backend_unlock (backend);
+
+ /* cleanup */
+ g_object_unref (backend);
+ g_object_unref (engine);
+
+ /* give the backend a sporting chance */
+ g_usleep (500*1000);
+
+ /* kill ourselves */
+ pk_debug ("Retrying SIGINT");
+ kill (getpid (), SIGINT);
+}
+
+/**
* main:
**/
int
@@ -148,8 +177,6 @@ main (int argc, char *argv[])
gboolean immediate_exit = FALSE;
gchar *backend_name = NULL;
PkConf *conf = NULL;
- PkBackend *backend;
- PkEngine *engine = NULL;
GError *error = NULL;
GOptionContext *context;
@@ -192,6 +219,9 @@ main (int argc, char *argv[])
g_thread_init (NULL);
dbus_g_thread_init ();
+ /* do stuff on ctrl-c */
+ signal (SIGINT, pk_main_sigint_handler);
+
/* we need to daemonize before we get a system connection */
if (use_daemon == TRUE && daemon (0, 0)) {
g_error ("Could not daemonize: %s", g_strerror (errno));
commit 8fb39e15313bc6413e95b8ce6bad89773842681d
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Feb 20 21:23:59 2008 +0000
fix a tricky crash in pk_client_finished_cb
If we g_object_unref the client in ::finished (which is valid) we'll
no longer be okay to dereference the client->priv->synchronous and
hence go boom. For this case detect that we are finalised, and let
the finalise quit the loop.
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 19ff300..0e06ca9 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -442,6 +442,12 @@ pk_client_finished_cb (DBusGProxy *proxy,
g_signal_emit (client, signals [PK_CLIENT_FINISHED], 0, exit, runtime);
+ /* check we are still valid */
+ if (PK_IS_CLIENT (client) == FALSE) {
+ pk_debug ("client was g_object_unref'd in finalise, object no longer valid");
+ return;
+ }
+
/* exit our private loop */
if (client->priv->synchronous == TRUE) {
g_main_loop_quit (client->priv->loop);
@@ -3125,6 +3131,9 @@ pk_client_finalize (GObject *object)
g_free (client->priv->tid);
/* clear the loop, if we were using it */
+ if (client->priv->synchronous == TRUE) {
+ g_main_loop_quit (client->priv->loop);
+ }
g_main_loop_unref (client->priv->loop);
/* free the hash table */
commit 547cecd09940a97e2b23edef0ebdbc033036a74d
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Feb 20 20:02:21 2008 +0000
make pkcon less insane. Now we've got pk_client_set_synchronous we can use it to great effect
diff --git a/client/pk-console.c b/client/pk-console.c
index dbb3ced..7eed863 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -46,7 +46,8 @@ static gboolean is_console = FALSE;
static gboolean has_output = FALSE;
static gboolean printed_bar = FALSE;
static guint timer_id = 0;
-static gchar *package_id = NULL;
+static PkClient *client = NULL;
+static PkClient *client_task = NULL;
typedef struct {
gint position;
@@ -357,17 +358,6 @@ const gchar *summary =
" package_id is typically gimp;2:2.4.0-0.rc1.1.fc8;i386;development";
/**
- * pk_client_wait:
- **/
-static gboolean
-pk_client_wait (void)
-{
- pk_debug ("starting loop");
- g_main_loop_run (loop);
- return TRUE;
-}
-
-/**
* pk_console_finished_cb:
**/
static void
@@ -403,10 +393,6 @@ pk_console_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpoint
if (restart != PK_RESTART_ENUM_NONE) {
g_print ("Requires restart: %s\n", pk_restart_enum_to_text (restart));
}
-
- if (loop != NULL) {
- g_main_loop_quit (loop);
- }
}
/**
@@ -417,7 +403,6 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
{
gboolean ret;
gboolean valid;
- PkClient *client_resolve;
const gchar *filter_text;
guint i;
guint length;
@@ -430,34 +415,27 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
}
/* we need to resolve it */
- client_resolve = pk_client_new ();
- g_signal_connect (client_resolve, "finished",
- /* TODO: send local loop */
- G_CALLBACK (pk_console_finished_cb), NULL);
filter_text = pk_filter_enum_to_text (filter);
- pk_client_set_use_buffer (client_resolve, TRUE);
- ret = pk_client_resolve (client_resolve, filter_text, package);
+ ret = pk_client_resolve (client_task, filter_text, package);
if (ret == FALSE) {
pk_warning ("Resolve is not supported in this backend");
return NULL;
- } else {
- g_main_loop_run (loop);
}
/* get length of items found */
- length = pk_client_package_buffer_get_size (client_resolve);
+ length = pk_client_package_buffer_get_size (client_task);
/* only found one, great! */
if (length == 1) {
- item = pk_client_package_buffer_get_item (client_resolve, 0);
- return item->package_id;
+ item = pk_client_package_buffer_get_item (client_task, 0);
+ return g_strdup (item->package_id);
}
/* else list the options if multiple matches found */
if (length != 0) {
g_print ("There are multiple matches\n");
for (i=0; i<length; i++) {
- item = pk_client_package_buffer_get_item (client_resolve, i);
+ item = pk_client_package_buffer_get_item (client_task, i);
g_print ("%i. %s\n", i+1, item->package_id);
}
}
@@ -486,7 +464,7 @@ pk_console_install_package (PkClient *client, const gchar *package)
* pk_console_remove_only:
**/
static gboolean
-pk_console_remove_only (PkClient *client, gboolean force)
+pk_console_remove_only (PkClient *client, const gchar *package_id, gboolean force)
{
gboolean ret;
@@ -501,11 +479,34 @@ pk_console_remove_only (PkClient *client, gboolean force)
}
/**
- * pk_console_requires_finished_cb:
+ * pk_console_remove_package:
**/
-static void
-pk_console_requires_finished_cb (PkClient *client2, PkStatusEnum status, guint runtime, PkClient *client)
+static gboolean
+pk_console_remove_package (PkClient *client, const gchar *package)
{
+ gchar *package_id;
+ package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_INSTALLED, package);
+ if (package_id == NULL) {
+ g_print ("Could not find a package with that name to remove\n");
+ return FALSE;
+ }
+
+ /* are we dumb and can't check for requires? */
+ if (pk_enum_list_contains (role_list, PK_ROLE_ENUM_GET_REQUIRES) == FALSE) {
+ /* no, just try to remove it without deps */
+ pk_console_remove_only (client, package_id, FALSE);
+ g_free (package_id);
+ return TRUE;
+ }
+
+ /* see if any packages require this one */
+ pk_client_reset (client_task);
+ pk_client_set_use_buffer (client_task, TRUE);
+ pk_client_set_synchronous (client_task, TRUE);
+
+ pk_debug ("getting requires for %s", package_id);
+ pk_client_get_requires (client_task, package_id, TRUE);
+
guint length;
PkPackageItem *item;
PkPackageId *ident;
@@ -513,20 +514,20 @@ pk_console_requires_finished_cb (PkClient *client2, PkStatusEnum status, guint r
gboolean remove;
/* see how many packages there are */
- length = pk_client_package_buffer_get_size (client2);
+ length = pk_client_package_buffer_get_size (client_task);
/* if there are no required packages, just do the remove */
if (length == 0) {
pk_debug ("no requires");
- pk_console_remove_only (client, FALSE);
- g_object_unref (client2);
- return;
+ pk_console_remove_only (client, package_id, FALSE);
+ g_free (package_id);
+ return TRUE;
}
/* present this to the user */
g_print ("The following packages have to be removed:\n");
for (i=0; i<length; i++) {
- item = pk_client_package_buffer_get_item (client2, i);
+ item = pk_client_package_buffer_get_item (client_task, i);
ident = pk_package_id_new_from_string (item->package_id);
g_print ("%i\t%s-%s\n", i, ident->name, ident->version);
pk_package_id_free (ident);
@@ -540,46 +541,14 @@ pk_console_requires_finished_cb (PkClient *client2, PkStatusEnum status, guint r
if (remove == FALSE) {
g_print ("Cancelled!\n");
- if (loop != NULL) {
- g_main_loop_quit (loop);
- pk_debug ("<kjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
- }
- } else {
- pk_debug ("the user aggreed, remove with deps");
- pk_console_remove_only (client, TRUE);
- }
- g_object_unref (client2);
-}
-
-/**
- * pk_console_remove_package:
- **/
-static gboolean
-pk_console_remove_package (PkClient *client, const gchar *package)
-{
- PkClient *client2;
-
- g_free (package_id);
- package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_INSTALLED, package);
- if (package_id == NULL) {
- g_print ("Could not find a package with that name to remove\n");
+ g_free (package_id);
return FALSE;
}
- /* are we dumb and can't check for requires? */
- if (pk_enum_list_contains (role_list, PK_ROLE_ENUM_GET_REQUIRES) == FALSE) {
- /* no, just try to remove it without deps */
- pk_console_remove_only (client, FALSE);
- return TRUE;
- }
+ pk_debug ("You agreed, remove with deps");
+ pk_console_remove_only (client, package_id, TRUE);
+ g_free (package_id);
- /* see if any packages require this one */
- client2 = pk_client_new ();
- pk_client_set_use_buffer (client2, TRUE);
- g_signal_connect (client2, "finished",
- G_CALLBACK (pk_console_requires_finished_cb), client);
- pk_debug ("getting requires for %s", package_id);
- pk_client_get_requires (client2, package_id, TRUE);
return TRUE;
}
@@ -695,14 +664,14 @@ pk_console_get_update_detail(PkClient *client, const gchar *package)
* pk_console_process_commands:
**/
static gboolean
-pk_console_process_commands (PkClient *client, int argc, char *argv[], gboolean wait_override, GError **error)
+pk_console_process_commands (PkClient *client, int argc, char *argv[], GError **error)
{
const gchar *mode;
const gchar *value = NULL;
const gchar *details = NULL;
const gchar *parameter = NULL;
- gboolean wait = FALSE;
PkEnumList *elist;
+ gboolean ret = FALSE;
mode = argv[1];
if (argc > 2) {
@@ -724,28 +693,28 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], gboolean
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_client_search_name (client, "none", details);
+ ret = pk_client_search_name (client, "none", details);
}
} else if (strcmp (value, "details") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_client_search_details (client, "none", details);
+ ret = pk_client_search_details (client, "none", details);
}
} else if (strcmp (value, "group") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_client_search_group (client, "none", details);
+ ret = pk_client_search_group (client, "none", details);
}
} else if (strcmp (value, "file") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_client_search_file (client, "none", details);
+ ret = pk_client_search_file (client, "none", details);
}
} else {
g_set_error (error, 0, 0, "invalid search type");
@@ -755,63 +724,63 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], gboolean
g_set_error (error, 0, 0, "you need to specify a package to install");
return FALSE;
} else {
- wait = pk_console_install_package (client, value);
+ ret = pk_console_install_package (client, value);
}
} else if (strcmp (mode, "install-file") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a package to install");
return FALSE;
} else {
- wait = pk_client_install_file (client, value);
+ ret = pk_client_install_file (client, value);
}
} else if (strcmp (mode, "service-pack") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a location to update from");
return FALSE;
} else {
- wait = pk_client_service_pack (client, value);
+ ret = pk_client_service_pack (client, value);
}
} else if (strcmp (mode, "remove") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a package to remove");
return FALSE;
} else {
- wait = pk_console_remove_package (client, value);
+ ret = pk_console_remove_package (client, value);
}
} else if (strcmp (mode, "update") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a package to update");
return FALSE;
} else {
- wait = pk_console_update_package (client, value);
+ ret = pk_console_update_package (client, value);
}
} else if (strcmp (mode, "resolve") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a package name to resolve");
return FALSE;
} else {
- wait = pk_client_resolve (client, "none", value);
+ ret = pk_client_resolve (client, "none", value);
}
} else if (strcmp (mode, "enable-repo") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a repo name");
return FALSE;
} else {
- pk_client_repo_enable (client, value, TRUE);
+ ret = pk_client_repo_enable (client, value, TRUE);
}
} else if (strcmp (mode, "disable-repo") == 0) {
if (value == NULL) {
g_set_error (error, 0, 0, "you need to specify a repo name");
return FALSE;
} else {
- wait = pk_client_repo_enable (client, value, FALSE);
+ ret = pk_client_repo_enable (client, value, FALSE);
}
} else if (strcmp (mode, "set-repo-data") == 0) {
if (value == NULL || details == NULL || parameter == NULL) {
g_set_error (error, 0, 0, "you need to specify a repo name/parameter and value");
return FALSE;
} else {
- wait = pk_client_repo_set_data (client, value, details, parameter);
+ ret = pk_client_repo_set_data (client, value, details, parameter);
}
} else if (strcmp (mode, "get") == 0) {
if (value == NULL) {
@@ -841,38 +810,38 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], gboolean
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_console_get_depends (client, details);
+ ret = pk_console_get_depends (client, details);
}
} else if (strcmp (value, "updatedetail") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_console_get_update_detail (client, details);
+ ret = pk_console_get_update_detail (client, details);
}
} else if (strcmp (value, "requires") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a search term");
return FALSE;
} else {
- wait = pk_console_get_requires (client, details);
+ ret = pk_console_get_requires (client, details);
}
} else if (strcmp (value, "description") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a package to find the description for");
return FALSE;
} else {
- wait = pk_console_get_description (client, details);
+ ret = pk_console_get_description (client, details);
}
} else if (strcmp (value, "files") == 0) {
if (details == NULL) {
g_set_error (error, 0, 0, "you need to specify a package to find the files for");
return FALSE;
} else {
- wait = pk_console_get_files (client, details);
+ ret = pk_console_get_files (client, details);
}
} else if (strcmp (value, "updates") == 0) {
- wait = pk_client_get_updates (client);
+ ret = pk_client_get_updates (client);
} else if (strcmp (value, "actions") == 0) {
elist = pk_client_get_actions (client);
pk_enum_list_print (elist);
@@ -882,31 +851,26 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], gboolean
pk_enum_list_print (elist);
g_object_unref (elist);
} else if (strcmp (value, "repos") == 0) {
- wait = pk_client_get_repo_list (client);
+ ret = pk_client_get_repo_list (client);
} else if (strcmp (value, "groups") == 0) {
elist = pk_client_get_groups (client);
pk_enum_list_print (elist);
g_object_unref (elist);
} else if (strcmp (value, "transactions") == 0) {
- wait = pk_client_get_old_transactions (client, 10);
+ ret = pk_client_get_old_transactions (client, 10);
} else {
g_set_error (error, 0, 0, "invalid get type");
}
} else if (strcmp (mode, "update-system") == 0) {
- wait = pk_client_update_system (client);
+ ret = pk_client_update_system (client);
} else if (strcmp (mode, "refresh") == 0) {
- wait = pk_client_refresh_cache (client, FALSE);
+ ret = pk_client_refresh_cache (client, FALSE);
} else if (strcmp (mode, "force-refresh") == 0) {
- wait = pk_client_refresh_cache (client, TRUE);
+ ret = pk_client_refresh_cache (client, TRUE);
} else {
g_set_error (error, 0, 0, "option not yet supported");
}
-
- /* only wait if success */
- if (wait == TRUE && wait_override == TRUE) {
- pk_client_wait ();
- }
- return TRUE;
+ return ret;
}
/**
@@ -1000,10 +964,8 @@ static void
pk_connection_changed_cb (PkConnection *pconnection, gboolean connected, gpointer data)
{
/* if the daemon crashed, don't hang around */
- if (connected == FALSE && loop != NULL) {
- pk_warning ("The daemon went away...");
- g_main_loop_quit (loop);
- }
+ g_print ("The daemon crashed mid transaction. This is bad\n");
+ exit (2);
}
/**
@@ -1014,13 +976,13 @@ main (int argc, char *argv[])
{
DBusGConnection *system_connection;
GError *error = NULL;
- PkClient *client;
PkConnection *pconnection;
gboolean verbose = FALSE;
gboolean program_version = FALSE;
gboolean nowait = FALSE;
GOptionContext *context;
gchar *options_help;
+ gboolean ret;
const GOptionEntry options[] = {
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
@@ -1077,6 +1039,8 @@ main (int argc, char *argv[])
G_CALLBACK (pk_connection_changed_cb), loop);
client = pk_client_new ();
+ pk_client_set_use_buffer (client, TRUE);
+ pk_client_set_synchronous (client, !nowait);
g_signal_connect (client, "package",
G_CALLBACK (pk_console_package_cb), NULL);
g_signal_connect (client, "transaction",
@@ -1098,11 +1062,20 @@ main (int argc, char *argv[])
g_signal_connect (client, "error-code",
G_CALLBACK (pk_console_error_code_cb), NULL);
+ client_task = pk_client_new ();
+ pk_client_set_use_buffer (client_task, TRUE);
+ pk_client_set_synchronous (client_task, TRUE);
+ g_signal_connect (client, "finished",
+ G_CALLBACK (pk_console_finished_cb), NULL);
+
role_list = pk_client_get_actions (client);
pk_debug ("actions=%s", pk_enum_list_to_string (role_list));
/* run the commands */
- pk_console_process_commands (client, argc, argv, !nowait, &error);
+ ret = pk_console_process_commands (client, argc, argv, &error);
+ if (ret == FALSE) {
+ g_print ("Command failed\n");
+ }
if (error != NULL) {
g_print ("Error:\n %s\n\n", error->message);
g_error_free (error);
@@ -1111,6 +1084,7 @@ main (int argc, char *argv[])
g_free (options_help);
g_object_unref (client);
+ g_object_unref (client_task);
return 0;
}
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 9f2558a..19ff300 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -440,7 +440,7 @@ pk_client_finished_cb (DBusGProxy *proxy,
/* only this instance is finished, and do it before the signal so we can reset */
client->priv->is_finished = TRUE;
- g_signal_emit (client , signals [PK_CLIENT_FINISHED], 0, exit, runtime);
+ g_signal_emit (client, signals [PK_CLIENT_FINISHED], 0, exit, runtime);
/* exit our private loop */
if (client->priv->synchronous == TRUE) {
More information about the PackageKit
mailing list