daemon: Make the Transaction.Start() method idempotent

Add a boolean return so callers can distinguish between actually starting
the transaction or reattaching to an in-progress transaction.
This commit is contained in:
Matthew Barnes 2015-08-26 11:29:06 -04:00
parent 6e28454e6d
commit 24f01556a0
3 changed files with 24 additions and 11 deletions

View File

@ -489,6 +489,7 @@ rpmostree_transaction_get_response_sync (RPMOSTreeSysroot *sysroot_proxy,
gint cancel_handler; gint cancel_handler;
gulong signal_handler = 0; gulong signal_handler = 0;
gboolean success = FALSE; gboolean success = FALSE;
gboolean just_started = FALSE;
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (sysroot_proxy)); connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (sysroot_proxy));
@ -544,10 +545,21 @@ rpmostree_transaction_get_response_sync (RPMOSTreeSysroot *sysroot_proxy,
/* Tell the server we're ready to receive signals. */ /* Tell the server we're ready to receive signals. */
if (!rpmostree_transaction_call_start_sync (transaction, if (!rpmostree_transaction_call_start_sync (transaction,
&just_started,
cancellable, cancellable,
error)) error))
goto out; goto out;
/* FIXME Use the 'just_started' flag to determine whether to print
* a message about reattaching to an in-progress transaction,
* like:
*
* Existing upgrade in progress, reattaching. Control-C to cancel.
*
* But that requires having a printable description of the
* operation. Maybe just add a string arg to this function?
*/
g_main_loop_run (tp->loop); g_main_loop_run (tp->loop);
g_cancellable_disconnect (cancellable, cancel_handler); g_cancellable_disconnect (cancellable, cancel_handler);

View File

@ -106,8 +106,13 @@
<!-- Yes, we can. --> <!-- Yes, we can. -->
<method name="Cancel"/> <method name="Cancel"/>
<!-- For owner to call when ready to receive signals --> <!-- For a client to call when ready to receive signals.
<method name="Start"/> The return boolean indicates whether the transaction was
started by this method call (true) or was already started
by another client (false). -->
<method name="Start">
<arg type="b" name="started" direction="out"/>
</method>
<signal name="Finished"> <signal name="Finished">
<arg name="success" type="b" direction="out"/> <arg name="success" type="b" direction="out"/>

View File

@ -506,6 +506,7 @@ transaction_handle_start (RPMOSTreeTransaction *transaction,
{ {
RpmostreedTransaction *self = RPMOSTREED_TRANSACTION (transaction); RpmostreedTransaction *self = RPMOSTREED_TRANSACTION (transaction);
RpmostreedTransactionPrivate *priv = rpmostreed_transaction_get_private (self); RpmostreedTransactionPrivate *priv = rpmostreed_transaction_get_private (self);
gboolean started = FALSE;
/* The bus name watch ID doubles as a "not-yet-started" flag. /* The bus name watch ID doubles as a "not-yet-started" flag.
* Once started the transaction proceeds independently of the * Once started the transaction proceeds independently of the
@ -514,6 +515,8 @@ transaction_handle_start (RPMOSTreeTransaction *transaction,
{ {
GTask *task; GTask *task;
started = TRUE;
g_debug ("%s (%p): Started", G_OBJECT_TYPE_NAME (self), self); g_debug ("%s (%p): Started", G_OBJECT_TYPE_NAME (self), self);
g_bus_unwatch_name (priv->watch_id); g_bus_unwatch_name (priv->watch_id);
@ -525,16 +528,9 @@ transaction_handle_start (RPMOSTreeTransaction *transaction,
NULL); NULL);
g_task_run_in_thread (task, transaction_execute_thread); g_task_run_in_thread (task, transaction_execute_thread);
g_object_unref (task); g_object_unref (task);
}
rpmostree_transaction_complete_start (transaction, invocation); rpmostree_transaction_complete_start (transaction, invocation, started);
}
else
{
g_dbus_method_invocation_return_error (invocation,
RPM_OSTREED_ERROR,
RPM_OSTREED_ERROR_FAILED,
"Transaction has already started");
}
return TRUE; return TRUE;
} }