diff options
author | Porteries Tristan <republicthunderbolt9@gmail.com> | 2015-10-25 21:22:29 +0300 |
---|---|---|
committer | Porteries Tristan <republicthunderbolt9@gmail.com> | 2015-10-25 21:22:29 +0300 |
commit | 06d2ad018564ff0538dad042ebe5670788979171 (patch) | |
tree | 9cf328e4e7d5b8210aeb813e0ea8c86d8071cc49 /source/gameengine/Converter | |
parent | 0d59acccd33402295e2a18b4051a8192de555a36 (diff) |
BGE: Fix issues with async libload.
This patch fixes:
- the call of LibFree on a unfinished loaded library;
- memory leak created on end of game : the async libraries are loaded but not converted, so not freed with the master scene.
Reviewers: campbellbarton, sybren, youle, hg1, moguri, lordloki
Reviewed By: moguri, lordloki
Differential Revision: https://developer.blender.org/D1571
Diffstat (limited to 'source/gameengine/Converter')
4 files changed, 45 insertions, 10 deletions
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 02c00b2835b..95d8fe1f294 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -138,14 +138,6 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() // clears meshes, and hashmaps from blender to gameengine data // delete sumoshapes - if (m_threadinfo) { - BLI_task_pool_work_and_wait(m_threadinfo->m_pool); - BLI_task_pool_free(m_threadinfo->m_pool); - - BLI_mutex_end(&m_threadinfo->m_mutex); - delete m_threadinfo; - } - int numAdtLists = m_map_blender_to_gameAdtList.size(); for (int i = 0; i < numAdtLists; i++) { BL_InterpolatorList *adtList = *m_map_blender_to_gameAdtList.at(i); @@ -188,6 +180,15 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() } m_DynamicMaggie.clear(); + + if (m_threadinfo) { + /* Thread infos like mutex must be freed after FreeBlendFile function. + Because it needs to lock the mutex, even if there's no active task when it's + in the scene converter destructor. */ + BLI_task_pool_free(m_threadinfo->m_pool); + BLI_mutex_end(&m_threadinfo->m_mutex); + delete m_threadinfo; + } } void KX_BlenderSceneConverter::SetNewFileName(const STR_String &filename) @@ -806,6 +807,16 @@ void KX_BlenderSceneConverter::MergeAsyncLoads() BLI_mutex_unlock(&m_threadinfo->m_mutex); } +void KX_BlenderSceneConverter::FinalizeAsyncLoads() +{ + // Finish all loading libraries. + if (m_threadinfo) { + BLI_task_pool_work_and_wait(m_threadinfo->m_pool); + } + // Merge all libraries data in the current scene, to avoid memory leak of unmerged scenes. + MergeAsyncLoads(); +} + void KX_BlenderSceneConverter::AddScenesToMergeQueue(KX_LibLoadStatus *status) { BLI_mutex_lock(&m_threadinfo->m_mutex); @@ -1017,7 +1028,19 @@ bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie) if (maggie == NULL) return false; - + + // If the given library is currently in loading, we do nothing. + if (m_status_map.count(maggie->name)) { + BLI_mutex_lock(&m_threadinfo->m_mutex); + const bool finished = m_status_map[maggie->name]->IsFinished(); + BLI_mutex_unlock(&m_threadinfo->m_mutex); + + if (!finished) { + printf("Library (%s) is currently being loaded asynchronously, and cannot be freed until this process is done\n", maggie->name); + return false; + } + } + /* tag all false except the one we remove */ for (vector<Main *>::iterator it = m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++) { Main *main = *it; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index a40188d197d..40c71a4d74b 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -184,6 +184,7 @@ public: bool FreeBlendFile(const char *path); virtual void MergeAsyncLoads(); + virtual void FinalizeAsyncLoads(); void AddScenesToMergeQueue(class KX_LibLoadStatus *status); void PrintStats() { diff --git a/source/gameengine/Converter/KX_LibLoadStatus.cpp b/source/gameengine/Converter/KX_LibLoadStatus.cpp index 2a38e062f89..66fcd998269 100644 --- a/source/gameengine/Converter/KX_LibLoadStatus.cpp +++ b/source/gameengine/Converter/KX_LibLoadStatus.cpp @@ -36,7 +36,8 @@ KX_LibLoadStatus::KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter, m_mergescene(merge_scene), m_data(NULL), m_libname(path), - m_progress(0.f) + m_progress(0.0f), + m_finished(false) #ifdef WITH_PYTHON , m_finish_cb(NULL), @@ -48,6 +49,7 @@ KX_LibLoadStatus::KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter, void KX_LibLoadStatus::Finish() { + m_finished = true; m_progress = 1.f; m_endtime = PIL_check_seconds_timer(); @@ -157,6 +159,7 @@ PyAttributeDef KX_LibLoadStatus::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RO("progress", KX_LibLoadStatus, m_progress), KX_PYATTRIBUTE_STRING_RO("libraryName", KX_LibLoadStatus, m_libname), KX_PYATTRIBUTE_RO_FUNCTION("timeTaken", KX_LibLoadStatus, pyattr_get_timetaken), + KX_PYATTRIBUTE_BOOL_RO("finished", KX_LibLoadStatus, m_finished), { NULL } //Sentinel }; diff --git a/source/gameengine/Converter/KX_LibLoadStatus.h b/source/gameengine/Converter/KX_LibLoadStatus.h index bedf4498c96..fd51bfddd85 100644 --- a/source/gameengine/Converter/KX_LibLoadStatus.h +++ b/source/gameengine/Converter/KX_LibLoadStatus.h @@ -43,6 +43,9 @@ private: double m_starttime; double m_endtime; + // The current status of this libload, used by the scene converter. + bool m_finished; + #ifdef WITH_PYTHON PyObject* m_finish_cb; PyObject* m_progress_cb; @@ -68,6 +71,11 @@ public: void SetData(void *data); void *GetData(); + inline bool IsFinished() const + { + return m_finished; + } + void SetProgress(float progress); float GetProgress(); void AddProgress(float progress); |