diff options
| author | 2015-01-07 16:55:44 -0200 | |
|---|---|---|
| committer | 2015-01-07 17:32:31 -0200 | |
| commit | a6ad68190fb02af9c89dc461f451bb75c8a10a94 (patch) | |
| tree | a1fd04b7356286f49d1624d81be53af5b9609145 /src | |
| parent | Merge pull request #438 from lioncash/swp (diff) | |
| download | yuzu-a6ad68190fb02af9c89dc461f451bb75c8a10a94.tar.gz yuzu-a6ad68190fb02af9c89dc461f451bb75c8a10a94.tar.xz yuzu-a6ad68190fb02af9c89dc461f451bb75c8a10a94.zip | |
Fix double-free in Service manager during shutdown
Fixes #423.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/service.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 15 |
2 files changed, 4 insertions, 25 deletions
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index c5233e687..0c5597283 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -46,36 +46,22 @@ Manager* g_manager = nullptr; ///< Service manager | |||
| 46 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 46 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 47 | // Service Manager class | 47 | // Service Manager class |
| 48 | 48 | ||
| 49 | Manager::Manager() { | ||
| 50 | } | ||
| 51 | |||
| 52 | Manager::~Manager() { | ||
| 53 | for(Interface* service : m_services) { | ||
| 54 | DeleteService(service->GetPortName()); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | /// Add a service to the manager (does not create it though) | ||
| 59 | void Manager::AddService(Interface* service) { | 49 | void Manager::AddService(Interface* service) { |
| 60 | // TOOD(yuriks): Fix error reporting | 50 | // TOOD(yuriks): Fix error reporting |
| 61 | m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); | 51 | m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); |
| 62 | m_services.push_back(service); | 52 | m_services.push_back(service); |
| 63 | } | 53 | } |
| 64 | 54 | ||
| 65 | /// Removes a service from the manager, also frees memory | ||
| 66 | void Manager::DeleteService(const std::string& port_name) { | 55 | void Manager::DeleteService(const std::string& port_name) { |
| 67 | Interface* service = FetchFromPortName(port_name); | 56 | Interface* service = FetchFromPortName(port_name); |
| 68 | m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); | 57 | m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); |
| 69 | m_port_map.erase(port_name); | 58 | m_port_map.erase(port_name); |
| 70 | delete service; | ||
| 71 | } | 59 | } |
| 72 | 60 | ||
| 73 | /// Get a Service Interface from its Handle | ||
| 74 | Interface* Manager::FetchFromHandle(Handle handle) { | 61 | Interface* Manager::FetchFromHandle(Handle handle) { |
| 75 | return Kernel::g_handle_table.Get<Interface>(handle); | 62 | return Kernel::g_handle_table.Get<Interface>(handle); |
| 76 | } | 63 | } |
| 77 | 64 | ||
| 78 | /// Get a Service Interface from its port | ||
| 79 | Interface* Manager::FetchFromPortName(const std::string& port_name) { | 65 | Interface* Manager::FetchFromPortName(const std::string& port_name) { |
| 80 | auto itr = m_port_map.find(port_name); | 66 | auto itr = m_port_map.find(port_name); |
| 81 | if (itr == m_port_map.end()) { | 67 | if (itr == m_port_map.end()) { |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 28b4ccd17..41ba1e554 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -114,29 +114,22 @@ private: | |||
| 114 | 114 | ||
| 115 | /// Simple class to manage accessing services from ports and UID handles | 115 | /// Simple class to manage accessing services from ports and UID handles |
| 116 | class Manager { | 116 | class Manager { |
| 117 | |||
| 118 | public: | 117 | public: |
| 119 | Manager(); | 118 | /// Add a service to the manager |
| 120 | |||
| 121 | ~Manager(); | ||
| 122 | |||
| 123 | /// Add a service to the manager (does not create it though) | ||
| 124 | void AddService(Interface* service); | 119 | void AddService(Interface* service); |
| 125 | 120 | ||
| 126 | /// Removes a service from the manager (does not delete it though) | 121 | /// Removes a service from the manager |
| 127 | void DeleteService(const std::string& port_name); | 122 | void DeleteService(const std::string& port_name); |
| 128 | 123 | ||
| 129 | /// Get a Service Interface from its UID | 124 | /// Get a Service Interface from its Handle |
| 130 | Interface* FetchFromHandle(u32 uid); | 125 | Interface* FetchFromHandle(Handle handle); |
| 131 | 126 | ||
| 132 | /// Get a Service Interface from its port | 127 | /// Get a Service Interface from its port |
| 133 | Interface* FetchFromPortName(const std::string& port_name); | 128 | Interface* FetchFromPortName(const std::string& port_name); |
| 134 | 129 | ||
| 135 | private: | 130 | private: |
| 136 | |||
| 137 | std::vector<Interface*> m_services; | 131 | std::vector<Interface*> m_services; |
| 138 | std::map<std::string, u32> m_port_map; | 132 | std::map<std::string, u32> m_port_map; |
| 139 | |||
| 140 | }; | 133 | }; |
| 141 | 134 | ||
| 142 | /// Initialize ServiceManager | 135 | /// Initialize ServiceManager |