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).
This commit is contained in:
Thomas Haller 2022-10-06 10:13:14 +02:00
parent 67ee036389
commit 2f5a2dc732
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 43 additions and 6 deletions

View file

@ -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(

View file

@ -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);

View file

@ -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())