Add base::concurrent_queue: a really simple concurrent queue

- Add base::scoped_unlock
This commit is contained in:
David Capello 2014-04-17 01:25:09 -03:00
parent a8d39e588a
commit 2b7bd3e831
2 changed files with 77 additions and 13 deletions

View File

@ -0,0 +1,55 @@
// Aseprite Base Library
// Copyright (c) 2001-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef BASE_CONCURRENT_QUEUE_H_INCLUDED
#define BASE_CONCURRENT_QUEUE_H_INCLUDED
#pragma once
#include "base/disable_copying.h"
#include "base/mutex.h"
#include "base/scoped_lock.h"
#include <queue>
namespace base {
template<typename T>
class concurrent_queue {
public:
concurrent_queue() {
}
~concurrent_queue() {
}
void push(const T& value) {
scoped_lock hold(m_mutex);
m_queue.push(value);
}
bool try_pop(T& value) {
if (!m_mutex.try_lock())
return false;
scoped_unlock unlock(m_mutex);
if (m_queue.empty())
return false;
value = m_queue.front();
m_queue.pop();
return true;
}
private:
std::queue<T> m_queue;
mutex m_mutex;
DISABLE_COPYING(concurrent_queue);
};
} // namespace base
#endif

View File

@ -1,5 +1,5 @@
// Aseprite Base Library
// Copyright (c) 2001-2013 David Capello
// Copyright (c) 2001-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -12,20 +12,12 @@
namespace base {
// An object to safely lock and unlock mutexes.
//
// The constructor of scoped_lock locks the mutex, and the destructor
// unlocks the mutex. In this way you can safely use scoped_lock inside
// a try/catch block without worrying about the lock state of the
// mutex if some exception is thrown.
class scoped_lock {
class scoped_unlock {
public:
scoped_lock(mutex& m) : m_mutex(m) {
m_mutex.lock();
scoped_unlock(mutex& m) : m_mutex(m) {
}
~scoped_lock() {
~scoped_unlock() {
m_mutex.unlock();
}
@ -36,10 +28,27 @@ namespace base {
private:
mutex& m_mutex;
// Undefined constructors.
scoped_unlock();
DISABLE_COPYING(scoped_unlock);
};
// An object to safely lock and unlock mutexes.
//
// The constructor of scoped_lock locks the mutex, and the destructor
// unlocks the mutex. In this way you can safely use scoped_lock inside
// a try/catch block without worrying about the lock state of the
// mutex if some exception is thrown.
class scoped_lock : public scoped_unlock {
public:
scoped_lock(mutex& m) : scoped_unlock(m) {
get_mutex().lock();
}
private:
// Undefined constructors.
scoped_lock();
DISABLE_COPYING(scoped_lock);
};
} // namespace base