svn commit: r211981 - head/sbin/hastd

Pawel Jakub Dawidek pjd at FreeBSD.org
Sun Aug 29 22:55:22 UTC 2010


Author: pjd
Date: Sun Aug 29 22:55:21 2010
New Revision: 211981
URL: http://svn.freebsd.org/changeset/base/211981

Log:
  - Move functionality responsible for checking one connection to separate
    function to make code more readable.
  - Be sure not to reconnect too often in case of signal delivery, etc.
  
  MFC after:	2 weeks
  Obtained from:	Wheel Systems Sp. z o.o. http://www.wheelsystems.com

Modified:
  head/sbin/hastd/primary.c

Modified: head/sbin/hastd/primary.c
==============================================================================
--- head/sbin/hastd/primary.c	Sun Aug 29 22:22:15 2010	(r211980)
+++ head/sbin/hastd/primary.c	Sun Aug 29 22:55:21 2010	(r211981)
@@ -1903,6 +1903,67 @@ keepalive_send(struct hast_resource *res
 	pjdlog_debug(2, "keepalive_send: Request sent.");
 }
 
+static void
+guard_one(struct hast_resource *res, unsigned int ncomp)
+{
+	struct proto_conn *in, *out;
+
+	if (!ISREMOTE(ncomp))
+		return;
+
+	rw_rlock(&hio_remote_lock[ncomp]);
+
+	if (!real_remote(res)) {
+		rw_unlock(&hio_remote_lock[ncomp]);
+		return;
+	}
+
+	if (ISCONNECTED(res, ncomp)) {
+		assert(res->hr_remotein != NULL);
+		assert(res->hr_remoteout != NULL);
+		keepalive_send(res, ncomp);
+	}
+
+	if (ISCONNECTED(res, ncomp)) {
+		assert(res->hr_remotein != NULL);
+		assert(res->hr_remoteout != NULL);
+		rw_unlock(&hio_remote_lock[ncomp]);
+		pjdlog_debug(2, "remote_guard: Connection to %s is ok.",
+		    res->hr_remoteaddr);
+		return;
+	}
+
+	assert(res->hr_remotein == NULL);
+	assert(res->hr_remoteout == NULL);
+	/*
+	 * Upgrade the lock. It doesn't have to be atomic as no other thread
+	 * can change connection status from disconnected to connected.
+	 */
+	rw_unlock(&hio_remote_lock[ncomp]);
+	pjdlog_debug(2, "remote_guard: Reconnecting to %s.",
+	    res->hr_remoteaddr);
+	in = out = NULL;
+	if (init_remote(res, &in, &out)) {
+		rw_wlock(&hio_remote_lock[ncomp]);
+		assert(res->hr_remotein == NULL);
+		assert(res->hr_remoteout == NULL);
+		assert(in != NULL && out != NULL);
+		res->hr_remotein = in;
+		res->hr_remoteout = out;
+		rw_unlock(&hio_remote_lock[ncomp]);
+		pjdlog_info("Successfully reconnected to %s.",
+		    res->hr_remoteaddr);
+		sync_start();
+	} else {
+		/* Both connections should be NULL. */
+		assert(res->hr_remotein == NULL);
+		assert(res->hr_remoteout == NULL);
+		assert(in == NULL && out == NULL);
+		pjdlog_debug(2, "remote_guard: Reconnect to %s failed.",
+		    res->hr_remoteaddr);
+	}
+}
+
 /*
  * Thread guards remote connections and reconnects when needed, handles
  * signals, etc.
@@ -1911,11 +1972,12 @@ static void *
 guard_thread(void *arg)
 {
 	struct hast_resource *res = arg;
-	struct proto_conn *in, *out;
 	unsigned int ii, ncomps;
+	time_t lastcheck, now;
 	int timeout;
 
 	ncomps = HAST_NCOMPONENTS;
+	lastcheck = time(NULL);
 
 	for (;;) {
 		if (sigexit_received) {
@@ -1930,63 +1992,24 @@ guard_thread(void *arg)
 		if (sigchld_received)
 			sigchld_received = false;
 
-		timeout = KEEPALIVE_SLEEP;
 		pjdlog_debug(2, "remote_guard: Checking connections.");
 		mtx_lock(&hio_guard_lock);
+		timeout = KEEPALIVE_SLEEP;
 		for (ii = 0; ii < ncomps; ii++) {
-			if (!ISREMOTE(ii))
-				continue;
-			rw_rlock(&hio_remote_lock[ii]);
-			if (ISCONNECTED(res, ii)) {
-				assert(res->hr_remotein != NULL);
-				assert(res->hr_remoteout != NULL);
-				keepalive_send(res, ii);
+			if (!ISCONNECTED(res, ii)) {
+				timeout = RECONNECT_SLEEP;
+				break;
 			}
-			if (ISCONNECTED(res, ii)) {
-				assert(res->hr_remotein != NULL);
-				assert(res->hr_remoteout != NULL);
-				rw_unlock(&hio_remote_lock[ii]);
-				pjdlog_debug(2,
-				    "remote_guard: Connection to %s is ok.",
-				    res->hr_remoteaddr);
-			} else if (real_remote(res)) {
-				assert(res->hr_remotein == NULL);
-				assert(res->hr_remoteout == NULL);
-				/*
-				 * Upgrade the lock. It doesn't have to be
-				 * atomic as no other thread can change
-				 * connection status from disconnected to
-				 * connected.
-				 */
-				rw_unlock(&hio_remote_lock[ii]);
-				pjdlog_debug(2,
-				    "remote_guard: Reconnecting to %s.",
-				    res->hr_remoteaddr);
-				in = out = NULL;
-				if (init_remote(res, &in, &out)) {
-					rw_wlock(&hio_remote_lock[ii]);
-					assert(res->hr_remotein == NULL);
-					assert(res->hr_remoteout == NULL);
-					assert(in != NULL && out != NULL);
-					res->hr_remotein = in;
-					res->hr_remoteout = out;
-					rw_unlock(&hio_remote_lock[ii]);
-					pjdlog_info("Successfully reconnected to %s.",
-					    res->hr_remoteaddr);
-					sync_start();
-				} else {
-					/* Both connections should be NULL. */
-					assert(res->hr_remotein == NULL);
-					assert(res->hr_remoteout == NULL);
-					assert(in == NULL && out == NULL);
-					pjdlog_debug(2,
-					    "remote_guard: Reconnect to %s failed.",
-					    res->hr_remoteaddr);
+		}
+		now = time(NULL);
+		if (lastcheck + timeout <= now) {
+			timeout = KEEPALIVE_SLEEP;
+			for (ii = 0; ii < ncomps; ii++) {
+				guard_one(res, ii);
+				if (!ISCONNECTED(res, ii))
 					timeout = RECONNECT_SLEEP;
-				}
-			} else {
-				rw_unlock(&hio_remote_lock[ii]);
 			}
+			lastcheck = now;
 		}
 		/* Sleep only if a signal wasn't delivered in the meantime. */
 		if (!sigexit_received && !sighup_received && !sigchld_received)


More information about the svn-src-all mailing list