]> git.lizzy.rs Git - minetest.git/commitdiff
Fix concurrency in texture source (#13150)
authorx2048 <codeforsmile@gmail.com>
Thu, 19 Jan 2023 20:44:27 +0000 (21:44 +0100)
committerGitHub <noreply@github.com>
Thu, 19 Jan 2023 20:44:27 +0000 (21:44 +0100)
src/client/tile.cpp

index 582219bb8a6ea4f11b3a21c1f78fe3eb7c924331..d36459bb25116ca337da5caeab1c64313a079091 100644 (file)
@@ -405,7 +405,7 @@ class TextureSource : public IWritableTextureSource
        std::mutex m_textureinfo_cache_mutex;
 
        // Queued texture fetches (to be processed by the main thread)
-       RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+       RequestQueue<std::string, u32, std::thread::id, u8> m_get_texture_queue;
 
        // Textures that have been overwritten with other ones
        // but can't be deleted because the ITexture* might still be used
@@ -491,16 +491,16 @@ u32 TextureSource::getTextureId(const std::string &name)
        infostream<<"getTextureId(): Queued: name=\""<<name<<"\""<<std::endl;
 
        // We're gonna ask the result to be put into here
-       static thread_local ResultQueue<std::string, u32, u8, u8> result_queue;
+       static thread_local ResultQueue<std::string, u32, std::thread::id, u8> result_queue;
 
        // Throw a request in
-       m_get_texture_queue.add(name, 0, 0, &result_queue);
+       m_get_texture_queue.add(name, std::this_thread::get_id(), 0, &result_queue);
 
        try {
                while(true) {
-                       // Wait for result for up to 4 seconds (empirical value)
-                       GetResult<std::string, u32, u8, u8>
-                               result = result_queue.pop_front(4000);
+                       // Wait for result for up to 1 seconds (empirical value)
+                       GetResult<std::string, u32, std::thread::id, u8>
+                               result = result_queue.pop_front(1000);
 
                        if (result.key == name) {
                                return result.item;
@@ -726,10 +726,10 @@ void TextureSource::processQueue()
        /*
                Fetch textures
        */
-       //NOTE this is only thread safe for ONE consumer thread!
-       if (!m_get_texture_queue.empty())
+       // NOTE: process outstanding requests from all mesh generation threads
+       while (!m_get_texture_queue.empty())
        {
-               GetRequest<std::string, u32, u8, u8>
+               GetRequest<std::string, u32, std::thread::id, u8>
                                request = m_get_texture_queue.pop();
 
                /*infostream<<"TextureSource::processQueue(): "