mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 18:53:28 +01:00
7b6482c01d
* Remove custom event queue's IPC management of favour of universal LV2 approach. * Move ipc_manager to FXO. * Fix ipc_manager internal storage memory leak: deallocate entry when IPC object destroyed. * Rewrite lv2_obj::create to be simpler (remove many duplicated code). * Always execute lv2_obj::create under both IPC and IDM mutexes at once (not in non-atomic single-steps). Fixing potential case where concurrency can cause IDM to contain 2 or more different objects with the same IPC key with SYS_SYNC_NOT_CARE (instead of the same object). * Do not rely on smart ptr reference count to tell if the object exists. Use similar approach as event queues as it makes error checkings accurate. * Optimize lv2_event_port by using std::shared_ptr for queue which wasn't allowed before.
71 lines
1.5 KiB
C++
71 lines
1.5 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
|
|
#include "Utilities/mutex.h"
|
|
|
|
// IPC manager for objects of type T and IPC keys of type K.
|
|
template <typename T, typename K>
|
|
class ipc_manager final
|
|
{
|
|
std::unordered_map<K, std::shared_ptr<T>> m_map;
|
|
|
|
mutable shared_mutex m_mutex;
|
|
|
|
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
|
|
template <typename F>
|
|
std::pair<bool, std::shared_ptr<T>> add(const K& ipc_key, F&& provider, bool peek_ptr = true)
|
|
{
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
// Get object location
|
|
std::shared_ptr<T>& ptr = m_map[ipc_key];
|
|
const bool existed = ptr.operator bool();
|
|
|
|
if (!existed)
|
|
{
|
|
// Call a function which must return the object
|
|
ptr = provider();
|
|
}
|
|
|
|
const bool added = !existed && ptr;
|
|
return {added, (peek_ptr || added) ? ptr : nullptr};
|
|
}
|
|
|
|
// Unregister specified ipc_key, may return true even if the object doesn't exist anymore
|
|
bool remove(const K& ipc_key)
|
|
{
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
return m_map.erase(ipc_key) != 0;
|
|
}
|
|
|
|
// Get object with specified ipc_key
|
|
std::shared_ptr<T> get(const K& ipc_key) const
|
|
{
|
|
reader_lock lock(m_mutex);
|
|
|
|
const auto found = m_map.find(ipc_key);
|
|
|
|
if (found != m_map.end())
|
|
{
|
|
return found->second;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// Check whether the object actually exists
|
|
bool check(const K& ipc_key) const
|
|
{
|
|
reader_lock lock(m_mutex);
|
|
|
|
const auto found = m_map.find(ipc_key);
|
|
|
|
return found != m_map.end();
|
|
}
|
|
};
|