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

Author Topic: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering  (Read 11624 times)

0 Members and 1 Guest are viewing this topic.

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
[Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« on: February 17, 2013, 10:42:44 pm »
Hello  :)

I was trying the example program provided in the CSFML 1.6 doc and everything went as expected.
But when I tried to use separate threads (one for rendering, another for handling events) the window freezes, and all I get is a black display  :o  the only way to close the program is through the task manager.

Here is my code:
#ifdef __linux__
        #include <unistd.h>
#elif _WIN32
        #include <windows.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// CSFML headers
#include <SFML/Graphics.h>
#include <SFML/Window.h>

// csfml
sfWindowSettings windowSettings = {24, 8, 0};
sfVideoMode videoMode = {800, 600, 32};
sfRenderWindow* mainWindow;
sfImage* image;
sfSprite* sprite;
sfFont* font;
sfString* text;
sfEvent event;


int gui_init ();
void gui_cleanup ();

void rendering_thread_handler (void* arg);
void event_handler_thread_handler (void* arg);

long mx_get_uptime ();
void mx_msleep ();
void mx_sync_loop (long* t1, long fps);



int main(int argc, char* argv[])
{
        if (gui_init() != EXIT_SUCCESS)
                return EXIT_FAILURE;
       
       
        sfThread* rendering_thread = sfThread_Create(rendering_thread_handler, NULL);
        sfThread* event_handling_thread = sfThread_Create(event_handler_thread_handler, NULL);
       
        sfThread_Launch(rendering_thread);
        sfThread_Launch(event_handling_thread);
       
        sfThread_Wait(event_handling_thread);
        sfThread_Wait(rendering_thread);
       
       
        gui_cleanup();

        return EXIT_SUCCESS;

}

int gui_init ()
{
        /* Create the main window */
        mainWindow = sfRenderWindow_Create(videoMode, "SFML window", sfResize | sfClose, windowSettings);
        if (!mainWindow)
                return EXIT_FAILURE;

        /* Load a sprite to display */
        image = sfImage_CreateFromFile("metal-hull.png");
        if (!image)
                return EXIT_FAILURE;
       
        sprite = sfSprite_Create();
        sfSprite_SetImage(sprite, image);

        /* Create a graphical string to display */
        font = sfFont_CreateFromFile("UbuntuMono-R.ttf", 64, NULL);
        if (!font)
                return EXIT_FAILURE;
       
        text = sfString_Create();
        sfString_SetText(text, "Hello CSFML");
        sfString_SetFont(text, font);
        sfString_SetSize(text, 32);
       
        return EXIT_SUCCESS;
}

void gui_cleanup ()
{
        /* Cleanup resources */
        sfString_Destroy(text);
        sfFont_Destroy(font);
        sfSprite_Destroy(sprite);
        sfImage_Destroy(image);
        sfRenderWindow_Destroy(mainWindow);
}

void rendering_thread_handler (void* arg)
{
        sfContext* p_context = sfContext_Create();
        sfContext_SetActive(p_context , sfTrue);
       
        long t1 = mx_get_uptime();
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                /* Clear the screen */
                sfRenderWindow_Clear(mainWindow, sfBlack);

                /* Draw the sprite */
                sfRenderWindow_DrawSprite(mainWindow, sprite);

                /* Draw the string */
                sfRenderWindow_DrawString(mainWindow, text);

                /* Update the window */
                sfRenderWindow_Display(mainWindow);
               
                mx_sync_loop(&t1, 30);
        }
       
        sfContext_Destroy(p_context);
}

void event_handler_thread_handler (void* arg)
{
        sfContext* p_context = sfContext_Create();
        sfContext_SetActive(p_context , sfTrue);
       
        /* Process events */
        long t1 = mx_get_uptime();
        while (sfRenderWindow_GetEvent(mainWindow, &event))
        {
               
                /* Close window : exit */
                if (event.Type == sfEvtClosed)
                {
                        sfRenderWindow_Close(mainWindow);
                        break;
                }
               
                mx_sync_loop(&t1, 30);
        }
       
        sfContext_Destroy(p_context);
}

/** \brief Returns the amount of micro-seconds since the program was started.
 * \return The time (in milli-seconds) since the program was started.
 *
 */

long mx_get_uptime ()
{
        return (long) ((double) clock() / (CLOCKS_PER_SEC / 1000.0));   // ... until I think of a better implementation...
}

/** \brief Causes the program to wait for ms_time milliseconds.
 *
 */

void mx_msleep (long ms_time)
{
#ifdef __linux__
        usleep(ms_time * 1000);
#elif _WIN32
        Sleep(ms_time);
#endif
}

/** \brief Synchronizes a loop to be executed at certain rate.
 * \param t1 a pointer to the last syncing time in milliseconds. Must be initialized before entering the loop.
 * \param fps the frame rate to maintain
 *
 */

void mx_sync_loop (long* t1, long fps)
{
        long t2 = mx_get_uptime();
        if ((t2-*t1) > (1000/fps))
        {
                *t1 = t2;
        }
        else
        {
                mx_msleep((1000/fps) - (t2-*t1));
                *t1 = mx_get_uptime();
        }
}
 

Can someone help me, please ?
I'm using Code::Blocks 12.11, MinGW with gcc 4.7.2 and my OS is a 64-bit Windows 7.

PS: I don't know why, but when I run the Debug build, the program prints a lot of
An internal OpenGL call failed in SOURCE_FILE.cpp (LINE_NUMBER) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
messages to the console (where SOURCE_FILE.cpp (LINE_NUMBER) are various, for example Image.cpp (482)).
Also, I tried with and without the
    sfContext* p_context = sfContext_Create();
    sfContext_SetActive(p_context , sfTrue);
    ...
    sfContext_Destroy(p_context);
 
lines, but the problem is the same.
« Last Edit: February 18, 2013, 01:07:29 am by M4X »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #1 on: February 17, 2013, 10:52:35 pm »
I would strongly advice you to use SFML 2.0, it also comes along with a C binding, if you, for some reason, don't want to use the intended C++ API.

You won't get much if any advantage by trying to separate event handling and rendering in different threads, mostly probably you'll only introduce more issues (race conditions, specific synchronisation issues, etc) and in the end your application still might run in serial rather than in parallel (e.g. since you might sync the two threads every frame iteration).

As for the problem, you'll have to handle the events in the same thread as you've created the window - at least that's the case in SFML 2.
I'm also not 100% sure if you need to define your own sf::Context...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #2 on: February 17, 2013, 11:07:31 pm »
Thank you for replying :) . I actually have to do this project entirely in C ;)
I moved the event handling in the main:
int main(int argc, char* argv[])
{
        if (gui_init() != EXIT_SUCCESS)
                return EXIT_FAILURE;
       
       
        sfThread* rendering_thread = sfThread_Create(rendering_thread_handler, NULL);
        sfThread_Launch(rendering_thread);
       
        event_handler_thread_handler(NULL);
       
        sfThread_Wait(rendering_thread);
       
       
        gui_cleanup();

        return EXIT_SUCCESS;

}
and I also removed the sfContext lines from the functions, but the problem is still the same.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #3 on: February 17, 2013, 11:18:05 pm »
I still would suggest to use SFML 2, since SFML 1.6 comes with quite a few bugs.
And I still advise you to not split the event handling and rendering in separated threads, it might seems

Anyways, at the moment you're handling the events only once and then the event_handler_thread_handler() function (2x handler really? ;D) will exit after processing the first few events.
You'll have to add a while(window.IsOpened()) loop as well, so it runs as long as the window is open and not just once.

Btw. you can also use sf::Sleep(float) instead of re-implementing it again (see here).
« Last Edit: February 17, 2013, 11:20:49 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #4 on: February 17, 2013, 11:38:33 pm »
lol
When I split the example program, I forgot to add the outer loop in the event handler ^^"
Thank you for your help.
Now the everything runs as expected :)
I'm posting the working code (some cleaning is needed though ;) ), in case someone else got the same problem (notice the necessity of the sfContext creation for both the thread and the function called from the main, that's the only way I got the program to work without errors. I don't know why, but I'll try to figure it out once I get deeper into the library (that's still my first program :p ))
#ifdef __linux__
        #include <unistd.h>
#elif _WIN32
        #include <windows.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// CSFML headers
#include <SFML/Graphics.h>
#include <SFML/Window.h>

// csfml
sfWindowSettings windowSettings = {24, 8, 0};
sfVideoMode videoMode = {800, 600, 32};
sfRenderWindow* mainWindow;
sfImage* image;
sfSprite* sprite;
sfFont* font;
sfString* text;
sfEvent event;


int gui_init ();
void gui_cleanup ();

void rendering_thread_handler (void* arg);
void event_handler_thread_handler (void* arg);

long mx_get_uptime ();
void mx_msleep ();
void mx_sync_loop (long* t1, long fps);



int main(int argc, char* argv[])
{
        if (gui_init() != EXIT_SUCCESS)
                return EXIT_FAILURE;
       
       
        sfThread* rendering_thread = sfThread_Create(rendering_thread_handler, NULL);
        //sfThread* event_handling_thread = sfThread_Create(event_handler_thread_handler, NULL);
       
        sfThread_Launch(rendering_thread);
        //sfThread_Launch(event_handling_thread);
       
        event_handler_thread_handler (NULL);
       
        //sfThread_Wait(event_handling_thread);
        sfThread_Wait(rendering_thread);
       
       
        gui_cleanup();

        return EXIT_SUCCESS;

}

int gui_init ()
{
        /* Create the main window */
        mainWindow = sfRenderWindow_Create(videoMode, "SFML window", sfResize | sfClose, windowSettings);
        if (!mainWindow)
                return EXIT_FAILURE;

        /* Load a sprite to display */
        image = sfImage_CreateFromFile("metal-hull.png");
        if (!image)
                return EXIT_FAILURE;
       
        sprite = sfSprite_Create();
        sfSprite_SetImage(sprite, image);

        /* Create a graphical string to display */
        font = sfFont_CreateFromFile("UbuntuMono-R.ttf", 64, NULL);
        if (!font)
                return EXIT_FAILURE;
       
        text = sfString_Create();
        sfString_SetText(text, "Hello CSFML");
        sfString_SetFont(text, font);
        sfString_SetSize(text, 32);
       
        return EXIT_SUCCESS;
}

void gui_cleanup ()
{
        /* Cleanup resources */
        sfString_Destroy(text);
        sfFont_Destroy(font);
        sfSprite_Destroy(sprite);
        sfImage_Destroy(image);
        sfRenderWindow_Destroy(mainWindow);
}

void rendering_thread_handler (void* arg)
{
        sfContext* p_context = sfContext_Create();
        sfContext_SetActive(p_context , sfTrue);
       
        long t1 = mx_get_uptime();
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                /* Clear the screen */
                sfRenderWindow_Clear(mainWindow, sfBlack);

                /* Draw the sprite */
                sfRenderWindow_DrawSprite(mainWindow, sprite);

                /* Draw the string */
                sfRenderWindow_DrawString(mainWindow, text);

                /* Update the window */
                sfRenderWindow_Display(mainWindow);
               
                mx_sync_loop(&t1, 30);
        }
       
        sfContext_Destroy(p_context);
}

void event_handler_thread_handler (void* arg)
{
        sfContext* p_context = sfContext_Create();
        sfContext_SetActive(p_context , sfTrue);
       
        /* Process events */
        long t1 = mx_get_uptime();
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                while (sfRenderWindow_GetEvent(mainWindow, &event))
                {

                        /* Close window : exit */
                        if (event.Type == sfEvtClosed)
                        {
                                sfRenderWindow_Close(mainWindow);
                                break;
                        }


                }
               
                mx_sync_loop(&t1, 30);
        }
        sfContext_Destroy(p_context);
}

/** \brief Returns the amount of micro-seconds since the program was started.
 * \return The time (in milli-seconds) since the program was started.
 *
 */

long mx_get_uptime ()
{
        return (long) ((double) clock() / (CLOCKS_PER_SEC / 1000.0));   // ... until I think of a better implementation...
}

/** \brief Causes the program to wait for ms_time milliseconds.
 *
 */

void mx_msleep (long ms_time)
{
#ifdef __linux__
        usleep(ms_time * 1000);
#elif _WIN32
        Sleep(ms_time);
#endif
}

/** \brief Synchronizes a loop to be executed at certain rate.
 * \param t1 a pointer to the last syncing time in milliseconds. Must be initialized before entering the loop.
 * \param fps the frame rate to maintain
 *
 */

void mx_sync_loop (long* t1, long fps)
{
        long t2 = mx_get_uptime();
        if ((t2-*t1) > (1000/fps))
        {
                *t1 = t2;
        }
        else
        {
                mx_msleep((1000/fps) - (t2-*t1));
                *t1 = mx_get_uptime();
        }
}
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #5 on: February 18, 2013, 07:59:45 am »
You don't need those contexts, trust me. What happens if you remove them?
Laurent Gomila - SFML developer

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #6 on: February 18, 2013, 01:01:05 pm »
The app doesn't freeze if I remove them, but nothing is rendered, all I get is a black window.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #7 on: February 18, 2013, 01:12:58 pm »
I know it's not directly linked to your problem, but it would be really great if you could write a complete and minimal example that reproduces this context problem :)
« Last Edit: February 18, 2013, 02:21:47 pm by Laurent »
Laurent Gomila - SFML developer

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #8 on: February 18, 2013, 01:38:24 pm »
You'll find the complete Code::Blocks project here https://docs.google.com/file/d/0Bxj_y2ql85uAZS1MZzVsUnZ2bDA/edit?usp=sharing (notice that I've put the dlls/resources within the Debug/Release folders on purpose)

I just copied the program you provided in the CFML 1.6 chm doc file and separated the init/rendering/enventHandling/cleaning in different functions (only the rendering is done in a separate thread, I would have liked to put the event handling in another thread, but the program didn't work)
I "tried" to keep everything relatively organized ;)

PS: also, if you know, I'd like to know how I could launch the program without the console window appearing. I didn't exaclty get how to do this with CSFML:
Quote
Under Windows operating systems, you may have created a "Windows Application" project, especially if don't want the console to show up. In such case, to avoid replacing main by WinMain, you can link with SFML_Main static library and keep a standard and portable main entry point.
# http://www.sfml-dev.org/tutorials/1.6/window-window.php

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #9 on: February 18, 2013, 01:46:40 pm »
Quote
You'll find the complete Code::Blocks project here
Sorry if I wasn't clear, but what I asked for is a minimal example that only shows this problem (and nothing else).

So that I can:
- confirm the bug
- debug it

Since you already have a small code, and that you can produce the bug, I think it's easier if you do it yourself. That's why I ask.

Quote
also, if you know, I'd like to know how I could launch the program without the console window appearing. I didn't exaclty get how to do this with CSFML:
The quoted explanation is not specific to C++ nor SFML (but rather to Code::Blocks), so you can apply it directly.
If you don't want to create a new project, you can change it directly in the project settings.
Laurent Gomila - SFML developer

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #10 on: February 18, 2013, 01:57:58 pm »
It's actually what I would call a minimal program with csfml...
I'll try to remove the unnecessary function calls later tonight and post the result.

Conserning the static linking, I tried linking (the Debug build) with these options
-lcsfml-window-s-d
-lcsfml-graphics-s-d
-lcsfml-system-s-d
but the build failed:
X:\programming\c\HelloCSFML\main.c||In function 'gui_init':|
X:\programming\c\HelloCSFML\main.c|74|warning: implicit declaration of function 'sfFont_CreateFromFile' [-Wimplicit-function-declaration]|
X:\programming\c\HelloCSFML\main.c|74|warning: assignment makes pointer from integer without a cast [enabled by default]|
X:\programming\c\HelloCSFML\main.c||In function 'gui_cleanup':|
X:\programming\c\HelloCSFML\main.c|90|warning: implicit declaration of function 'sfFont_Destroy' [-Wimplicit-function-declaration]|
C:\mingw\lib\SFML\libcsfml-window-s-d.a(Context.o):Context.cpp|| undefined reference to `sf::Context::SetActive(bool)'|
C:\mingw\lib\SFML\libcsfml-window-s-d.a(Context.o):Context.cpp:(.text$_ZN9sfContextC1Ev[__ZN9sfContextC1Ev]+0xd)||undefined reference to `sf::Context::Context()'|
||=== Build finished: 2 errors, 3 warnings (0 minutes, 0 seconds) ===|
 
« Last Edit: February 18, 2013, 01:59:32 pm by M4X »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #11 on: February 18, 2013, 02:27:16 pm »
You can't link CSFML statically, it is written in C++ and would thus produce errors with your C linker.

Quote
It's actually what I would call a minimal program with csfml...
I'll try to remove the unnecessary function calls later tonight and post the result.
I think you still don't understand what I'm talking about.

I don't want your current project, or parts of it. I just need a tiny (but complete) code that demonstrates the "cannot draw without a context" problem. Something written from scratch, based (or not) on the code that you posted above.

But I'm starting to annoy you, just forget about that ;)
Laurent Gomila - SFML developer

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #12 on: February 18, 2013, 04:48:14 pm »
No problem, I was just a little bit busy ;)
So I left the things that I think caused the problem (i.e. the rendering from a separate thread), the event handling (for closing the window) is left in the main()
Notice that, now, it doesn't matter whether I comment the sfContext lines or not, no rendering is made in the window.
#include <stdlib.h>

#include <SFML/Graphics.h>
#include <SFML/Window.h>


sfRenderWindow* mainWindow;
sfSprite* sprite;

void rendering_thread_handler (void* arg);

int main(int argc, char* argv[])
{
        sfWindowSettings windowSettings = {24, 8, 0};
        sfVideoMode videoMode = {800, 600, 32};
        sfImage* image;
        sfEvent event;
       
        mainWindow = sfRenderWindow_Create(videoMode, "SFML window", sfResize | sfClose, windowSettings);
        if (!mainWindow)
                return EXIT_FAILURE;

        image = sfImage_CreateFromFile("metal-hull.png");
        if (!image)
                return EXIT_FAILURE;
       
        sprite = sfSprite_Create();
        sfSprite_SetImage(sprite, image);
       
       
        sfThread* rendering_thread = sfThread_Create(rendering_thread_handler, NULL);
        sfThread_Launch(rendering_thread);
       
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                while (sfRenderWindow_GetEvent(mainWindow, &event))
                {
                        if (event.Type == sfEvtClosed)
                        {
                                sfRenderWindow_Close(mainWindow);
                                break;
                        }
                }
        }
       
        sfThread_Wait(rendering_thread);
       
       
        sfSprite_Destroy(sprite);
        sfImage_Destroy(image);
        sfRenderWindow_Destroy(mainWindow);

        return EXIT_SUCCESS;

}

void rendering_thread_handler (void* arg)
{
        //sfContext* p_context = sfContext_Create();
        //sfContext_SetActive(p_context , sfTrue);
       
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                sfRenderWindow_Clear(mainWindow, sfBlack);
                sfRenderWindow_DrawSprite(mainWindow, sprite);
                sfRenderWindow_Display(mainWindow);
        }
       
        //sfContext_Destroy(p_context);
}

Quote
You can't link CSFML statically, it is written in C++ and would thus produce errors with your C linker.
Is that also the reason why -static-libgcc and/or -static have no effect on the linker ? (the program can't run without libgcc_s_dw2-1.dll )

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #13 on: February 18, 2013, 08:10:06 pm »
I think I understand what happens. You must call sfRenderWindow_SetActive(false) in the main thread before launching the rendering thread. If you check your standard output, you should see an error message.

With this fix you should not need the sfContexts anymore.

Quote
Is that also the reason why -static-libgcc and/or -static have no effect on the linker ? (the program can't run without libgcc_s_dw2-1.dll )
Yes, this DLL is required indirectly, by SFML. If you want to get rid of it you must recompile SFML.
Laurent Gomila - SFML developer

M4X

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: [Solved] [CSFML 1.6] Using threads, window freezes, no rendering
« Reply #14 on: February 18, 2013, 09:53:11 pm »
Interesting.
I added
sfRenderWindow_SetActive(mainWindow, sfFalse);
before launching the thread as you mensioned:
#include <stdlib.h>

#include <SFML/Graphics.h>
#include <SFML/Window.h>


sfRenderWindow* mainWindow;
sfSprite* sprite;

void rendering_thread_handler (void* arg);

int main(int argc, char* argv[])
{
        sfWindowSettings windowSettings = {24, 8, 0};
        sfVideoMode videoMode = {800, 600, 32};
        sfImage* image;
        sfEvent event;
       
        mainWindow = sfRenderWindow_Create(videoMode, "SFML window", sfResize | sfClose, windowSettings);
        if (!mainWindow)
                return EXIT_FAILURE;

        image = sfImage_CreateFromFile("metal-hull.png");
        if (!image)
                return EXIT_FAILURE;
       
        sprite = sfSprite_Create();
        sfSprite_SetImage(sprite, image);
       
       
        sfThread* rendering_thread = sfThread_Create(rendering_thread_handler, NULL);
       
        sfRenderWindow_SetActive(mainWindow, sfFalse);
        sfThread_Launch(rendering_thread);
       
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                while (sfRenderWindow_GetEvent(mainWindow, &event))
                {
                        if (event.Type == sfEvtClosed)
                        {
                                sfRenderWindow_Close(mainWindow);
                                break;
                        }
                }
        }
       
        sfThread_Wait(rendering_thread);
       
       
        sfSprite_Destroy(sprite);
        sfImage_Destroy(image);
        sfRenderWindow_Destroy(mainWindow);

        return EXIT_SUCCESS;

}

void rendering_thread_handler (void* arg)
{
        while (sfRenderWindow_IsOpened(mainWindow))
        {
                sfRenderWindow_Clear(mainWindow, sfBlack);
                sfRenderWindow_DrawSprite(mainWindow, sprite);
                sfRenderWindow_Display(mainWindow);
        }
}
The image is now correctly rendered to the window... but, as you said, I get an error when I close the program:
pure virtual method called
terminate called without an active exception

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Process returned 3 (0x3)   execution time : 9.661 s
Press any key to continue.