using ceph::operator <<;
-class SafeTimerThread : public Thread {
- SafeTimer *parent;
+template <class Mutex>
+class CommonSafeTimerThread : public Thread {
+ CommonSafeTimer<Mutex> *parent;
public:
- explicit SafeTimerThread(SafeTimer *s) : parent(s) {}
+ explicit CommonSafeTimerThread(CommonSafeTimer<Mutex> *s) : parent(s) {}
void *entry() override {
parent->timer_thread();
return NULL;
}
};
-
-SafeTimer::SafeTimer(CephContext *cct_, ceph::mutex &l, bool safe_callbacks)
+template <class Mutex>
+CommonSafeTimer<Mutex>::CommonSafeTimer(CephContext *cct_, Mutex &l, bool safe_callbacks)
: cct(cct_), lock(l),
safe_callbacks(safe_callbacks),
thread(NULL),
{
}
-SafeTimer::~SafeTimer()
+template <class Mutex>
+CommonSafeTimer<Mutex>::~CommonSafeTimer()
{
ceph_assert(thread == NULL);
}
-void SafeTimer::init()
+template <class Mutex>
+void CommonSafeTimer<Mutex>::init()
{
ldout(cct,10) << "init" << dendl;
- thread = new SafeTimerThread(this);
+ thread = new CommonSafeTimerThread<Mutex>(this);
thread->create("safe_timer");
}
-void SafeTimer::shutdown()
+template <class Mutex>
+void CommonSafeTimer<Mutex>::shutdown()
{
ldout(cct,10) << "shutdown" << dendl;
if (thread) {
}
}
-void SafeTimer::timer_thread()
+template <class Mutex>
+void CommonSafeTimer<Mutex>::timer_thread()
{
std::unique_lock l{lock};
ldout(cct,10) << "timer_thread starting" << dendl;
ldout(cct,10) << "timer_thread exiting" << dendl;
}
-Context* SafeTimer::add_event_after(double seconds, Context *callback)
+template <class Mutex>
+Context* CommonSafeTimer<Mutex>::add_event_after(double seconds, Context *callback)
{
return add_event_after(ceph::make_timespan(seconds), callback);
}
-Context* SafeTimer::add_event_after(ceph::timespan duration, Context *callback)
+template <class Mutex>
+Context* CommonSafeTimer<Mutex>::add_event_after(ceph::timespan duration, Context *callback)
{
ceph_assert(ceph_mutex_is_locked(lock));
return add_event_at(when, callback);
}
-Context* SafeTimer::add_event_at(SafeTimer::clock_t::time_point when, Context *callback)
+template <class Mutex>
+Context* CommonSafeTimer<Mutex>::add_event_at(CommonSafeTimer<Mutex>::clock_t::time_point when, Context *callback)
{
ceph_assert(ceph_mutex_is_locked(lock));
ldout(cct,10) << __func__ << " " << when << " -> " << callback << dendl;
return callback;
}
-Context* SafeTimer::add_event_at(ceph::real_clock::time_point when, Context *callback)
+template <class Mutex>
+Context* CommonSafeTimer<Mutex>::add_event_at(ceph::real_clock::time_point when, Context *callback)
{
ceph_assert(ceph_mutex_is_locked(lock));
// convert from real_clock to mono_clock
return add_event_at(mono_atime, callback);
}
-bool SafeTimer::cancel_event(Context *callback)
+template <class Mutex>
+bool CommonSafeTimer<Mutex>::cancel_event(Context *callback)
{
ceph_assert(ceph_mutex_is_locked(lock));
return true;
}
-void SafeTimer::cancel_all_events()
+template <class Mutex>
+void CommonSafeTimer<Mutex>::cancel_all_events()
{
ldout(cct,10) << "cancel_all_events" << dendl;
ceph_assert(ceph_mutex_is_locked(lock));
}
}
-void SafeTimer::dump(const char *caller) const
+template <class Mutex>
+void CommonSafeTimer<Mutex>::dump(const char *caller) const
{
if (!caller)
caller = "";
++s)
ldout(cct,10) << " " << s->first << "->" << s->second << dendl;
}
+
+template class CommonSafeTimer<ceph::mutex>;
+template class CommonSafeTimer<ceph::fair_mutex>;
#include "include/common_fwd.h"
#include "ceph_time.h"
#include "ceph_mutex.h"
+#include "fair_mutex.h"
+#include <condition_variable>
class Context;
-class SafeTimerThread;
-class SafeTimer
+template <class Mutex> class CommonSafeTimerThread;
+
+template <class Mutex>
+class CommonSafeTimer
{
CephContext *cct;
- ceph::mutex& lock;
- ceph::condition_variable cond;
+ Mutex& lock;
+ std::condition_variable_any cond;
bool safe_callbacks;
- friend class SafeTimerThread;
- SafeTimerThread *thread;
+ friend class CommonSafeTimerThread<Mutex>;
+ class CommonSafeTimerThread<Mutex> *thread;
void timer_thread();
void _shutdown();
public:
// This class isn't supposed to be copied
- SafeTimer(const SafeTimer&) = delete;
- SafeTimer& operator=(const SafeTimer&) = delete;
+ CommonSafeTimer(const CommonSafeTimer&) = delete;
+ CommonSafeTimer& operator=(const CommonSafeTimer&) = delete;
/* Safe callbacks determines whether callbacks are called with the lock
* held.
* If you are able to relax requirements on cancelled callbacks, then
* setting safe_callbacks = false eliminates the lock cycle issue.
* */
- SafeTimer(CephContext *cct, ceph::mutex &l, bool safe_callbacks=true);
- virtual ~SafeTimer();
+ CommonSafeTimer(CephContext *cct, Mutex &l, bool safe_callbacks=true);
+ virtual ~CommonSafeTimer();
/* Call with the event_lock UNLOCKED.
*
};
+extern template class CommonSafeTimer<ceph::mutex>;
+extern template class CommonSafeTimer<ceph::fair_mutex>;
+using SafeTimer = class CommonSafeTimer<ceph::mutex>;
+
#endif
#include "include/rados/librados.hpp"
#include "common/AsyncOpTracker.h"
#include "common/Cond.h"
+#include "common/Timer.h"
#include "common/ceph_mutex.h"
#include "common/RefCountedObj.h"
#include "common/WorkQueue.h"
#include <string>
#include "include/ceph_assert.h"
-class SafeTimer;
-
namespace journal {
class JournalMetadata : public RefCountedObject, boost::noncopyable {
#include "include/Context.h"
#include "include/rados/librados.hpp"
#include "common/AsyncOpTracker.h"
+#include "common/Timer.h"
#include "journal/JournalMetadata.h"
#include "journal/ObjectPlayer.h"
#include "journal/Types.h"
#include <boost/optional.hpp>
#include <map>
-class SafeTimer;
-
namespace journal {
class CacheManagerHandler;
#include "include/rados/librados.hpp"
#include "common/ceph_mutex.h"
#include "common/containers.h"
+#include "common/Timer.h"
#include "journal/Future.h"
#include "journal/FutureImpl.h"
#include "journal/JournalMetadata.h"
#include <map>
#include <string>
-class SafeTimer;
-
namespace journal {
class JournalRecorder {
#include "journal/Future.h"
#include "journal/JournalMetadataListener.h"
#include "cls/journal/cls_journal_types.h"
+#include "common/Timer.h"
#include <list>
#include <map>
#include <string>
#include "include/ceph_assert.h"
class ContextWQ;
-class SafeTimer;
class ThreadPool;
namespace journal {
#include "include/interval_set.h"
#include "include/rados/librados.hpp"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "common/RefCountedObj.h"
#include "journal/Entry.h"
#include <list>
#include <boost/unordered_map.hpp>
#include "include/ceph_assert.h"
-class SafeTimer;
-
namespace journal {
class ObjectPlayer : public RefCountedObject {
#include "common/ceph_mutex.h"
#include "common/RefCountedObj.h"
#include "common/WorkQueue.h"
+#include "common/Timer.h"
#include "journal/FutureImpl.h"
#include <list>
#include <map>
#include <boost/noncopyable.hpp>
#include "include/ceph_assert.h"
-class SafeTimer;
-
namespace journal {
class ObjectRecorder;
namespace {
-class SafeTimerSingleton : public SafeTimer {
+class SafeTimerSingleton : public CommonSafeTimer<ceph::mutex> {
public:
ceph::mutex lock = ceph::make_mutex("librbd::SafeTimerSingleton::lock");
#include <string>
#include <vector>
+#include "common/Timer.h"
#include "common/ceph_mutex.h"
#include "common/config_proxy.h"
#include "common/event_socket.h"
#include <boost/lockfree/policies.hpp>
#include <boost/lockfree/queue.hpp>
-class SafeTimer;
-
namespace neorados {
class IOContext;
class RADOS;
#include "include/rados/librados_fwd.hpp"
#include "common/AsyncOpTracker.h"
#include "common/Cond.h"
+#include "common/Timer.h"
#include "common/RefCountedObj.h"
#include "journal/Future.h"
#include "journal/JournalMetadataListener.h"
#include <unordered_map>
class ContextWQ;
-class SafeTimer;
namespace journal { class Journaler; }
namespace librbd {
#ifndef CEPH_LIBRBD_CACHE_PARENT_WRITE_LOG
#define CEPH_LIBRBD_CACHE_PARENT_WRITE_LOG
+#include "common/Timer.h"
#include "common/RWLock.h"
#include "common/WorkQueue.h"
#include "common/AsyncOpTracker.h"
#include <list>
class Context;
-class SafeTimer;
namespace librbd {
#include <functional>
#include <libpmemobj.h>
#include <list>
+#include "common/Timer.h"
#include "common/RWLock.h"
#include "common/WorkQueue.h"
#include "common/AsyncOpTracker.h"
#include "librbd/cache/pwl/rwl/Builder.h"
class Context;
-class SafeTimer;
namespace librbd {
#include "include/rados/librados.hpp"
#include "librbd/ImageCtx.h"
#include "librbd/image/TypeTraits.h"
+#include "common/Timer.h"
#include <list>
class Context;
-class SafeTimer;
namespace librbd {
#ifndef CEPH_LIBRBD_IO_TYPE_TRAITS_H
#define CEPH_LIBRBD_IO_TYPE_TRAITS_H
-class SafeTimer;
+#include "common/Timer.h"
namespace librbd {
namespace io {
#include "include/rados/librados.hpp"
#include "include/rbd/librbd.hpp"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "librbd/ImageCtx.h"
#include "journal/Journaler.h"
#include "librbd/journal/Types.h"
class Context;
class ContextWQ;
-class SafeTimer;
namespace journal {
class Journaler;
#include "librbd/ImageCtx.h"
#include "journal/Journaler.h"
#include "librbd/journal/TypeTraits.h"
+#include "common/Timer.h"
using librados::IoCtx;
using journal::Journaler;
class Context;
class ContextWQ;
-class SafeTimer;
namespace journal {
class Journaler;
#include "include/rados/librados.hpp"
#include "include/rbd/librbd.hpp"
#include "librbd/journal/TypeTraits.h"
+#include "common/Timer.h"
#include <string>
class Context;
class ContextWQ;
-class SafeTimer;
namespace journal { class Journaler; }
#include "include/buffer.h"
#include "include/rbd/librbd.hpp"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "librbd/internal.h"
#include <string>
#include <set>
-class SafeTimer;
struct Context;
namespace librbd {
#ifndef CEPH_LIBRBD_PLUGIN_API_H
#define CEPH_LIBRBD_PLUGIN_API_H
+#include "common/Timer.h"
#include "common/ceph_mutex.h"
#include "include/common_fwd.h"
#include "include/int_types.h"
namespace ZTracer { struct Trace; }
-class SafeTimer;
-
namespace librbd {
namespace io {
#include "include/Context.h"
#include "common/RefCountedObj.h"
#include "common/ceph_time.h"
+#include "common/Timer.h"
#include "rgw_common.h"
#include "cls/rgw/cls_rgw_types.h"
#include "cls/version/cls_version_types.h"
struct D3nDataCache;
class RGWWatcher;
-class SafeTimer;
class ACLOwner;
class RGWGC;
class RGWMetaNotifier;
const std::string SERVICE_DAEMON_MIRROR_ENABLE_FAILED_KEY("mirroring_failed");
-class SafeTimerSingleton : public SafeTimer {
+class SafeTimerSingleton : public CommonSafeTimer<ceph::mutex> {
public:
ceph::mutex timer_lock = ceph::make_mutex("cephfs::mirror::timer_lock");
#define CEPHFS_MIRROR_SERVICE_DAEMON_H
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "mds/FSMap.h"
#include "Types.h"
-class SafeTimer;
-
namespace cephfs {
namespace mirror {
namespace {
-class SafeTimerSingleton : public SafeTimer {
+class SafeTimerSingleton : public CommonSafeTimer<ceph::mutex> {
public:
ceph::mutex lock = ceph::make_mutex
("ceph::immutable_object_cache::SafeTimerSingleton::lock");
explicit SafeTimerSingleton(CephContext *cct)
- : SafeTimer(cct, lock, true) {
+ : CommonSafeTimer(cct, lock, true) {
init();
}
~SafeTimerSingleton() {
#include "common/ceph_context.h"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "common/Throttle.h"
#include "common/Cond.h"
#include "include/rados/librados.hpp"
#include "include/utime.h"
#include "common/AsyncOpTracker.h"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "tools/rbd_mirror/Types.h"
#include "tools/rbd_mirror/image_deleter/Types.h"
#include <atomic>
class AdminSocketHook;
class Context;
-class SafeTimer;
namespace librbd {
struct ImageCtx;
namespace asio { struct ContextWQ; }
#include "include/common_fwd.h"
#include "include/rados/librados_fwd.hpp"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include <memory>
-class SafeTimer;
class ThreadPool;
namespace librbd {
#include "include/int_types.h"
#include "include/rados/librados.hpp"
#include "common/ceph_mutex.h"
+#include "common/Timer.h"
#include "cls/rbd/cls_rbd_types.h"
#include "librbd/mirror/Types.h"
#include "tools/rbd_mirror/CancelableRequest.h"
#include <string>
class Context;
-class SafeTimer;
namespace journal { class CacheManagerHandler; }
namespace librbd { class ImageCtx; }