fork(2) download
  1. #include <functional>
  2. #include <vector>
  3. #include <memory>
  4. #include <mutex>
  5.  
  6. #include <iostream>
  7. using std::cout;
  8. using std::endl;
  9.  
  10. template<typename T>
  11. class ResourceManager{
  12. public:
  13. using Actions = struct{
  14. using LoadFunc = std::function<T*(const std::string &)>;
  15. using UnloadFunc = std::function<void(T *)>;
  16. LoadFunc load;
  17. UnloadFunc unload;
  18. };
  19. using ResourcePtr = std::unique_ptr<T, typename Actions::UnloadFunc>;
  20. struct MutexWrapper{
  21. std::mutex m;
  22. MutexWrapper() {}
  23. MutexWrapper(MutexWrapper const&) {}
  24. MutexWrapper& operator=(MutexWrapper const&) { return *this; }
  25. inline std::mutex &get(){ return m; }
  26. };
  27. using Key = size_t;
  28. public:
  29. ResourceManager(Actions actions):
  30. _actions(actions){}
  31. ResourceManager(const ResourceManager &rhs) = delete;
  32. public:
  33. Key load(const std::string &path){
  34. auto resource = _actions.load(path);
  35. return load(resource);
  36. }
  37.  
  38. Key load(T *resource){
  39. std::lock_guard<std::mutex> guard(_mutex);
  40. auto resourcePtr = ResourcePtr(resource, _actions.unload);
  41. _resources.push_back(std::move(resourcePtr));
  42. _mutexes.push_back(MutexWrapper());
  43. return _resources.size()-1;
  44. }
  45.  
  46. void unload(Key key){
  47. std::lock_guard<std::mutex> guard(_mutex);
  48. _resources.erase(_resources.begin()+key);
  49. _mutexes.erase(_mutexes.begin()+key);
  50. }
  51.  
  52. void operate(Key key, std::function<void(T&)> operation){
  53. std::lock_guard<std::mutex> guard(_mutexes.at(key).get());
  54. operation(*_resources.at(key));
  55. }
  56.  
  57. void operate(Key key, std::function<void(const T&)> operation) const{
  58. std::lock_guard<std::mutex> guard(_mutexes.at(key).get());
  59. operation(*_resources.at(key));
  60. }
  61. private:
  62. Actions _actions;
  63. std::vector<ResourcePtr> _resources;
  64. std::vector<MutexWrapper> _mutexes;
  65. std::mutex _mutex;
  66. };
  67.  
  68. int main() {
  69. ResourceManager<int> rm{{
  70. [](const std::string &){return new int;},
  71. [](int *arg){ delete arg; }
  72. }};
  73.  
  74. auto id = rm.load(new int(5));
  75. rm.operate(id, [](int&arg){ cout << "Hello world! " << arg << endl; });
  76. return 0;
  77. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
Hello world! 5