rpcsx/rpcs3/Emu/IPC.h

71 lines
1.5 KiB
C
Raw Normal View History

2016-05-13 16:01:48 +02:00
#pragma once
#include <memory>
#include <unordered_map>
#include "Utilities/mutex.h"
2016-05-13 16:01:48 +02:00
// IPC manager for objects of type T and IPC keys of type K.
2017-07-24 17:59:48 +02:00
template <typename T, typename K>
2016-05-13 16:01:48 +02:00
class ipc_manager final
{
std::unordered_map<K, std::shared_ptr<T>> m_map;
2016-05-13 16:01:48 +02:00
mutable shared_mutex m_mutex;
2016-05-13 16:01:48 +02:00
public:
// Add new object if specified ipc_key is not used
// .first: added new object?, .second: what's at m_map[key] after this function if (peek_ptr || added new object) is true
2017-07-24 17:59:48 +02:00
template <typename F>
std::pair<bool, std::shared_ptr<T>> add(const K& ipc_key, F&& provider, bool peek_ptr = true)
2016-05-13 16:01:48 +02:00
{
std::lock_guard lock(m_mutex);
2016-05-13 16:01:48 +02:00
// Get object location
std::shared_ptr<T>& ptr = m_map[ipc_key];
const bool existed = ptr.operator bool();
if (!existed)
2016-05-13 16:01:48 +02:00
{
// Call a function which must return the object
ptr = provider();
2016-05-13 16:01:48 +02:00
}
const bool added = !existed && ptr;
return {added, (peek_ptr || added) ? ptr : nullptr};
2016-05-13 16:01:48 +02:00
}
// Unregister specified ipc_key, may return true even if the object doesn't exist anymore
bool remove(const K& ipc_key)
2016-05-13 16:01:48 +02:00
{
std::lock_guard lock(m_mutex);
2016-05-13 16:01:48 +02:00
return m_map.erase(ipc_key) != 0;
2016-05-13 16:01:48 +02:00
}
// Get object with specified ipc_key
std::shared_ptr<T> get(const K& ipc_key) const
2016-05-13 16:01:48 +02:00
{
reader_lock lock(m_mutex);
2016-05-13 16:01:48 +02:00
const auto found = m_map.find(ipc_key);
2016-05-13 16:01:48 +02:00
if (found != m_map.end())
2016-05-13 16:01:48 +02:00
{
return found->second;
2016-05-13 16:01:48 +02:00
}
return nullptr;
}
// Check whether the object actually exists
bool check(const K& ipc_key) const
2016-05-13 16:01:48 +02:00
{
reader_lock lock(m_mutex);
2016-05-13 16:01:48 +02:00
const auto found = m_map.find(ipc_key);
2016-05-13 16:01:48 +02:00
return found != m_map.end();
2016-05-13 16:01:48 +02:00
}
};