I was playing around with my multi-threaded vulkan renderer today and I managed to build a nice tool for managing my shared resources (mesh, texture, pipeline, etc. data).

template <typename T>
class factory_t
{
public:
	std::shared_ptr<T> create (std::string const key_, std::function<std::shared_ptr<T> ()> create_)
	{
		std::unique_lock<std::mutex> mapLock{m_mapGuard};

		auto &data_wk = m_map[key_];
		mapLock.unlock ();

		std::lock_guard<std::mutex> dataLock{std::get<0> (data_wk)};

		std::shared_ptr<T> data = std::get<1> (data_wk).lock ();

		if (!data)
		{
			data = create_ ();

			std::get<1> (data_wk) = data;
		}

		return data;
	}

	std::mutex                                                      m_mapGuard;
	std::map<std::string, std::tuple<std::mutex, std::weak_ptr<T>>> m_map;
};

Just provide a key and make sure your create_ functor is thread-safe and you’ll get per-key factory allocations with thread safety.

If you want to use it, license it under GPL, LGPL, or MIT and maybe say nice things about me to your friends. Happy coding!