Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Asynchronous loading of textures causes Stack Overflow  (Read 4531 times)

0 Members and 1 Guest are viewing this topic.

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Asynchronous loading of textures causes Stack Overflow
« on: January 27, 2016, 10:02:47 pm »
The following code, which is my attempt at recreating the issue, appears to cause a stack overflow with the latest version of master of SFML (Debug or Release) in Visual Studio 2015. It also seems to crash gcc version 5.2.0 (x86_64-posix-seh-rev1, Built by MinGW-W64 project).

Loading with std::launch::deferred (So single-threaded) does not appear to cause any issue, suggesting it's a multithreading-exclusive issue.

#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <future>

int main() {

        sf::RenderWindow window(sf::VideoMode(320, 240), "Possible bug with multithreading");
        std::shared_ptr<sf::Texture> texture = std::async(std::launch::async, []() -> std::shared_ptr<sf::Texture> {
                std::shared_ptr<sf::Texture> result = std::make_shared<sf::Texture>();
                if (!result->loadFromFile("simple.png")) { // <-- this line causes a crash
                        return nullptr;
                }
                return result;
        }).get();

        if (!texture) {
                return -1;
        }

        sf::Sprite sprite;
        sprite.setTexture(*texture);
        sprite.setPosition(sf::Vector2f(0.0, 0.0));

        while (true) {
                window.draw(sprite);
                window.display();

                sf::Event event;
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed) {
                                return 0;
                        }
                }
        }
}
 

Battling the visual studio debugger would make it look like the code is repeatedly jumping in SFML between four functions:
    sfml-window-d-2.dll!`anonymous namespace'::getInternalContext() Line 155   C++
    sfml-window-d-2.dll!sf::priv::GlContext::ensureContext() Line 213   C++
    sfml-window-d-2.dll!sf::GlResource::GlResource() Line 61   C++
    sfml-window-d-2.dll!sf::Context::Context() Line 61   C++
And this endless recursive loop leads to stack overflow. gdb gives similar output when running 'where' after the segmentatiom fault.

It seems the newing up of a ThreadLocal sf::Context is triggering a call to getInternalContext, which then sees there is no internal context, so it then news up an sf::Context, which calls getInternalContext, which then goes on ad infinitum.

Is multithreaded texture creation currently broken? It's something I can imagine not being too rare a use-case, wanting to load assets in a separate thread from the main.
« Last Edit: January 28, 2016, 07:53:47 am by Laurent »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.


MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: Asynchronous loading of textures causes Stack Overflow
« Reply #2 on: January 27, 2016, 10:39:06 pm »
And somehow I missed all of those when searching *facepalms self* Now I feel stupid, sorry :)

Thanks for the speedy reply :) This is what happens when I come back to C++ and SFML after a long absence, I miss alllll of the stuff.

For the record, the reason I was attempting this is an experiment in multithreaded coding where the update tick is entirely asynchronous and event based. Loading assets in update before sending them where they needed to go seemed cleaner code-design wise with that pattern.
« Last Edit: January 27, 2016, 11:00:33 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.