diff --git a/src/core/dns/nm-dns-plugin.c b/src/core/dns/nm-dns-plugin.c index 371e51586..41a0dbc13 100644 --- a/src/core/dns/nm-dns-plugin.c +++ b/src/core/dns/nm-dns-plugin.c @@ -17,8 +17,16 @@ /*****************************************************************************/ +enum { + UPDATE_PENDING_CHANGED, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = {0}; + typedef struct _NMDnsPluginPrivate { - int _dummy; + bool update_pending_inited : 1; + bool update_pending : 1; } NMDnsPluginPrivate; G_DEFINE_ABSTRACT_TYPE(NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT) @@ -104,6 +112,79 @@ nm_dns_plugin_stop(NMDnsPlugin *self) /*****************************************************************************/ +static gboolean +_get_update_pending(NMDnsPlugin *self) +{ + NMDnsPluginClass *klass; + + nm_assert(NM_IS_DNS_PLUGIN(self)); + + klass = NM_DNS_PLUGIN_GET_CLASS(self); + if (klass->get_update_pending) { + if (klass->get_update_pending(self)) + return TRUE; + } + return FALSE; +} + +gboolean +nm_dns_plugin_get_update_pending(NMDnsPlugin *self) +{ + NMDnsPluginPrivate *priv; + + g_return_val_if_fail(NM_IS_DNS_PLUGIN(self), FALSE); + + priv = NM_DNS_PLUGIN_GET_PRIVATE(self); + + /* We cache the boolean and rely on the subclass to call + * _nm_dns_plugin_update_pending_maybe_changed(). The subclass + * anyway must get it right to notify us when the value (maybe) + * changes. By caching the value, the subclass is free to notify + * even if the value did not actually change. + * + * Also, this allows the base implementation to combine multiple + * sources/reasons (if we need that in the future). */ + + if (!priv->update_pending_inited) { + priv->update_pending_inited = TRUE; + priv->update_pending = _get_update_pending(self); + _LOGD("[%s] update-pending changed (%spending)", + nm_dns_plugin_get_name(self), + priv->update_pending ? "" : "not "); + } else + nm_assert(priv->update_pending == _get_update_pending(self)); + + return priv->update_pending; +} + +void +_nm_dns_plugin_update_pending_maybe_changed(NMDnsPlugin *self) +{ + NMDnsPluginPrivate *priv; + gboolean v; + + g_return_if_fail(NM_IS_DNS_PLUGIN(self)); + + priv = NM_DNS_PLUGIN_GET_PRIVATE(self); + + v = _get_update_pending(self); + + if (!priv->update_pending_inited) + priv->update_pending_inited = TRUE; + else if (priv->update_pending == v) + return; + + priv->update_pending = v; + + _LOGD("[%s] update-pending changed (%spending)", + nm_dns_plugin_get_name(self), + priv->update_pending ? "" : "not "); + + g_signal_emit(self, signals[UPDATE_PENDING_CHANGED], 0, (gboolean) priv->update_pending); +} + +/*****************************************************************************/ + static void nm_dns_plugin_init(NMDnsPlugin *self) { @@ -113,6 +194,9 @@ nm_dns_plugin_init(NMDnsPlugin *self) self->_priv = priv; + nm_assert(priv->update_pending_inited == FALSE); + nm_assert(priv->update_pending == FALSE); + nm_shutdown_wait_obj_register_object(self, "dns-plugin"); } @@ -122,4 +206,15 @@ nm_dns_plugin_class_init(NMDnsPluginClass *klass) GObjectClass *object_class = G_OBJECT_CLASS(klass); g_type_class_add_private(object_class, sizeof(NMDnsPluginPrivate)); + + signals[UPDATE_PENDING_CHANGED] = g_signal_new(NM_DNS_PLUGIN_UPDATE_PENDING_CHANGED, + G_OBJECT_CLASS_TYPE(klass), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_BOOLEAN); } diff --git a/src/core/dns/nm-dns-plugin.h b/src/core/dns/nm-dns-plugin.h index e52757695..24d6083be 100644 --- a/src/core/dns/nm-dns-plugin.h +++ b/src/core/dns/nm-dns-plugin.h @@ -19,6 +19,8 @@ #define NM_DNS_PLUGIN_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DNS_PLUGIN, NMDnsPluginClass)) +#define NM_DNS_PLUGIN_UPDATE_PENDING_CHANGED "update-pending-changed" + struct _NMDnsPluginPrivate; typedef struct { @@ -42,6 +44,8 @@ typedef struct { void (*stop)(NMDnsPlugin *self); + gboolean (*get_update_pending)(NMDnsPlugin *self); + const char *plugin_name; /* Types should set to TRUE if they start a local caching nameserver @@ -66,4 +70,8 @@ gboolean nm_dns_plugin_update(NMDnsPlugin *self, void nm_dns_plugin_stop(NMDnsPlugin *self); +gboolean nm_dns_plugin_get_update_pending(NMDnsPlugin *self); + +void _nm_dns_plugin_update_pending_maybe_changed(NMDnsPlugin *self); + #endif /* __NM_DNS_PLUGIN_H__ */