summaryrefslogtreecommitdiffstats
path: root/src/common/HeartbeatMap.cc
diff options
context:
space:
mode:
authorSage Weil <sage.weil@dreamhost.com>2011-07-28 07:38:43 +0200
committerSage Weil <sage@newdream.net>2011-07-28 18:49:23 +0200
commitbdfccb099723f42fd543422acc8745aabeb8b738 (patch)
tree6b3f8e201872f3a2e32bc99d629b29accd89229b /src/common/HeartbeatMap.cc
parentmds: mark ambig imports in ESubtreeMap during resolve (diff)
downloadceph-bdfccb099723f42fd543422acc8745aabeb8b738.tar.xz
ceph-bdfccb099723f42fd543422acc8745aabeb8b738.zip
heartbeatmap: introduce heartbeat_map
Each thread registered and gets a private structure it can write a timeout value to. The timeout is time_t and always fits in a single word, so no locking is used to update it. Anyone can call is_healthy() to find out if any timeouts have expired. Eventually some background thread will do this. Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
Diffstat (limited to 'src/common/HeartbeatMap.cc')
-rw-r--r--src/common/HeartbeatMap.cc80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/common/HeartbeatMap.cc b/src/common/HeartbeatMap.cc
new file mode 100644
index 00000000000..b5c20f33eac
--- /dev/null
+++ b/src/common/HeartbeatMap.cc
@@ -0,0 +1,80 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include <time.h>
+
+#include "HeartbeatMap.h"
+#include "ceph_context.h"
+
+#include "debug.h"
+#define DOUT_SUBSYS heartbeatmap
+#undef dout_prefix
+#define dout_prefix *_dout << "heartbeat_map "
+
+
+HeartbeatMap::HeartbeatMap(CephContext *cct)
+ : m_cct(cct),
+ m_rwlock("HeartbeatMap::m_rwlock")
+{
+}
+
+HeartbeatMap::~HeartbeatMap()
+{
+}
+
+heartbeat_handle_d *HeartbeatMap::add_worker(pthread_t thread, string name)
+{
+ m_rwlock.get_write();
+ ldout(m_cct, 10) << "add_worker " << thread << " '" << name << "'" << dendl;
+ assert(m_workers.count(thread) == 0);
+ heartbeat_handle_d *h = new heartbeat_handle_d(thread, name);
+ m_workers[thread] = h;
+ m_rwlock.put_write();
+ return h;
+}
+
+void HeartbeatMap::remove_worker(heartbeat_handle_d *h)
+{
+ m_rwlock.get_write();
+ ldout(m_cct, 10) << "remove_worker " << h->thread << " '" << h->name << "'" << dendl;
+ map<pthread_t, heartbeat_handle_d*>::iterator p = m_workers.find(h->thread);
+ assert(p != m_workers.end());
+ m_workers.erase(p);
+ m_rwlock.put_write();
+ delete h;
+}
+
+void HeartbeatMap::touch_worker(heartbeat_handle_d *h, time_t grace)
+{
+ ldout(m_cct, 20) << "touch_worker " << h->thread << " grace " << grace << dendl;
+ h->timeout = time(NULL) + grace;
+}
+
+bool HeartbeatMap::is_healthy()
+{
+ m_rwlock.get_read();
+ time_t now = time(NULL);
+ bool healthy = true;
+ for (map<pthread_t, heartbeat_handle_d*>::iterator p = m_workers.begin();
+ p != m_workers.end();
+ ++p)
+ if (p->second->timeout && p->second->timeout < now) {
+ ldout(m_cct, 0) << "is_healthy " << p->first << " '" << p->second->name << "'"
+ << " timed out" << dendl;
+ healthy = false;
+ }
+ m_rwlock.put_read();
+ return healthy;
+}
+