From b2d9205796eef23fd5d9a436d438fa2ca31ec21a Mon Sep 17 00:00:00 2001 From: sapier Date: Thu, 14 Nov 2013 18:30:43 +0100 Subject: [PATCH] Fix Result of processed Request was written to invalid (non existent) ResultQueue if requesting thread timed out before --- src/itemdef.cpp | 21 ++++---- src/shader.cpp | 30 ++++++------ src/tile.cpp | 127 ++++++++++++++++++++++++------------------------ 3 files changed, 92 insertions(+), 86 deletions(-) diff --git a/src/itemdef.cpp b/src/itemdef.cpp index c520ea902..d34d68582 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -477,21 +477,24 @@ public: else { // We're gonna ask the result to be put into here - ResultQueue result_queue; + static ResultQueue result_queue; + // Throw a request in m_get_clientcached_queue.add(name, 0, 0, &result_queue); try{ - // Wait result for a second - GetResult + while(true) { + // Wait result for a second + GetResult result = result_queue.pop_front(1000); - // Check that at least something worked OK - assert(result.key == name); - // Return it - return result.item; + + if (result.key == name) { + return result.item; + } + } } catch(ItemNotFoundException &e) { - errorstream<<"Waiting for clientcached timed out."< result_queue; + + static ResultQueue result_queue; // Throw a request in m_get_shader_queue.add(name, 0, 0, &result_queue); - infostream<<"Waiting for shader from main thread, name=\"" - < + while(true) { + // Wait result for a second + GetResult result = result_queue.pop_front(1000); - // Check that at least something worked OK - assert(result.key == name); - - return result.item; + if (result.key == name) { + return result.item; + } + } } catch(ItemNotFoundException &e){ - infostream<<"Waiting for shader timed out."< request = m_get_shader_queue.pop(); - /*infostream<<"ShaderSource::processQueue(): " + /**errorstream<<"ShaderSource::processQueue(): " <<"got shader request with " <<"name=\""<onSetConstants(services, is_highlevel); } } - + ShaderInfo generate_shader(std::string name, IrrlichtDevice *device, video::IShaderConstantSetCallBack *callback, SourceShaderCache *sourcecache) diff --git a/src/tile.cpp b/src/tile.cpp index 5dec79a10..71c7290b7 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -58,7 +58,7 @@ static bool replace_ext(std::string &path, const char *ext) last_dot_i = i; break; } - + if(path[i] == '\\' || path[i] == '/') break; } @@ -97,7 +97,7 @@ std::string getImagePath(std::string path) return path; } while((++ext) != NULL); - + return ""; } @@ -120,7 +120,7 @@ std::string getTexturePath(const std::string &filename) bool incache = g_texturename_to_path_cache.get(filename, &fullpath); if(incache) return fullpath; - + /* Check from texture_path */ @@ -143,10 +143,10 @@ std::string getTexturePath(const std::string &filename) // Check all filename extensions. Returns "" if not found. fullpath = getImagePath(testpath); } - + // Add to cache (also an empty result is cached) g_texturename_to_path_cache.set(filename, fullpath); - + // Finally return it return fullpath; } @@ -302,14 +302,14 @@ public: getTextureId("stone.png^mineral_coal.png^crack0"). */ - + /* Gets a texture id from cache or - if main thread, from getTextureIdDirect - if other thread, adds to request queue and waits for main thread */ u32 getTextureId(const std::string &name); - + /* Example names: "stone.png" @@ -363,21 +363,21 @@ public: // Processes queued texture requests from other threads. // Shall be called from the main thread. void processQueue(); - + // Insert an image into the cache without touching the filesystem. // Shall be called from the main thread. void insertSourceImage(const std::string &name, video::IImage *img); - + // Rebuild images and textures from the current set of source images // Shall be called from the main thread. void rebuildImagesAndTextures(); - + // Render a mesh to a texture. // Returns NULL if render-to-texture failed. // Shall be called from the main thread. video::ITexture* generateTextureFromMesh( const TextureFromMeshParams ¶ms); - + // Generates an image from a full string like // "stone.png^mineral_coal.png^[crack:1:0". // Shall be called from the main thread. @@ -389,12 +389,12 @@ public: bool generateImage(std::string part_of_name, video::IImage *& baseimg); private: - + // The id of the thread that is allowed to use irrlicht directly threadid_t m_main_thread; // The irrlicht device IrrlichtDevice *m_device; - + // Cache of source images // This should be only accessed from the main thread SourceImageCache m_sourcecache; @@ -409,7 +409,7 @@ private: std::map m_name_to_id; // The two former containers are behind this mutex JMutex m_textureinfo_cache_mutex; - + // Queued texture fetches (to be processed by the main thread) RequestQueue m_get_texture_queue; @@ -432,15 +432,15 @@ TextureSource::TextureSource(IrrlichtDevice *device): m_device(device) { assert(m_device); - + m_textureinfo_cache_mutex.Init(); - + m_main_thread = get_current_thread_id(); - + // Add a NULL TextureInfo as the first index, named "" m_textureinfo_cache.push_back(TextureInfo("")); m_name_to_id[""] = 0; - + // Cache some settings // Note: Since this is only done once, the game must be restarted // for these settings to take effect @@ -499,7 +499,7 @@ u32 TextureSource::getTextureId(const std::string &name) return n->second; } } - + /* Get texture */ @@ -512,32 +512,33 @@ u32 TextureSource::getTextureId(const std::string &name) infostream<<"getTextureId(): Queued: name=\""< result_queue; - + static ResultQueue result_queue; + // Throw a request in m_get_texture_queue.add(name, 0, 0, &result_queue); - - infostream<<"Waiting for texture from main thread, name=\"" - < + while(true) { + // Wait result for a second + GetResult result = result_queue.pop_front(1000); - - // Check that at least something worked OK - assert(result.key == name); - return result.item; + if (result.key == name) { + return result.item; + } + } } catch(ItemNotFoundException &e) { - infostream<<"Waiting for texture timed out."<=0; i--) @@ -647,9 +648,9 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) <addTexture(name.c_str(), baseimg); } - + /* Add texture to caches (add NULL textures too) */ JMutexAutoLock lock(m_textureinfo_cache_mutex); - + u32 id = m_textureinfo_cache.size(); TextureInfo ti(name, t, baseimg); m_textureinfo_cache.push_back(ti); @@ -733,7 +734,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) /*infostream<<"getTextureIdDirect(): " <<"Returning id="< dim = image->getDimension(); @@ -1031,7 +1032,7 @@ bool TextureSource::generateImage(std::string part_of_name, video::IImage *& bas /*infostream<<"generateImage(): generating special " <<"modification \""< dim = baseimg->getDimension(); - + // Set alpha to full for(u32 y=0; y dim = baseimg->getDimension(); - + /*video::IImage *oldbaseimg = baseimg; baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); oldbaseimg->copyTo(baseimg); @@ -1292,7 +1293,7 @@ bool TextureSource::generateImage(std::string part_of_name, video::IImage *& bas img_top->drop(); img_left->drop(); img_right->drop(); - + /* Draw a cube mesh into a render target texture */ @@ -1322,9 +1323,9 @@ bool TextureSource::generateImage(std::string part_of_name, video::IImage *& bas params.light_position.set(10, 100, -50); params.light_color.set(1.0, 0.5, 0.5, 0.5); params.light_radius = 1000; - + video::ITexture *rtt = generateTextureFromMesh(params); - + // Drop mesh cube->drop(); @@ -1332,7 +1333,7 @@ bool TextureSource::generateImage(std::string part_of_name, video::IImage *& bas driver->removeTexture(texture_top); driver->removeTexture(texture_left); driver->removeTexture(texture_right); - + if(rtt == NULL) { baseimg = generateImageFromScratch(imagename_top); @@ -1407,7 +1408,7 @@ bool TextureSource::generateImage(std::string part_of_name, video::IImage *& bas <<"\", cancelling."<getDimension(); frame_size.Y /= frame_count; @@ -1566,7 +1567,7 @@ void brighten(video::IImage *image) { if(image == NULL) return; - + core::dimension2d dim = image->getDimension(); for(u32 y=0; y srcdim = src->getDimension(); core::dimension2d dstdim = dst->getDimension();