mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 15:48:06 +02:00
core/ovs: allow ovsdb calls to be cancelled
In general, providing an async API also requires the ability to cancel requests. It's not yet used, but add a way to handle a GCancellable.
This commit is contained in:
parent
8b4d77a453
commit
c44c8e7fbc
1 changed files with 74 additions and 6 deletions
|
|
@ -90,8 +90,11 @@ typedef struct {
|
||||||
guint64 call_id;
|
guint64 call_id;
|
||||||
OvsdbCommand command;
|
OvsdbCommand command;
|
||||||
OvsdbMethodCallback callback;
|
OvsdbMethodCallback callback;
|
||||||
|
GCancellable * cancellable;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
OvsdbMethodPayload payload;
|
OvsdbMethodPayload payload;
|
||||||
|
gulong cancellable_id;
|
||||||
|
guint timeout_id;
|
||||||
} OvsdbMethodCall;
|
} OvsdbMethodCall;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
@ -238,6 +241,9 @@ _call_complete(OvsdbMethodCall *call, json_t *response, GError *error)
|
||||||
{
|
{
|
||||||
c_list_unlink_stale(&call->calls_lst);
|
c_list_unlink_stale(&call->calls_lst);
|
||||||
|
|
||||||
|
nm_clear_g_signal_handler(call->cancellable, &call->cancellable_id);
|
||||||
|
g_clear_object(&call->cancellable);
|
||||||
|
|
||||||
if (call->callback)
|
if (call->callback)
|
||||||
call->callback(call->self, response, error, call->user_data);
|
call->callback(call->self, response, error, call->user_data);
|
||||||
|
|
||||||
|
|
@ -330,6 +336,49 @@ _signal_emit_interface_failed(NMOvsdb * self,
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_method_call_cancelled_on_idle_cb(gpointer user_data)
|
||||||
|
{
|
||||||
|
OvsdbMethodCall *call = user_data;
|
||||||
|
gs_unref_object NMOvsdb *self = call->self;
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
|
||||||
|
call->timeout_id = 0;
|
||||||
|
_LOGT_call("cancelled (run on idle)", call, NULL);
|
||||||
|
nm_utils_error_set_cancelled(&error, FALSE, "NMOvsdb");
|
||||||
|
_call_complete(call, NULL, error);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_method_call_cancelled_cb(gpointer user_data)
|
||||||
|
{
|
||||||
|
OvsdbMethodCall *call = user_data;
|
||||||
|
NMOvsdb * self = call->self;
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
|
||||||
|
nm_assert(NM_IS_OVSDB(self));
|
||||||
|
|
||||||
|
if (call->cancellable_id == 0) {
|
||||||
|
/* We are invoked synchronously by g_cancellable_connection().
|
||||||
|
* Let's consistently emit the completion callback asynchronously,
|
||||||
|
* hence schedule it on an idle handler. */
|
||||||
|
c_list_unlink(&call->calls_lst);
|
||||||
|
g_object_ref(self);
|
||||||
|
nm_clear_g_source(&call->timeout_id);
|
||||||
|
_LOGT_call("cancelled (schedule on idle)", call, NULL);
|
||||||
|
call->timeout_id = g_idle_add(_method_call_cancelled_on_idle_cb, call);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_utils_error_set_cancelled(&error, FALSE, "NMOvsdb");
|
||||||
|
_call_complete(call, NULL, error);
|
||||||
|
|
||||||
|
_LOGT_call("cancelled", call, NULL);
|
||||||
|
|
||||||
|
ovsdb_next_command(self);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ovsdb_call_method:
|
* ovsdb_call_method:
|
||||||
*
|
*
|
||||||
|
|
@ -340,6 +389,7 @@ static void
|
||||||
ovsdb_call_method(NMOvsdb * self,
|
ovsdb_call_method(NMOvsdb * self,
|
||||||
OvsdbMethodCallback callback,
|
OvsdbMethodCallback callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
|
GCancellable * cancellable,
|
||||||
gboolean add_first,
|
gboolean add_first,
|
||||||
OvsdbCommand command,
|
OvsdbCommand command,
|
||||||
const OvsdbMethodPayload *payload)
|
const OvsdbMethodPayload *payload)
|
||||||
|
|
@ -352,11 +402,12 @@ ovsdb_call_method(NMOvsdb * self,
|
||||||
|
|
||||||
call = g_slice_new(OvsdbMethodCall);
|
call = g_slice_new(OvsdbMethodCall);
|
||||||
*call = (OvsdbMethodCall){
|
*call = (OvsdbMethodCall){
|
||||||
.self = self,
|
.self = self,
|
||||||
.call_id = CALL_ID_UNSPEC,
|
.call_id = CALL_ID_UNSPEC,
|
||||||
.command = command,
|
.command = command,
|
||||||
.callback = callback,
|
.callback = callback,
|
||||||
.user_data = user_data,
|
.user_data = user_data,
|
||||||
|
.cancellable = nm_g_object_ref(cancellable),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (add_first)
|
if (add_first)
|
||||||
|
|
@ -364,7 +415,7 @@ ovsdb_call_method(NMOvsdb * self,
|
||||||
else
|
else
|
||||||
c_list_link_tail(&priv->calls_lst_head, &call->calls_lst);
|
c_list_link_tail(&priv->calls_lst_head, &call->calls_lst);
|
||||||
|
|
||||||
/* Mmigrate the arguments from @payload to @call->payload. Technically,
|
/* Migrate the arguments from @payload to @call->payload. Technically,
|
||||||
* this is not a plain copy, because
|
* this is not a plain copy, because
|
||||||
* - call->payload is not initialized (thus no need to free the previous data).
|
* - call->payload is not initialized (thus no need to free the previous data).
|
||||||
* - payload does not own the data. It is merely initialized using the
|
* - payload does not own the data. It is merely initialized using the
|
||||||
|
|
@ -397,6 +448,19 @@ ovsdb_call_method(NMOvsdb * self,
|
||||||
|
|
||||||
_LOGT_call("enqueue", call, NULL);
|
_LOGT_call("enqueue", call, NULL);
|
||||||
|
|
||||||
|
if (call->cancellable) {
|
||||||
|
gulong id;
|
||||||
|
|
||||||
|
id = g_cancellable_connect(call->cancellable,
|
||||||
|
G_CALLBACK(_method_call_cancelled_cb),
|
||||||
|
call,
|
||||||
|
NULL);
|
||||||
|
if (id == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
call->cancellable_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
ovsdb_next_command(self);
|
ovsdb_next_command(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2131,6 +2195,7 @@ ovsdb_try_connect(NMOvsdb *self)
|
||||||
ovsdb_call_method(self,
|
ovsdb_call_method(self,
|
||||||
_monitor_bridges_cb,
|
_monitor_bridges_cb,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
TRUE,
|
TRUE,
|
||||||
OVSDB_MONITOR,
|
OVSDB_MONITOR,
|
||||||
OVSDB_METHOD_PAYLOAD_MONITOR());
|
OVSDB_METHOD_PAYLOAD_MONITOR());
|
||||||
|
|
@ -2201,6 +2266,7 @@ nm_ovsdb_add_interface(NMOvsdb * self,
|
||||||
ovsdb_call_method(self,
|
ovsdb_call_method(self,
|
||||||
_transact_cb,
|
_transact_cb,
|
||||||
ovsdb_call_new(callback, user_data),
|
ovsdb_call_new(callback, user_data),
|
||||||
|
NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
OVSDB_ADD_INTERFACE,
|
OVSDB_ADD_INTERFACE,
|
||||||
OVSDB_METHOD_PAYLOAD_ADD_INTERFACE(bridge,
|
OVSDB_METHOD_PAYLOAD_ADD_INTERFACE(bridge,
|
||||||
|
|
@ -2219,6 +2285,7 @@ nm_ovsdb_del_interface(NMOvsdb * self,
|
||||||
ovsdb_call_method(self,
|
ovsdb_call_method(self,
|
||||||
_transact_cb,
|
_transact_cb,
|
||||||
ovsdb_call_new(callback, user_data),
|
ovsdb_call_new(callback, user_data),
|
||||||
|
NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
OVSDB_DEL_INTERFACE,
|
OVSDB_DEL_INTERFACE,
|
||||||
OVSDB_METHOD_PAYLOAD_DEL_INTERFACE(ifname));
|
OVSDB_METHOD_PAYLOAD_DEL_INTERFACE(ifname));
|
||||||
|
|
@ -2234,6 +2301,7 @@ nm_ovsdb_set_interface_mtu(NMOvsdb * self,
|
||||||
ovsdb_call_method(self,
|
ovsdb_call_method(self,
|
||||||
_transact_cb,
|
_transact_cb,
|
||||||
ovsdb_call_new(callback, user_data),
|
ovsdb_call_new(callback, user_data),
|
||||||
|
NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
OVSDB_SET_INTERFACE_MTU,
|
OVSDB_SET_INTERFACE_MTU,
|
||||||
OVSDB_METHOD_PAYLOAD_SET_INTERFACE_MTU(ifname, mtu));
|
OVSDB_METHOD_PAYLOAD_SET_INTERFACE_MTU(ifname, mtu));
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue