summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-10-06 10:13:14 +0200
committerThomas Haller <thaller@redhat.com>2022-10-14 17:37:03 +0200
commit2f5a2dc7327f969003e4c526ce3a0c9e83d75204 (patch)
tree483e03826a37a08950efd1f0c10a321f0eb7a3dd
parent67ee0363899b3c926118a53515b1a633377f1d82 (diff)
downloadNetworkManager-2f5a2dc7327f969003e4c526ce3a0c9e83d75204.tar.gz
libnm: add "initialized-{good,bad}" flags to NMClientInstanceFlags
When using async initialization with GAsyncInitable, the user usually can only know that initialization is complete by passing a callback. In simple cases, that can be cumbersome. Also expose a flag that allows to poll that information. Reuse the existing NM_CLIENT_INSTANCE_FLAGS for that. There is an ugliness here, that suddenly there are instance flags that cannot be set, but are still returned by the getter. But as this is a relatively obscure feature, it seems more lightweight to implement it this way (instead of adding a separate property and getter function).
-rw-r--r--src/libnm-client-impl/nm-client.c27
-rw-r--r--src/libnm-client-impl/nm-libnm-utils.h11
-rw-r--r--src/libnm-client-public/nm-client.h11
3 files changed, 43 insertions, 6 deletions
diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c
index a2ca833336..a16f9873db 100644
--- a/src/libnm-client-impl/nm-client.c
+++ b/src/libnm-client-impl/nm-client.c
@@ -287,7 +287,7 @@ typedef struct {
guint dbsid_nm_vpn_connection_state_changed;
guint dbsid_nm_check_permissions;
- NMClientInstanceFlags instance_flags : 3;
+ NMClientInstanceFlags instance_flags : 5;
NMTernary permissions_state : 3;
@@ -7277,7 +7277,8 @@ nml_cleanup_context_busy_watcher_on_idle(GObject *context_busy_watcher_take, GMa
static void
_init_start_complete(NMClient *self, GError *error_take)
{
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
+ gs_unref_object NMClient *self_keep_alive = g_object_ref(self);
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
NML_NMCLIENT_LOG_D(
self,
@@ -7285,6 +7286,11 @@ _init_start_complete(NMClient *self, GError *error_take)
priv->init_data->is_sync ? "sync" : "async",
NM_PRINT_FMT_QUOTED(error_take, "error: ", error_take->message, "", "success"));
+ priv->instance_flags |= (error_take ? NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD
+ : NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD);
+
+ _notify(self, PROP_INSTANCE_FLAGS);
+
nml_init_data_return(g_steal_pointer(&priv->init_data), error_take);
}
@@ -7585,8 +7591,18 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
/* construct */
v_uint = g_value_get_uint(value);
- g_return_if_fail(!NM_FLAGS_ANY(v_uint, ~((guint) NM_CLIENT_INSTANCE_FLAGS_ALL)));
- v_uint &= ((guint) NM_CLIENT_INSTANCE_FLAGS_ALL);
+
+ /* Silently ignore "initialized-{good,bad}" flags. They are only set internally
+ * and cannot be change by the user. However, accept the caller to set them,
+ * so that
+ * nmc.props.instance_flags = nmc.props.instance_flags | NM.ClientInstanceFlags.NO_AUTO_FETCH_PERMISSIONS
+ * works. */
+ v_uint &= ~((guint) (NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD
+ | NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD));
+
+ g_return_if_fail(!NM_FLAGS_ANY(v_uint, ~((guint) NM_CLIENT_INSTANCE_FLAGS_ALL_WRITABLE)));
+
+ v_uint &= ((guint) NM_CLIENT_INSTANCE_FLAGS_ALL_WRITABLE);
if (!priv->instance_flags_constructed) {
priv->instance_flags_constructed = TRUE;
@@ -8175,6 +8191,9 @@ nm_client_class_init(NMClientClass *client_class)
* property to know whether permissions are ready. Note that permissions are only fetched
* when NMClient has a D-Bus name owner.
*
+ * The flags %NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD and %NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD
+ * cannot be set, however they will be returned by the getter after initialization completes.
+ *
* Since: 1.24
*/
obj_properties[PROP_INSTANCE_FLAGS] = g_param_spec_uint(
diff --git a/src/libnm-client-impl/nm-libnm-utils.h b/src/libnm-client-impl/nm-libnm-utils.h
index 9d9cfa2530..da13c615cb 100644
--- a/src/libnm-client-impl/nm-libnm-utils.h
+++ b/src/libnm-client-impl/nm-libnm-utils.h
@@ -227,7 +227,16 @@ typedef enum {
/*****************************************************************************/
-#define NM_CLIENT_INSTANCE_FLAGS_ALL ((NMClientInstanceFlags) 0x1)
+#define NM_CLIENT_INSTANCE_FLAGS_ALL \
+ ((NMClientInstanceFlags) (NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS \
+ | NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD \
+ | NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD))
+
+#define NM_CLIENT_INSTANCE_FLAGS_ALL_WRITABLE \
+ ((NMClientInstanceFlags) (NM_CLIENT_INSTANCE_FLAGS_ALL \
+ & ~(( \
+ NMClientInstanceFlags) (NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD \
+ | NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD))))
typedef struct {
GType (*get_o_type_fcn)(void);
diff --git a/src/libnm-client-public/nm-client.h b/src/libnm-client-public/nm-client.h
index 6307f11217..02481a8145 100644
--- a/src/libnm-client-public/nm-client.h
+++ b/src/libnm-client-public/nm-client.h
@@ -22,12 +22,21 @@ G_BEGIN_DECLS
* can be disabled. You can toggle this flag to enable and disable automatic
* fetching of the permissions. Watch also nm_client_get_permissions_state()
* to know whether the permissions are up to date.
+ * @NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD: as #NMClient is an GInitable
+ * and GAsyncInitable, nm_client_get_instance_flags() returns this flag
+ * once initialization completed with success. This flag cannot be set
+ * as NM_CLIENT_INSTANCE_FLAGS property. Since: 1.42.
+ * @NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD: like @NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD
+ * indicates that the instance completed initialization with failure. In that
+ * case the instance is unusable. Since: 1.42.
*
* Since: 1.24
*/
typedef enum /*< flags >*/ {
NM_CLIENT_INSTANCE_FLAGS_NONE = 0,
- NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS = 1,
+ NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS = 0x1,
+ NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_GOOD = 0x2,
+ NM_CLIENT_INSTANCE_FLAGS_INITIALIZED_BAD = 0x4,
} NMClientInstanceFlags;
#define NM_TYPE_CLIENT (nm_client_get_type())