mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-04 15:40:10 +00:00
Add base::concurrent_queue: a really simple concurrent queue
- Add base::scoped_unlock
This commit is contained in:
parent
a8d39e588a
commit
2b7bd3e831
55
src/base/concurrent_queue.h
Normal file
55
src/base/concurrent_queue.h
Normal 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
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user