diff options
| -rw-r--r-- | src/core/hle/service/nvdrv/core/container.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/core/container.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/core/nvmap.cpp | 8 |
3 files changed, 13 insertions, 3 deletions
diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp index e89cca6f2..9edce03f6 100644 --- a/src/core/hle/service/nvdrv/core/container.cpp +++ b/src/core/hle/service/nvdrv/core/container.cpp | |||
| @@ -49,6 +49,7 @@ SessionId Container::OpenSession(Kernel::KProcess* process) { | |||
| 49 | continue; | 49 | continue; |
| 50 | } | 50 | } |
| 51 | if (session.process == process) { | 51 | if (session.process == process) { |
| 52 | session.ref_count++; | ||
| 52 | return session.id; | 53 | return session.id; |
| 53 | } | 54 | } |
| 54 | } | 55 | } |
| @@ -66,6 +67,7 @@ SessionId Container::OpenSession(Kernel::KProcess* process) { | |||
| 66 | } | 67 | } |
| 67 | auto& session = impl->sessions[new_id]; | 68 | auto& session = impl->sessions[new_id]; |
| 68 | session.is_active = true; | 69 | session.is_active = true; |
| 70 | session.ref_count = 1; | ||
| 69 | // Optimization | 71 | // Optimization |
| 70 | if (process->IsApplication()) { | 72 | if (process->IsApplication()) { |
| 71 | auto& page_table = process->GetPageTable().GetBasePageTable(); | 73 | auto& page_table = process->GetPageTable().GetBasePageTable(); |
| @@ -114,8 +116,11 @@ SessionId Container::OpenSession(Kernel::KProcess* process) { | |||
| 114 | 116 | ||
| 115 | void Container::CloseSession(SessionId session_id) { | 117 | void Container::CloseSession(SessionId session_id) { |
| 116 | std::scoped_lock lk(impl->session_guard); | 118 | std::scoped_lock lk(impl->session_guard); |
| 117 | impl->file.UnmapAllHandles(session_id); | ||
| 118 | auto& session = impl->sessions[session_id.id]; | 119 | auto& session = impl->sessions[session_id.id]; |
| 120 | if (--session.ref_count > 0) { | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | impl->file.UnmapAllHandles(session_id); | ||
| 119 | auto& smmu = impl->host1x.MemoryManager(); | 124 | auto& smmu = impl->host1x.MemoryManager(); |
| 120 | if (session.has_preallocated_area) { | 125 | if (session.has_preallocated_area) { |
| 121 | const DAddr region_start = session.mapper->GetRegionStart(); | 126 | const DAddr region_start = session.mapper->GetRegionStart(); |
diff --git a/src/core/hle/service/nvdrv/core/container.h b/src/core/hle/service/nvdrv/core/container.h index b4d3938a8..f159ced09 100644 --- a/src/core/hle/service/nvdrv/core/container.h +++ b/src/core/hle/service/nvdrv/core/container.h | |||
| @@ -46,6 +46,7 @@ struct Session { | |||
| 46 | bool has_preallocated_area{}; | 46 | bool has_preallocated_area{}; |
| 47 | std::unique_ptr<HeapMapper> mapper{}; | 47 | std::unique_ptr<HeapMapper> mapper{}; |
| 48 | bool is_active{}; | 48 | bool is_active{}; |
| 49 | s32 ref_count{}; | ||
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 51 | class Container { | 52 | class Container { |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index bc1c033c6..453cb5831 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp | |||
| @@ -333,9 +333,13 @@ void NvMap::UnmapAllHandles(NvCore::SessionId session_id) { | |||
| 333 | }(); | 333 | }(); |
| 334 | 334 | ||
| 335 | for (auto& [id, handle] : handles_copy) { | 335 | for (auto& [id, handle] : handles_copy) { |
| 336 | if (handle->session_id.id == session_id.id) { | 336 | { |
| 337 | FreeHandle(id, false); | 337 | std::scoped_lock lk{handle->mutex}; |
| 338 | if (handle->session_id.id != session_id.id || handle->dupes <= 0) { | ||
| 339 | continue; | ||
| 340 | } | ||
| 338 | } | 341 | } |
| 342 | FreeHandle(id, false); | ||
| 339 | } | 343 | } |
| 340 | } | 344 | } |
| 341 | 345 | ||