namespace librbd {
-template <typename Task>
-class TaskFinisher {
-public:
- TaskFinisher(CephContext &cct)
- : m_cct(cct), m_lock("librbd::TaskFinisher::m_lock"),
- m_finisher(new Finisher(&cct)),
- m_safe_timer(new SafeTimer(&cct, m_lock, false))
- {
- m_finisher->start();
+struct TaskFinisherSingleton {
+ Mutex m_lock;
+ SafeTimer *m_safe_timer;
+ Finisher *m_finisher;
+
+ explicit TaskFinisherSingleton(CephContext *cct)
+ : m_lock("librbd::TaskFinisher::m_lock") {
+ m_safe_timer = new SafeTimer(cct, m_lock, false);
m_safe_timer->init();
+ m_finisher = new Finisher(cct, "librbd::TaskFinisher::m_finisher", "taskfin_librbd");
+ m_finisher->start();
}
-
- ~TaskFinisher() {
+ virtual ~TaskFinisherSingleton() {
{
Mutex::Locker l(m_lock);
m_safe_timer->shutdown();
delete m_safe_timer;
}
-
m_finisher->wait_for_empty();
m_finisher->stop();
delete m_finisher;
}
+};
+
+
+template <typename Task>
+class TaskFinisher {
+public:
+ TaskFinisher(CephContext &cct) : m_cct(cct) {
+ TaskFinisherSingleton *singleton;
+ cct.lookup_or_create_singleton_object<TaskFinisherSingleton>(
+ singleton, "librbd::TaskFinisher::m_safe_timer");
+ m_lock = &singleton->m_lock;
+ m_safe_timer = singleton->m_safe_timer;
+ m_finisher = singleton->m_finisher;
+ }
void cancel(const Task& task) {
- Mutex::Locker l(m_lock);
+ Mutex::Locker l(*m_lock);
typename TaskContexts::iterator it = m_task_contexts.find(task);
if (it != m_task_contexts.end()) {
delete it->second.first;
}
void cancel_all() {
- Mutex::Locker l(m_lock);
+ Mutex::Locker l(*m_lock);
for (typename TaskContexts::iterator it = m_task_contexts.begin();
it != m_task_contexts.end(); ++it) {
delete it->second.first;
}
bool add_event_after(const Task& task, double seconds, Context *ctx) {
- Mutex::Locker l(m_lock);
+ Mutex::Locker l(*m_lock);
if (m_task_contexts.count(task) != 0) {
// task already scheduled on finisher or timer
delete ctx;
}
bool queue(const Task& task, Context *ctx) {
- Mutex::Locker l(m_lock);
+ Mutex::Locker l(*m_lock);
typename TaskContexts::iterator it = m_task_contexts.find(task);
if (it != m_task_contexts.end()) {
if (it->second.second != NULL) {
CephContext &m_cct;
- Mutex m_lock;
+ Mutex *m_lock;
Finisher *m_finisher;
SafeTimer *m_safe_timer;
void complete(const Task& task) {
Context *ctx = NULL;
{
- Mutex::Locker l(m_lock);
+ Mutex::Locker l(*m_lock);
typename TaskContexts::iterator it = m_task_contexts.find(task);
if (it != m_task_contexts.end()) {
ctx = it->second.first;