예제 #1
0
int main(int argc, char *argv[]) {
    bool gameIsActive;

    if (!init()) {
        printf("error initializing");
        return 1;
    }
    printf("initialized\n");
    printf("Waiting for connection...\n");
    while (true) {
        acceptConnection();
        initGame();
        printf("Game initialized");
        gameIsActive = true;
        packetId=0;
        SDL_DetachThread(SDL_CreateThread(udpListener, "udpThread", NULL));
        while (1) {
            updateBullets();
            updateShips();
            createAndSendUDPPackets();
            SDL_Delay(20);
//            if (!ClientsAreReady()) {
//                gameIsActive = false;
//            }
        }
    }
    closeServer();
    return 0;
}
예제 #2
0
int OSX_Mouse_Init(void)
{
	if (cur_mdata)
		OSX_Mouse_Shutdown();
	
	cur_mdata = new struct osx_mouse_data();
	if (!cur_mdata)
		return -1;

	cur_mdata->mouse_mutex = SDL_CreateMutex();
	if (!cur_mdata->mouse_mutex) {
		delete cur_mdata;
		cur_mdata = NULL;
		return -1;
	}
	
	SDL_Thread *thread = SDL_CreateThread(OSX_Mouse_Thread, "OSX_Mouse_Thread", cur_mdata);
	if (!thread) {
		SDL_DestroyMutex(cur_mdata->mouse_mutex);
		delete cur_mdata;
		cur_mdata = NULL;
		return -1;
	}
	
	SDL_DetachThread(thread);
	return 0;
}
예제 #3
0
파일: http.cpp 프로젝트: YJSoft/OpenRCT2
void http_request_json_async(const http_json_request *request, void (*callback)(http_json_response*))
{
	struct TempThreadArgs {
		http_json_request request;
		void (*callback)(http_json_response*);
	};

	TempThreadArgs *args = (TempThreadArgs*)malloc(sizeof(TempThreadArgs));
	args->request.url = _strdup(request->url);
	args->request.method = request->method;
	args->request.body = json_deep_copy(request->body);
	args->request.tag = request->tag;
	args->callback = callback;

	SDL_Thread *thread = SDL_CreateThread([](void *ptr) -> int {
		TempThreadArgs *args = (TempThreadArgs*)ptr;

		http_json_response *response = http_request_json(&args->request);
		args->callback(response);

		free((char*)args->request.url);
		json_decref((json_t*)args->request.body);
		free(args);
		return 0;
	}, NULL, args);

	if (thread == NULL) {
		log_error("Unable to create thread!");
		callback(NULL);
	} else {
		SDL_DetachThread(thread);
	}
}
예제 #4
0
Thread::~Thread() {
  if (!thread)
    delete terminated;
#ifdef _WIN32
  else if (!joined)
    SDL_DetachThread((SDL_Thread*)thread);
#endif
}
예제 #5
0
파일: http.cpp 프로젝트: LucaRed/OpenRCT2
void http_request_async(const http_request_t *request, void (*callback)(http_response_t*))
{
    struct TempThreadArgs {
        http_request_t request;
        void (*callback)(http_response_t*);
    };

    TempThreadArgs *args = (TempThreadArgs*)malloc(sizeof(TempThreadArgs));
    args->request.url = _strdup(request->url);
    args->request.method = request->method;

    if (request->type == HTTP_DATA_JSON) {
        args->request.root = json_deep_copy(request->root);
    } else {
        char* bodyCopy = (char*) malloc(request->size);
        memcpy(bodyCopy, request->body, request->size);
        args->request.body = bodyCopy;
    }

    args->request.type = request->type;
    args->request.size = request->size;
    args->request.tag = request->tag;
    args->callback = callback;

    SDL_Thread *thread = SDL_CreateThread([](void *ptr) -> sint32 {
        TempThreadArgs *args2 = (TempThreadArgs*)ptr;

        http_response_t *response = http_request(&args2->request);
        args2->callback(response);

        free((char*)args2->request.url);

        if (args2->request.type == HTTP_DATA_JSON) {
            json_decref((json_t*) args2->request.root);
        } else {
            free(args2->request.body);
        }

        free(args2);
        return 0;
    }, NULL, args);

    if (thread == NULL) {
        log_error("Unable to create thread!");
        callback(NULL);
    } else {
        SDL_DetachThread(thread);
    }
}
//Destroy the thread pool
void ThreadPool::destroy()
{
    for (int i = 0; i < numThreads; i++)
    {
        //Kill threads
        if (threads[i] != NULL)
            SDL_DetachThread(threads[i]);
    }

    //Destroy Mutex and Signals
    SDL_DestroyMutex(quequeMutex);
    SDL_DestroyMutex(workerMutex);
    SDL_DestroyMutex(mutexBarrier);
    SDL_DestroyCond(condBarrier);
    SDL_DestroyCond(condHaveWork);
}
예제 #7
0
static void qtvlist_spawn_updater(void)
{
	SDL_Thread *qtvlist_thread;

	if (qtvlist_mutex == NULL) {
		Com_Printf("error: cannot update QTV list, mutex not initialized\n");
		return;
	}

	qtvlist_thread = SDL_CreateThread(qtvlist_update, "qtvupdater", (void*)NULL);
	if (qtvlist_thread == NULL) {
		Com_Printf("error: failed to initialize qtvlist thread\n");
		Com_Printf("error: qtv/observeqtv commands may not work...\n");
		return;
	}

	SDL_DetachThread(qtvlist_thread);
}
예제 #8
0
void acceptConnection() {
    int clientId;
    TCPsocket incomming;

    while (true) {
        incomming = SDLNet_TCP_Accept(TCPsock);

        if (incomming !=0x0) {
            if ((clientId = getClientId())<0) {printf("Too many users! \n");}
            else {
                clients[clientId].socket = incomming;
                clients[clientId].id = clientId;
                clients[clientId].active = true;
                clients[clientId].ip = SDLNet_TCP_GetPeerAddress(incomming)->host;
                SDL_DetachThread(SDL_CreateThread(Lobby, "lobbyThread", &clientId));
                incomming = NULL;
            }
        }
        if(ClientsAreReady()) {
            printf("starting in 3...\n");
            Broadcast("$4starting in 3...");
            SDL_Delay(1000);
            if(ClientsAreReady()) {
                printf("starting in 2...\n");
                Broadcast("$4starting in 2...");
                SDL_Delay(1000);
                if(ClientsAreReady()) {
                    printf("starting in 1...\n");
                    Broadcast("$4starting in 1...");
                    SDL_Delay(1000);
                    printf("!GO\n");
                    Broadcast("!GO");
                    break;
                }
            }
        }
        incomming = NULL;
        SDL_Delay(1000);
    }

}
예제 #9
0
App::App(int &argc, char **argv, int samplerate/*=44100*/)
//main_window(SCREEN_WIDTH, SCREEN_HEIGHT, APP_NAME_VERSION)
{
  //Colors::precompute(*main_window->screen);
  //Render_Context::load_from_window(main_window);
  file_system = new File_System;
  app_settings=new App_Settings(file_system);
  audio=new Audio;
  player=new Music_Player;
  Player_Context::player = player;

  handle_error(player->init(samplerate, app_settings->vars.audio_out_dev) );
  
  //App_Settings_Context::app_settings = &app_settings;

  debugger = new Debugger(argc, argv);

  SDL_Thread *thread = SDL_CreateThread(create_midi, "create_midi", this);
  SDL_DetachThread(thread);

}
예제 #10
0
void joinLobby(int *mode){
    printf("DEBUG: JOINING LOBBY... REMOVE THIS LATER (inputhandler.c:242)\n");
    bool success;
    success = resolveIPPortFromStrings();
    if(!success)
        return;

    client.TCPSock = SDLNet_TCP_Open(&ip);
    if(client.TCPSock == NULL){
        printf("TCP Open Failure\n");
        //exit(EXIT_FAILURE);
        return;
    }

    SDLNet_TCP_Send(client.TCPSock, textString[ENTERING_NAME], MAX_NAME_LENGTH);

    client.UDPRecvSock = SDLNet_UDP_Open(0);
    client.UDPSendSock = SDLNet_UDP_Open(0);
    if(client.UDPRecvSock == NULL || client.UDPSendSock == NULL){
        printf("Opening of UDP sockets failed!\n");
        exit(EXIT_FAILURE);
    }
//
//    // Send the clients ports for UDP recieve and UDP send
//    SDLNet_TCP_Send(client.TCPSock, 1234, sizeof(int)); printf("1\n");
//    //SDLNet_TCP_Send(client.TCPSock, &(SDLNet_UDP_GetPeerAddress(client.UDPSendSock,-1)->port),sizeof(Uint16));
//    SDLNet_TCP_Recv(client.TCPSock, &(client.ServerRecvUDPPort), sizeof(int));printf("2\n");
//    printf("sENT: %x\nRecieved port: %x\n", (SDLNet_UDP_GetPeerAddress(client.UDPRecvSock,-1))->port, client.ServerRecvUDPPort);printf("3\n");

    printf("CONNECTED\n"); exit(0);

    chatRecv = SDL_CreateThread(chatRecieve, "BC ChatRecv", &client);
    SDL_DetachThread(chatRecv);
    isConnected = true;
    //*******************************************************************************************
    *mode = LOBBY;
    clearTextStrings(6);
    return;
}
예제 #11
0
파일: thread.c 프로젝트: dns/CLove
/*
static int l_thread_getThreadID(lua_State* state) { 
    thread_Data* thread = (thread_Data*)lua_touserdata(state, 1);
    lua_pushinteger(state, SDL_GetThreadID(thread->thread));
    return 1;
}

static int l_thread_getThreadName(lua_State* state) { 
    thread_Data* thread = (thread_Data*)lua_touserdata(state, 1);
    lua_pushstring(state, SDL_GetThreadName(thread->thread));
    return 1;
}
*/
static int l_thread_gcThread(lua_State* state) {
    thread_Data* thread = (thread_Data*)lua_touserdata(state, 1);
    SDL_DetachThread(thread->thread);
    return 1;
}
예제 #12
0
TaskManager* taskmgr_create(uint numthreads, SDL_ThreadPriority prio, const char *name) {
	int numcores = SDL_GetCPUCount();
	uint maxthreads = numcores * 8;

	if(numcores < 1) {
		log_warn("SDL_GetCPUCount() returned %i, assuming 1", numcores);
		numcores = 1;
	}

	if(numthreads == 0) {
		numthreads = numcores * 4;
	} else if(numthreads > maxthreads) {
		log_warn("Number of threads capped to %i (%i requested)", maxthreads, numthreads);
		numthreads = maxthreads;
	}

	TaskManager *mgr = calloc(1, sizeof(TaskManager) + numthreads * sizeof(SDL_Thread*));

	if(!(mgr->mutex = SDL_CreateMutex())) {
		log_sdl_error(LOG_WARN, "SDL_CreateMutex");
		goto fail;
	}

	if(!(mgr->cond = SDL_CreateCond())) {
		log_sdl_error(LOG_WARN, "SDL_CreateCond");
		goto fail;
	}

	mgr->numthreads = numthreads;
	mgr->thread_prio = prio;

	for(uint i = 0; i < numthreads; ++i) {
		int digits = i ? log10(i) + 1 : 0;
		static const char *const prefix = "taskmgr";
		char threadname[sizeof(prefix) + strlen(name) + digits + 2];
		snprintf(threadname, sizeof(threadname), "%s:%s/%i", prefix, name, i);

		if(!(mgr->threads[i] = SDL_CreateThread(taskmgr_thread, threadname, mgr))) {
			log_sdl_error(LOG_WARN, "SDL_CreateThread");

			for(uint j = 0; j < i; ++j) {
				SDL_DetachThread(mgr->threads[j]);
				mgr->threads[j] = NULL;
			}

			SDL_LockMutex(mgr->mutex);
			mgr->aborted = true;
			SDL_CondBroadcast(mgr->cond);
			SDL_UnlockMutex(mgr->mutex);
			goto fail;
		}
	}

	SDL_LockMutex(mgr->mutex);
	mgr->running = true;
	SDL_CondBroadcast(mgr->cond);
	SDL_UnlockMutex(mgr->mutex);

	log_debug(
		"Created task manager %s (%p) with %u threads at priority %i",
		name,
		(void*)mgr,
		mgr->numthreads,
		prio
	);

	return mgr;

fail:
	taskmgr_free(mgr);
	return NULL;
}
예제 #13
0
int Runtime::runShell(const char *startupBas, int fontScale, int debugPort) {
  logEntered();

  os_graphics = 1;
  os_color_depth = 16;
  opt_interactive = true;
  opt_usevmt = 0;
  opt_file_permitted = 1;
  opt_graphics = true;
  opt_pref_bpp = 0;
  opt_nosave = true;

  _output->setTextColor(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
  _output->setFontSize(getStartupFontSize(_window));
  _initialFontSize = _output->getFontSize();
  if (fontScale != 100) {
    _fontScale = fontScale;
    int fontSize = (_initialFontSize * _fontScale / 100);
    _output->setFontSize(fontSize);
  }

  SDL_Init(SDL_INIT_AUDIO);
  SDL_AudioSpec desiredSpec;
  desiredSpec.freq = FREQUENCY;
  desiredSpec.format = AUDIO_S16SYS;
  desiredSpec.channels = 1;
  desiredSpec.samples = 2048;
  desiredSpec.callback = audio_callback;

  SDL_AudioSpec obtainedSpec;
  SDL_OpenAudio(&desiredSpec, &obtainedSpec);
  net_init();

  if (debugPort > 0) {
    appLog("Debug active on port %d\n", debugPort);
    g_lock = SDL_CreateMutex();
    g_cond = SDL_CreateCond();
    opt_trace_on = 1;
    g_debugBreak = SDL_TRUE;
    SDL_Thread *thread =
      SDL_CreateThread(debugThread, "DBg", (void *)(intptr_t)debugPort);
    SDL_DetachThread(thread);
  }

  if (startupBas != NULL) {
    String bas = startupBas;
    if (opt_ide == IDE_INTERNAL) {
      runEdit(bas.c_str());
    } else {
      runOnce(bas.c_str());
    }
    while (_state == kRestartState) {
      _state = kActiveState;
      if (_loadPath.length() != 0) {
        bas = _loadPath;
      }
      runOnce(bas.c_str());
    }
  } else {
    runMain(MAIN_BAS);
  }

  if (debugPort > 0) {
    SDL_DestroyCond(g_cond);
    SDL_DestroyMutex(g_lock);
  }

  debugStop();
  net_close();
  SDL_CloseAudio();
  _state = kDoneState;
  logLeaving();
  return _fontScale;
}
int main(int argc, char **argv)
{
    daemonize();
    storepid();//Lagra pid nummer för att kunna stänga med stop-skript
    srand(time(NULL));

    gameOver = true;

    ghostHitCount = 0;

    r3p1v.x = 180;
    r3p1v.y = 97;
    r3p1v.w = 16;
    r3p1v.h = 50;

    r3p1h.x = 440;
    r3p1h.y = 97;
    r3p1h.w = 16;
    r3p1h.h = 50;

    r2p0v.x = 0;
    r2p0v.y = 195;
    r2p0v.w = 16;
    r2p0v.h = 50;

    r2p0h.x = 270;
    r2p0h.y = 195;
    r2p0h.w = 16;
    r2p0h.h = 50;

    r2p1v.x = 370;
    r2p1v.y = 195;
    r2p1v.w = 16;
    r2p1v.h = 50;

    r2p1h.x = 622;
    r2p1h.y = 195;
    r2p1h.w = 16;
    r2p1h.h = 50;

    r1p1v.x = 190;
    r1p1v.y = 297;
    r1p1v.w = 16;
    r1p1v.h = 50;

    r1p1h.x = 450;
    r1p1h.y = 297;
    r1p1h.w = 16;
    r1p1h.h = 50;

    r0p0v.x = 0;
    r0p0v.y = 415;
    r0p0v.w = 16;
    r0p0v.h = 50;

    r0p0h.x = 622;
    r0p0h.y = 415;
    r0p0h.w = 16;
    r0p0h.h = 50;

    ghostRect1.x = 300;
    ghostRect1.y = 97;
    ghostRect1.w = 50;
    ghostRect1.h = 50;

    ghostRect2.x = 50;
    ghostRect2.y = 195;
    ghostRect2.w = 50;
    ghostRect2.h = 50;

    ghostRect3.x = 500;
    ghostRect3.y = 195;
    ghostRect3.w = 50;
    ghostRect3.h = 50;

    ghostRect4.x = 300;
    ghostRect4.y = 297;
    ghostRect4.w = 50;
    ghostRect4.h = 50;

    ghostRect5.x = 400;
    ghostRect5.y = 415;
    ghostRect5.w = 50;
    ghostRect5.h = 50;

	IPaddress ip, *remoteIP;
	int quit, quit2;
	char buffer[512];
	bool clientInitiated;

	firstPosition = false;

	SDL_Thread *client1, *client2, *enemy1, *enemy2, *enemy3, *enemy4, *enemy5;

    positionSetMutex = SDL_CreateMutex();
    ghostHitMutex = SDL_CreateMutex();
    if(!positionSetMutex)
    {
        return 0;
    }
    if(!ghostHitMutex)
    {
        return 0;
    }
	initFunctions(&ip, &sd); //Initiera TCP för SDL

    enemy1 = SDL_CreateThread(nextMove, "ghost1", &ghostRect1);
    enemy2 = SDL_CreateThread(nextMove, "ghost1", &ghostRect2);
    enemy3 = SDL_CreateThread(nextMove, "ghost1", &ghostRect3);
    enemy4 = SDL_CreateThread(nextMove, "ghost1", &ghostRect4);
    enemy5 = SDL_CreateThread(nextMove, "ghost1", &ghostRect5);

    while(true)
    {
        if(gameOver == true)
        {
                waitForClients(&sd); // Väntar på 2 st klienter ska koppla upp sig
                resetVariables();
                gameOver = false;
                client1Position = 0;
                client1 = SDL_CreateThread(startClient, "Client1", (void *)NULL);
                client2 = SDL_CreateThread(startClient, "Client2", (void *)NULL);
                SDL_DetachThread(client1); // Förhindrar att tråden tar upp minne efter att den stänger ner
                SDL_DetachThread(client2);

        }

        SDL_Delay(1000);
    }

	SDLNet_TCP_Close(sd);
	SDLNet_Quit();

	return EXIT_SUCCESS;
}
예제 #15
0
REALIGN STDCALL void WrapperStartInThread(SDL_ThreadFunction mainCodeInSeparateThread)
{
	initializeSDL2();
	SDL_DetachThread(SDL_CreateThread(mainCodeInSeparateThread, NULL, NULL));
}
예제 #16
0
파일: main.c 프로젝트: thebirk/ccpu
int main(int argc, char** argv)
{
	int i;
	int window = 1;
	int showhelp = 0;
	int fps = 0;
	int width = 640;
	int height = 360;
	int fullscreen = 0;

	if(argc > 2) {
		for(i = 2; i < argc; i++) {
			char* dup = strdup(argv[i]);
			char* tok = strtok(dup, "=");			

			if(strcmp(argv[i], "-s") == 0) {
				stepping = 1;
			}else if(strcmp(argv[i], "-noscreen") == 0) {
				window = 0;
			}else if(strcmp(argv[i], "-h") == 0) {
				showhelp = 1;
			}else if(strcmp(argv[i], "-fps") == 0) {
				fps = 1;
			}else if(strcmp(tok, "-width") == 0) {
				tok = strtok(NULL, "=");
				width = strtol(tok, NULL, 0);
			}else if(strcmp(tok, "-height") == 0) {
				tok = strtok(NULL, "=");
				height = strtol(tok, NULL, 0);
			}else if(strcmp(argv[i], "-f") == 0) {
				fullscreen = 1;
			}
			else {
				printf("Ignoring unknown argument '%s'. Use '-h' for more information\n", argv[i]);
			}
		}
	}

	if(argc < 2 | showhelp) {
		printf("Usage: ccpu <binary> [options]\n\nOptions:\n\t-s - Stepping mode\n\t-noscreen - No screen/window\n\t-fps - Output fps\n\t-width=w - Set window width\n\t-height=h - Set window height\n\t-f - Fullscreen mode\n");
		return -1;
	}

	FILE* f = fopen(argv[1], "rb");
	if(f == NULL) {
		printf("Failed to open '%s'\n", argv[1]);
		return -1;
	}
	fseek(f, 0, SEEK_END);
	int length = ftell(f);
	rewind(f);
	u8* buffer = (u8*)malloc(sizeof(u8)*length);
	int read = fread(buffer, sizeof(u8), length, f);
	fclose(f);

	if(read != length) {
		printf("Failed to read file '%s'\n", argv[1]);
		return -1;
	}

	f = fopen("rom.bin", "rb");
	if(f == NULL) {
		printf("Could not open 'rom.bin'\n");
		return -1;
	}
	fseek(f, 0, SEEK_END);
	int rom_length = ftell(f);
	if(rom_length > 0x1000) {
		printf("'rom.bin' is %04X bytes long, but can not be longer than 0x100 bytes\n", rom_length);
		return -1;
	}
	rewind(f);
	u8* rom_buffer = (u8*)malloc(sizeof(u8)*rom_length);
	read = fread(rom_buffer, sizeof(u8), rom_length, f);
	if(read != rom_length) {
		printf("Failed to read 'rom.bin'\n");
		return -1;
	}
	fclose(f);

	c = cpu_init(0x1000);

	for(i = 0; i < length; i++) {
		c->mem[c->ip+i] = buffer[i];
	}

	for(i = 0; i < rom_length; i++) {
		c->mem[0xF000+i] = rom_buffer[i];
	}

	c->ip = 0xF000;

	SDL_Thread* ccpu_thread = SDL_CreateThread(cpu_thread_func, "ccpu_thread", NULL);
	
	if(window) {
	Screen* s = screen_init(width, height, 640, 360, 8, 12, 16, 16, fullscreen);

	Uint32 now = SDL_GetTicks();
	Uint32 lastTime = now;
	Uint32 fpsCounterTime = now;
	Uint32 interval = 16;

	int frames = 0;

	while(!screen_closerequested(s)) {
		now = SDL_GetTicks();
		
		if(now - lastTime > interval) {
			screen_update(s, c);
			frames++;
			lastTime = now;	
		}

		if(now - fpsCounterTime > 1000) {
			if(fps) printf("fps %d\n", frames);
			frames = 0;
			fpsCounterTime = now;
		}

		screen_pollevents(s, c);
		if(!cpu_running) break;
	}
	screen_cleanup(s);
	SDL_DetachThread(ccpu_thread);
	}else {
		SDL_WaitThread(ccpu_thread, NULL);
	}
	
	return 0;
}
예제 #17
0
파일: mt.c 프로젝트: yoanlcq/FATE
void          fe_mt_thread_detach(fe_mt_thread t) {
    SDL_DetachThread(pool.slots[t].thread);
    fe_mt_mutex_lock(&pool_mutex);
    pool.slots[t].taken = false;
    fe_mt_mutex_unlock(&pool_mutex);
}
예제 #18
0
bool App::InitApp (void)
{
#ifdef CONFDIR
    strcpy (settings_path, (std::string (CONFDIR) + PATH_SEPARATOR + "test3d.ini").c_str());
#else
    strcpy (settings_path, (std::string (SDL_GetBasePath ()) + "settings.ini").c_str());
#endif

    int w, h;

    // initialize SDL with screen sizes from settings file:
    w = LoadSetting (settings_path, SCREENWIDTH_SETTING);
    if (w < 640)
        w = 640;

    h = LoadSetting (settings_path, SCREENHEIGHT_SETTING);
    if (h < 480)
        h = 480;

    fullscreen = LoadSetting (settings_path, FULLSCREEN_SETTING) > 0 ? true : false;

    // Create a window:
    if (!InitializeSDL(w, h))
        return false;

    // Create a rendering context in the window:
    if (!InitializeGL())
        return false;

    pScene = new HubScene (this);

    RandomSeed ();

    Progress progress;
    Loader loader;

    // Collect jobs to be done:
    pScene->AddAll (&loader);

    // Progress bar is rendered in a different thread while the scene loads:
    bool error = false;
    SDL_Thread* progressThread = MakeSDLThread (
                                    [&] () { return ProgressLoop (mainWindow, &progress, error); },
                                    "progress"
                                 );
    if (!progressThread)
    {
        SetError ("failed to create progress thread: %s", SDL_GetError());
        return false;
    }

    /*
        Do all jobs while the progress bar is rendered.
        Some of them depend on the current thread's rendering context.
     */
    if (!loader.LoadAll (&progress))
    {
        error = true;
        SDL_DetachThread (progressThread);
        return false;
    }

    // progressThread will finish automatically, now that everything is loaded ..

    // Check for other errors:
    if (!CheckGLOK ("scene init"))
        return false;

    // Wait for progress display thread to finish:
    int progressReturn;
    SDL_WaitThread (progressThread, &progressReturn);
    if (progressReturn != 0)
    {
        SetError ("progress thread returned exit code %d", progressReturn);
        return false;
    }

    return true;
}