From 2380ebca01bdff36c2d12b0a23bef84e07920cb3 Mon Sep 17 00:00:00 2001 From: Pixel Date: Thu, 8 Mar 2012 07:25:27 -0800 Subject: Adding the ScopeLock class to simplify a bit some pieces of code. --- includes/Threads.h | 42 +++++++++++++++++++++++++++++++++--------- src/HttpServer.cc | 10 +++------- src/Printer.cc | 3 +-- src/TaskMan.cc | 9 +++------ 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/includes/Threads.h b/includes/Threads.h index 67143ca..c5146a5 100644 --- a/includes/Threads.h +++ b/includes/Threads.h @@ -15,11 +15,21 @@ class Lock { void enter() { pthread_mutex_lock(&m_lock); } void leave() { pthread_mutex_unlock(&m_lock); } private: + Lock(const Lock &); pthread_mutex_t m_lock; template friend class Queue; }; +class ScopeLock { + public: + ScopeLock(Lock & lock) : m_lock(lock) { m_lock.enter(); } + ~ScopeLock() { m_lock.leave(); } + private: + ScopeLock(const ScopeLock &); + Lock & m_lock; +}; + class RWLock { public: RWLock(); @@ -28,9 +38,28 @@ class RWLock { void enterW() { pthread_rwlock_wrlock(&m_lock); } void leave() { pthread_rwlock_unlock(&m_lock); } private: + RWLock(const RWLock &); pthread_rwlock_t m_lock; }; +class ScopeLockR { + public: + ScopeLockR(Lock & lock) : m_lock(lock) { m_lock.enterR(); } + ~ScopeLockR() { m_lock.leave(); } + private: + ScopeLockR(const ScopeLockR &); + RWLock & m_lock; +}; + +class ScopeLockW { + public: + ScopeLockW(Lock & lock) : m_lock(lock) { m_lock.enterW(); } + ~ScopeLockW() { m_lock.leave(); } + private: + ScopeLockW(const ScopeLockW &); + RWLock & m_lock; +}; + class ThreadHelper; class Thread { @@ -63,7 +92,7 @@ class Queue { Queue() : m_front(NULL), m_back(NULL) { pthread_cond_init(&m_cond, NULL); } ~Queue() { while (!isEmpty()) pop(); pthread_cond_destroy(&m_cond); } void push(T * t) { - m_lock.enter(); + ScopeLock sl(m_lock); Cell * c = new Cell(t); c->m_prev = m_back; if (m_back) @@ -72,10 +101,9 @@ class Queue { m_front = c; m_back = c; pthread_cond_signal(&m_cond); - m_lock.leave(); } T * pop() { - m_lock.enter(); + ScopeLock sl(m_lock); while (!m_front) pthread_cond_wait(&m_cond, &m_lock.m_lock); Cell * c = m_front; @@ -86,15 +114,11 @@ class Queue { m_back = NULL; T * t = c->m_elem; delete c; - m_lock.leave(); return t; } bool isEmpty() { - bool r; - m_lock.enter(); - r = !m_front; - m_lock.leave(); - return r; + ScopeLock sl(m_lock); + return !m_front; } private: Lock m_lock; diff --git a/src/HttpServer.cc b/src/HttpServer.cc index c596005..fe421b9 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -607,21 +607,19 @@ void Balau::HttpServer::stop() { } void Balau::HttpServer::registerAction(Action * action) { - m_actionsLock.enterW(); + ScopeLockW slw(m_actionsLock); action->ref(); m_actions.push_front(action); - m_actionsLock.leave(); } void Balau::HttpServer::flushAllActions() { - m_actionsLock.enterW(); + ScopeLockW slw(m_actionsLock); Action * a; while (!m_actions.empty()) { a = m_actions.front(); m_actions.pop_front(); a->unref(); } - m_actionsLock.leave(); } Balau::HttpServer::Action::ActionMatch Balau::HttpServer::Action::matches(const char * uri, const char * host) { @@ -636,7 +634,7 @@ Balau::HttpServer::Action::ActionMatch Balau::HttpServer::Action::matches(const } Balau::HttpServer::ActionFound Balau::HttpServer::findAction(const char * uri, const char * host) { - m_actionsLock.enterR(); + ScopeLockR slr(m_actionsLock); ActionList::iterator i; ActionFound r; @@ -653,8 +651,6 @@ Balau::HttpServer::ActionFound Balau::HttpServer::findAction(const char * uri, c else r.action->ref(); - m_actionsLock.leave(); - return r; } diff --git a/src/Printer.cc b/src/Printer.cc index 026ee1a..ee6029c 100644 --- a/src/Printer.cc +++ b/src/Printer.cc @@ -40,7 +40,7 @@ void Balau::Printer::_log(uint32_t level, const char * fmt, va_list ap) { if (l & level) break; - m_lock.enter(); + ScopeLock sl(m_lock); if (m_detailledLogs) { struct ev_loop * loop = ev_default_loop(0); ev_now_update(loop); @@ -50,7 +50,6 @@ void Balau::Printer::_log(uint32_t level, const char * fmt, va_list ap) { _print(prefixes[i]); _print(fmt, ap); _print("\n"); - m_lock.leave(); } void Balau::Printer::_print(const char * fmt, va_list ap) { diff --git a/src/TaskMan.cc b/src/TaskMan.cc index 843423f..ea7a613 100644 --- a/src/TaskMan.cc +++ b/src/TaskMan.cc @@ -53,13 +53,12 @@ void Balau::TaskScheduler::registerTask(Task * t) { } void Balau::TaskScheduler::registerTaskMan(TaskMan * t) { - m_lock.enter(); + ScopeLock sl(m_lock); m_taskManagers.push(t); - m_lock.leave(); } void Balau::TaskScheduler::unregisterTaskMan(TaskMan * t) { - m_lock.enter(); + ScopeLock sl(m_lock); TaskMan * p = NULL; // yes, this is a potentially dangerous operation. // But unregistering task managers shouldn't happen that often. @@ -70,12 +69,11 @@ void Balau::TaskScheduler::unregisterTaskMan(TaskMan * t) { break; m_taskManagers.push(p); } - m_lock.leave(); } void Balau::TaskScheduler::stopAll(int code) { m_stopping = true; - m_lock.enter(); + ScopeLock sl(m_lock); std::queue altQueue; TaskMan * tm; while (!m_taskManagers.empty()) { @@ -90,7 +88,6 @@ void Balau::TaskScheduler::stopAll(int code) { altQueue.pop(); m_taskManagers.push(tm); } - m_lock.leave(); } void * Balau::TaskScheduler::proc() { -- cgit v1.2.3