SDLVideo In Threads Under OS X

Has anyone had any luck getting SDL to init video under OS X when calling
it from a newly created thread (either SDL threads or pthreads (which SDL
threads call I suppose))? It draws the video window and then crashes on a
Quartz drawing function during SetVideoMode. I’ve modified testhread to
reproduce this:

/* Simple test of the SDL threading code */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <Cocoa/Cocoa.h>

#include “SDL.h”
#include “SDL_thread.h”

static int alive = 0;

int ThreadFunc(void *data)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    SDL_Surface* screen;
    
    printf(\"Started thread %s: My thread id is %u\\n\",
			(char *)data, SDL_ThreadID());
while ( alive ) {
	printf(\"Thread \'%s\' is alive!\\n\", (char *)data);
            
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
	fprintf(stderr, \"Couldn\'t initialize SDL: %s\\n\",SDL_GetError());
	exit(1);
}
    if ( (screen=SDL_SetVideoMode(640,480,16,SDL_SWSURFACE)) == NULL )

{
fprintf(stderr, “Couldn’t set 640x480x16 video mode: %s\n”,
SDL_GetError());
exit(2);
}
SDL_Delay(1*1000);
}
printf(“Thread ‘%s’ exiting!\n”, (char *)data);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
[pool release];
return(0);
}

static void killed(int sig)
{
printf(“Killed with SIGTERM, waiting 5 seconds to exit\n”);
SDL_Delay(5*1000);
alive = 0;
exit(0);
}

int main(int argc, char *argv[])
{
SDL_Thread *thread;

/* Load the SDL library */
if ( SDL_Init(0) < 0 ) {
	fprintf(stderr, \"Couldn\'t initialize SDL: %s\\n\",SDL_GetError());
	exit(1);
}
atexit(SDL_Quit);

alive = 1;
thread = SDL_CreateThread(ThreadFunc, \"#1\");
if ( thread == NULL ) {
	fprintf(stderr, \"Couldn\'t create thread: %s\\n\", SDL_GetError());
	exit(1);
}
SDL_Delay(5*1000);
printf(\"Waiting for thread #1\\n\");
alive = 0;
SDL_WaitThread(thread, NULL);

alive = 1;
thread = SDL_CreateThread(ThreadFunc, \"#2\");
if ( thread == NULL ) {
	fprintf(stderr, \"Couldn\'t create thread: %s\\n\", SDL_GetError());
	exit(1);
}
SDL_Delay(5*1000);
printf(\"Killing thread #2\\n\");
SDL_KillThread(thread);

alive = 1;
signal(SIGTERM, killed);
thread = SDL_CreateThread(ThreadFunc, \"#3\");
if ( thread == NULL ) {
	fprintf(stderr, \"Couldn\'t create thread: %s\\n\", SDL_GetError());
	exit(1);
}
raise(SIGTERM);

return(0);	/* Never reached */

}

Thanks.
-Lucas Newman

I wouldn’t think this would be thread safe, I would assume that you can
only init and draw to the main process of execution. Otherwise, I would
think you could run into some rather nasty race conditions with the
blitter/GPU.On Sun, 2002-11-24 at 19:30, flea at emuscene.com wrote:

Has anyone had any luck getting SDL to init video under OS X when calling
it from a newly created thread (either SDL threads or pthreads (which SDL
threads call I suppose))? It draws the video window and then crashes on a
Quartz drawing function during SetVideoMode. I’ve modified testhread to
reproduce this:

/* Simple test of the SDL threading code */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <Cocoa/Cocoa.h>

#include “SDL.h”
#include “SDL_thread.h”

static int alive = 0;

int ThreadFunc(void *data)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    SDL_Surface* screen;
    
    printf(\"Started thread %s: My thread id is %u\\n\",
  		(char *)data, SDL_ThreadID());

while ( alive ) {
printf(“Thread ‘%s’ is alive!\n”, (char *)data);

if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, “Couldn’t initialize SDL: %s\n”,SDL_GetError());
exit(1);
}
if ( (screen=SDL_SetVideoMode(640,480,16,SDL_SWSURFACE)) == NULL )
{
fprintf(stderr, “Couldn’t set 640x480x16 video mode: %s\n”,
SDL_GetError());
exit(2);
}
SDL_Delay(1*1000);
}
printf(“Thread ‘%s’ exiting!\n”, (char *)data);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
[pool release];
return(0);
}

static void killed(int sig)
{
printf(“Killed with SIGTERM, waiting 5 seconds to exit\n”);
SDL_Delay(5*1000);
alive = 0;
exit(0);
}

int main(int argc, char *argv[])
{
SDL_Thread *thread;

/* Load the SDL library */
if ( SDL_Init(0) < 0 ) {
fprintf(stderr, “Couldn’t initialize SDL: %s\n”,SDL_GetError());
exit(1);
}
atexit(SDL_Quit);

alive = 1;
thread = SDL_CreateThread(ThreadFunc, “#1”);
if ( thread == NULL ) {
fprintf(stderr, “Couldn’t create thread: %s\n”, SDL_GetError());
exit(1);
}
SDL_Delay(5*1000);
printf(“Waiting for thread #1\n”);
alive = 0;
SDL_WaitThread(thread, NULL);

alive = 1;
thread = SDL_CreateThread(ThreadFunc, “#2”);
if ( thread == NULL ) {
fprintf(stderr, “Couldn’t create thread: %s\n”, SDL_GetError());
exit(1);
}
SDL_Delay(5*1000);
printf(“Killing thread #2\n”);
SDL_KillThread(thread);

alive = 1;
signal(SIGTERM, killed);
thread = SDL_CreateThread(ThreadFunc, “#3”);
if ( thread == NULL ) {
fprintf(stderr, “Couldn’t create thread: %s\n”, SDL_GetError());
exit(1);
}
raise(SIGTERM);

return(0); /* Never reached */
}

Thanks.
-Lucas Newman


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Has anyone had any luck getting SDL to init video under OS X when
calling
it from a newly created thread (either SDL threads or pthreads (which
SDL
threads call I suppose))? It draws the video window and then crashes
on a
Quartz drawing function during SetVideoMode. I’ve modified testhread
to
reproduce this:

Many of the API’s used to implement SDL on Mac OS X are not
thread-safe. Drawing operations will not work from an SDL thread, since
there is per-thread graphics context info that must be present in the
thread you are drawing from (by default, the main thread contains this
information). To draw from another thread, you would have to use
NSApp’s detachDrawingThread method to create the thread. I wouldn’t be
surprised if this approached didn’t work in SDL, however.

This isn’t such a bad thing. Since most of the blitters in SDL will be
memory bandwidth limited (both to the CPU caches and video memory),
there usually isn’t an advantage to using a multi-threaded blitter.On Sunday, November 24, 2002, at 08:30 PM, flea at emuscene.com wrote: