【Bug】TextureCache::addImageAsync V3.4

addImageAsync异步加载
未响应回调前调用unbindImageAsync撤销消息回调
void TextureCache::unbindImageAsync(const std::string& filename)
{
_imageInfoMutex.lock();
if (_imageInfoQueue && !_imageInfoQueue->empty())
{
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filename);
auto found = std::find_if(_imageInfoQueue->begin(), _imageInfoQueue->end(), &fullpath](ImageInfo* ptr)->bool{ return ptr->asyncStruct->filename == fullpath; });
if (found != _imageInfoQueue->end())
{
(*found)->asyncStruct->callback = nullptr;
}
}
_imageInfoMutex.unlock();
}

但是在极端情况下,调用 addImageAsync后马上调用unbindImageAsync
此时loadImage线程还未将ImageInfo加入_imageInfoQueue
而是在unbindImageAsync之后添加,导致消息回调解绑失败,无法调用(*found)->asyncStruct->callback = nullptr;
从而在异步加载完成后调用callback时候出现问题

void TextureCache::loadImage()
{
// generate image info
ImageInfo *imageInfo = new (std::nothrow) ImageInfo();
imageInfo->asyncStruct = asyncStruct;
imageInfo->image = image;

    // put the image info into the queue
    _imageInfoMutex.lock();
    _imageInfoQueue->push_back(imageInfo);
    _imageInfoMutex.unlock();

}

Bug 补充

loadImage()线程
同时操作两个链表
_asyncStructQueue
_imageInfoQueue

请求从_asyncStructQueue弹出后生成ImageInfo添加到_imageInfoQueue

void TextureCache::loadImage()
{
_asyncStructQueueMutex.lock();
_asyncStructQueue
_asyncStructQueueMutex.unlock();

…临界点,执行unbindImageAsync

_imageInfoMutex.lock();
_imageInfoQueue
_imageInfoMutex.unlock();
}

此处的Bug是两个链表是分别加锁的
请求从_asyncStructQueue弹出后,未即时插入_imageInfoQueue
在临界点又调用了unbindImageAsync撤销异步加载响应
跟昨天提到的Bug类似,同样会导致撤销失败
在回调时引起异常:8:

随便说一下,昨天提到底Bug都没人理吗?