Hello,

Replace isc_atomic_* in MetaLDAP with reference counter abstraction.
+
Replace isc_atomic_* in instance tainting with reference counter abstraction.

Reference counters are used as abstraction which hides missing isc_atomic_*()
functions on some architectures.


This change is necessary for architectures like s390x and ppc64le where BIND
does not provide isc_atomic_* abstractions.

-- 
Petr^2 Spacek
From 1221199b195c39143ce9d193163241739e93354f Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Wed, 10 Jun 2015 16:51:14 +0200
Subject: [PATCH] Replace isc_atomic_* in instance tainting with reference
 counter abstraction.

Reference counters are used as abstraction which hides missing isc_atomic_*()
functions on some architectures.
---
 src/ldap_helper.c | 40 ++++++++++++++++++++++++++++++++++++----
 src/ldap_helper.h |  6 ++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index d6461a3e83b63555a46ff3f60761e3703d9a6b4e..6804acf95b74528277093f26236f57f4aa0b7d05 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -24,7 +24,6 @@
 #include <dns/soa.h>
 #include <dns/update.h>
 
-#include <isc/atomic.h>
 #include <isc/buffer.h>
 #include <isc/dir.h>
 #include <isc/mem.h>
@@ -37,6 +36,7 @@
 #include <isc/util.h>
 #include <isc/netaddr.h>
 #include <isc/parseint.h>
+#include <isc/refcount.h>
 #include <isc/timer.h>
 #include <isc/serial.h>
 #include <isc/string.h>
@@ -162,7 +162,7 @@ struct ldap_instance {
 	/* Non-zero if this instance 'tainted' by a unrecoverable problem.
 	 * It should be accessed using isc_atomic_*() because it might be
 	 * modified from multiple threads. */
-	isc_int32_t		tainted;
+	isc_refcount_t		errors;
 
 	/* Settings. */
 	settings_set_t		*local_settings;
@@ -517,6 +517,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
 
 	CHECKED_MEM_GET_PTR(mctx, ldap_inst);
 	ZERO_PTR(ldap_inst);
+	CHECK(isc_refcount_init(&ldap_inst->errors, 0));
 	isc_mem_attach(mctx, &ldap_inst->mctx);
 
 	ldap_inst->db_name = db_name;
@@ -663,6 +664,10 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
 	settings_set_free(&ldap_inst->local_settings);
 
 	sync_ctx_free(&ldap_inst->sctx);
+	/* zero out error counter (and do nothing other than that) */
+	ldap_instance_untaint_finish(ldap_inst,
+				     ldap_instance_untaint_start(ldap_inst));
+	isc_refcount_destroy(&ldap_inst->errors);
 
 	MEM_PUT_AND_DETACH(ldap_inst);
 
@@ -4684,10 +4689,37 @@ ldap_instance_isexiting(ldap_instance_t *ldap_inst)
  * (if it is even possible). */
 void
 ldap_instance_taint(ldap_instance_t *ldap_inst) {
-	isc_atomic_store(&ldap_inst->tainted, 1);
+	isc_refcount_increment0(&ldap_inst->errors, NULL);
 }
 
 isc_boolean_t
 ldap_instance_istained(ldap_instance_t *ldap_inst) {
-	return ISC_TF(isc_atomic_cmpxchg(&ldap_inst->tainted, 0, 0) != 0);
+	return ISC_TF(isc_refcount_current(&ldap_inst->errors) != 0);
+}
+
+/**
+ * Pass result of this function to ldap_instance_untaint_finish().
+ */
+unsigned int
+ldap_instance_untaint_start(ldap_instance_t *ldap_inst) {
+	unsigned int errors;
+	errors = isc_refcount_current(&ldap_inst->errors);
+
+	return ISC_TF(errors != 0);
+}
+
+/**
+ * DNS_R_CONTINUE: untainting was not finished - start again.
+ */
+isc_result_t
+ldap_instance_untaint_finish(ldap_instance_t *ldap_inst, unsigned int count) {
+	unsigned int remaining = 0;
+	while (count > 0) {
+		isc_refcount_decrement(&ldap_inst->errors, &remaining);
+		count--;
+	}
+	if (remaining != 0)
+		return DNS_R_CONTINUE;
+	else
+		return ISC_R_SUCCESS;
 }
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
index e81b8aa59d3518b80afec2ad357e859bcb7eac20..b4b1ee59edb3414b305888271dc425980a1fd3df 100644
--- a/src/ldap_helper.h
+++ b/src/ldap_helper.h
@@ -90,4 +90,10 @@ isc_boolean_t ldap_instance_isexiting(ldap_instance_t *ldap_inst) ATTR_NONNULLS
 
 void ldap_instance_taint(ldap_instance_t *ldap_inst) ATTR_NONNULLS;
 
+unsigned int
+ldap_instance_untaint_start(ldap_instance_t *ldap_inst);
+
+isc_result_t
+ldap_instance_untaint_finish(ldap_instance_t *ldap_inst, unsigned int count);
+
 #endif /* !_LD_LDAP_HELPER_H_ */
-- 
2.1.0

From f91cfee843dab9adac2626d88f11566993f58562 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Wed, 10 Jun 2015 18:25:19 +0200
Subject: [PATCH] Replace isc_atomic_* in MetaLDAP with reference counter
 abstraction.

Reference counters are used as abstraction which hides missing isc_atomic_*()
functions on some architectures.
---
 src/mldap.c | 47 +++++++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/mldap.c b/src/mldap.c
index 0c8327ccd7be802c9ee97838d19efb57715328fc..8cffe8a1fbf8eaa20aae79c28ad8d7a305494f19 100644
--- a/src/mldap.c
+++ b/src/mldap.c
@@ -11,6 +11,7 @@
 
 #include <isc/boolean.h>
 #include <isc/net.h>
+#include <isc/refcount.h>
 #include <isc/result.h>
 #include <isc/util.h>
 #include <isc/serial.h>
@@ -47,7 +48,7 @@ static dns_name_t uuid_rootname =
 struct mldapdb {
 	isc_mem_t	*mctx;
 	metadb_t	*mdb;
-	isc_uint32_t	generation;
+	isc_refcount_t	generation;
 };
 
 
@@ -62,8 +63,8 @@ mldap_new(isc_mem_t *mctx, mldapdb_t **mldapp) {
 	ZERO_PTR(mldap);
 	isc_mem_attach(mctx, &mldap->mctx);
 
+	CHECK(isc_refcount_init(&mldap->generation, 0));
 	CHECK(metadb_new(mctx, &mldap->mdb));
-	mldap->generation = 1;
 
 	*mldapp = mldap;
 	return result;
@@ -104,28 +105,39 @@ mldap_closeversion(mldapdb_t *mldap, isc_boolean_t commit) {
  * Atomically increment MetaLDAP generation number.
  */
 void mldap_cur_generation_bump(mldapdb_t *mldap) {
-	isc_uint32_t oldgen;
-	isc_uint32_t curgen;
-	isc_uint32_t newgen;
-
 	REQUIRE(mldap != NULL);
 
-	curgen = isc_atomic_cmpxchg((isc_int32_t *)&mldap->generation, 0, 0);
-	do {
-		oldgen = curgen;
-		newgen = dns_update_soaserial(oldgen, dns_updatemethod_increment);
-		curgen = isc_atomic_cmpxchg((isc_int32_t *)&mldap->generation, oldgen, newgen);
-	} while (curgen != oldgen);
+	isc_refcount_increment0(&mldap->generation, NULL);
 }
 
+/*
+ * Verify that isc_refcount_t can be casted properly to isc_uint32_t
+ * so isc_serial_* functions can be safely used for comparison.
+ *
+ * The spell 'typeof(isc_refcount_current((isc_refcount_t *)0))' walks through
+ * isc_refcount_t abstractions and returns underlying type used for storing the
+ * reference counter value.
+ */
+STATIC_ASSERT((isc_uint32_t)
+		(typeof(isc_refcount_current((isc_refcount_t *)0)))
+		-1
+	      == 0xFFFFFFFF, \
+	      "negative isc_refcount_t cannot be properly shortened to 32 bits");
+
+STATIC_ASSERT((isc_uint32_t)
+		(typeof(isc_refcount_current((isc_refcount_t *)0)))
+		0x90ABCDEF12345678
+	      == 0x12345678, \
+	      "positive isc_refcount_t cannot be properly shortened to 32 bits");
+
 /**
  * Get current MetaLDAP generation number.
  *
  * Generation numbers have to be compared using isc_serial_* functions.
  */
 isc_uint32_t
 mldap_cur_generation_get(mldapdb_t *mldap) {
-	return isc_atomic_cmpxchg((isc_int32_t *)&mldap->generation, 0, 0);
+	return (isc_uint32_t)isc_refcount_current(&mldap->generation);
 }
 
 /**
@@ -209,9 +221,6 @@ cleanup:
 	return result;
 }
 
-
-STATIC_ASSERT((sizeof(((mldapdb_t *)0)->generation) == sizeof(struct in_addr)), \
-		"mldapdb_t->generation is too big for A rdata type");
 /**
  * mldapdb_t->generation is stored inside A record type
  */
@@ -223,8 +232,10 @@ mldap_generation_store(mldapdb_t *mldap, metadb_node_t *node) {
 	dns_rdata_t rdata;
 	isc_uint32_t generation;
 
-	STATIC_ASSERT((sizeof(((mldapdb_t *)0)->generation) == sizeof(generation)), \
-		       "mldapdb_t->generation and local generation size does not match");
+	STATIC_ASSERT(sizeof(mldap_cur_generation_get(mldap)) == sizeof(struct in_addr), \
+		      "mldapdb_t->generation value is too big for A rdata type");
+	STATIC_ASSERT(sizeof(mldap_cur_generation_get(mldap)) == sizeof(generation), \
+		      "mldapdb_t->generation and local generation sizes do not match");
 
 	dns_rdata_init(&rdata);
 
-- 
2.1.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to