about summary refs log tree commit diff
path: root/src/core/dns/nm-dns-plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/dns/nm-dns-plugin.c')
-rw-r--r--src/core/dns/nm-dns-plugin.c161
1 files changed, 134 insertions, 27 deletions
diff --git a/src/core/dns/nm-dns-plugin.c b/src/core/dns/nm-dns-plugin.c
index 847d7839..41a0dbc1 100644
--- a/src/core/dns/nm-dns-plugin.c
+++ b/src/core/dns/nm-dns-plugin.c
@@ -17,11 +17,16 @@
 
 /*****************************************************************************/
 
+enum {
+    UPDATE_PENDING_CHANGED,
+    LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
 typedef struct _NMDnsPluginPrivate {
-    GPid  pid;
-    guint watch_id;
-    char *progname;
-    char *pidfile;
+    bool update_pending_inited : 1;
+    bool update_pending : 1;
 } NMDnsPluginPrivate;
 
 G_DEFINE_ABSTRACT_TYPE(NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT)
@@ -32,26 +37,29 @@ G_DEFINE_ABSTRACT_TYPE(NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT)
 
 #define _NMLOG_PREFIX_NAME "dns-plugin"
 #define _NMLOG_DOMAIN      LOGD_DNS
-#define _NMLOG(level, ...)                                                    \
-    G_STMT_START                                                              \
-    {                                                                         \
-        const NMLogLevel __level = (level);                                   \
-                                                                              \
-        if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) {                     \
-            char                     __prefix[20];                            \
-            const NMDnsPlugin *const __self = (self);                         \
-                                                                              \
-            _nm_log(__level,                                                  \
-                    _NMLOG_DOMAIN,                                            \
-                    0,                                                        \
-                    NULL,                                                     \
-                    NULL,                                                     \
-                    "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),              \
-                    _NMLOG_PREFIX_NAME,                                       \
-                    (!__self ? "" : nm_sprintf_buf(__prefix, "[%p]", __self)) \
-                        _NM_UTILS_MACRO_REST(__VA_ARGS__));                   \
-        }                                                                     \
-    }                                                                         \
+#define _NMLOG(level, ...)                                                                      \
+    G_STMT_START                                                                                \
+    {                                                                                           \
+        const NMLogLevel __level = (level);                                                     \
+                                                                                                \
+        if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) {                                       \
+            char                     __prefix[20];                                              \
+            const NMDnsPlugin *const __self = (self);                                           \
+                                                                                                \
+            _nm_log(__level,                                                                    \
+                    _NMLOG_DOMAIN,                                                              \
+                    0,                                                                          \
+                    NULL,                                                                       \
+                    NULL,                                                                       \
+                    "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),                                \
+                    _NMLOG_PREFIX_NAME,                                                         \
+                    (!__self ? ""                                                               \
+                             : nm_sprintf_buf(__prefix,                                         \
+                                              "[" NM_HASH_OBFUSCATE_PTR_FMT "]",                \
+                                              NM_HASH_OBFUSCATE_PTR(                            \
+                                                  __self))) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
+        }                                                                                       \
+    }                                                                                           \
     G_STMT_END
 
 /*****************************************************************************/
@@ -104,10 +112,109 @@ 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)
-{}
+{
+    NMDnsPluginPrivate *priv;
+
+    priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DNS_PLUGIN, NMDnsPluginPrivate);
+
+    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");
+}
 
 static void
-nm_dns_plugin_class_init(NMDnsPluginClass *plugin_class)
-{}
+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);
+}