view src/thread/generic/SDL_syssem.c @ 1211:304d8dd6a989

To: sdl@libsdl.org From: Christian Walther <cwalther@gmx.ch> Date: Wed, 28 Dec 2005 12:13:20 +0100 Subject: [SDL] Fix for opening documents on Mac OS X < 10.4 The current code in SDLMain.m that transforms documents opened from the Finder into command-line arguments (introduced in revision 1.14, 2005-08-11) uses the methods -[NSString lengthOfBytesUsingEncoding:] and -[NSString getCString:maxLength:encoding:], which are only available in Mac OS X 10.4. Compiling this code on 10.3 produces warnings, and running it (i.e. starting an SDL application by opening a document) leads to weird behavior which I didn't investigate in detail ("*** -[NSCFString lengthOfBytesUsingEncoding:]: selector not recognized" is printed to the console log, and the SDL window never opens). The attached patch removes the offending calls and uses -[NSString UTF8String] instead, which is available everywhere. Tested on 10.3.9, and I see no reason why it shouldn't also work on 10.2 and 10.4. Two further comments: * The comment above the -[SDLMain application: openFile:] implementation says "You need to have a CFBundleDocumentsType section in your Info.plist to get this message, apparently." This is not the case in my experience - it worked just fine with a hand-built bare-bones application consisting only of Test.app/Contents/MacOS/test, without any Info.plist (although you have to press the option and command keys for such an application to accept a dragged file). * I took the liberty of cleaning up another area of SDLMain.m: I changed "CustomApplicationMain (argc, argv)" to "CustomApplicationMain (int argc, char **argv)". This avoids the "type of `argv' defaults to `int'" warnings, and I'm not sure if leaving out the types could cause problems on platforms where an int and a char** aren't of the same size. -Christian
author Ryan C. Gordon <icculus@icculus.org>
date Sun, 01 Jan 2006 23:45:52 +0000
parents b8d311d90021
children c9b51268668f
line wrap: on
line source

/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2004 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
*/

#ifdef SAVE_RCSID
static char rcsid =
 "@(#) $Id$";
#endif

/* An implementation of semaphores using mutexes and condition variables */

#include <stdlib.h>

#include "SDL_error.h"
#include "SDL_timer.h"
#include "SDL_thread.h"
#include "SDL_systhread_c.h"


#ifdef DISABLE_THREADS

SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
	SDL_SetError("SDL not configured with thread support");
	return (SDL_sem *)0;
}

void SDL_DestroySemaphore(SDL_sem *sem)
{
	return;
}

int SDL_SemTryWait(SDL_sem *sem)
{
	SDL_SetError("SDL not configured with thread support");
	return -1;
}

int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	SDL_SetError("SDL not configured with thread support");
	return -1;
}

int SDL_SemWait(SDL_sem *sem)
{
	SDL_SetError("SDL not configured with thread support");
	return -1;
}

Uint32 SDL_SemValue(SDL_sem *sem)
{
	return 0;
}

int SDL_SemPost(SDL_sem *sem)
{
	SDL_SetError("SDL not configured with thread support");
	return -1;
}

#else

struct SDL_semaphore
{
	Uint32 count;
	Uint32 waiters_count;
	SDL_mutex *count_lock;
	SDL_cond *count_nonzero;
};

SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
	SDL_sem *sem;

	sem = (SDL_sem *)malloc(sizeof(*sem));
	if ( ! sem ) {
		SDL_OutOfMemory();
		return(0);
	}
	sem->count = initial_value;
	sem->waiters_count = 0;

	sem->count_lock = SDL_CreateMutex();
	sem->count_nonzero = SDL_CreateCond();
	if ( ! sem->count_lock || ! sem->count_nonzero ) {
		SDL_DestroySemaphore(sem);
		return(0);
	}

	return(sem);
}

/* WARNING:
   You cannot call this function when another thread is using the semaphore.
*/
void SDL_DestroySemaphore(SDL_sem *sem)
{
	if ( sem ) {
		sem->count = 0xFFFFFFFF;
		while ( sem->waiters_count > 0) {
			SDL_CondSignal(sem->count_nonzero);
			SDL_Delay(10);
		}
		SDL_DestroyCond(sem->count_nonzero);
		SDL_mutexP(sem->count_lock);
		SDL_mutexV(sem->count_lock);
		SDL_DestroyMutex(sem->count_lock);
		free(sem);
	}
}

int SDL_SemTryWait(SDL_sem *sem)
{
	int retval;

	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	retval = SDL_MUTEX_TIMEDOUT;
	SDL_LockMutex(sem->count_lock);
	if ( sem->count > 0 ) {
		--sem->count;
		retval = 0;
	}
	SDL_UnlockMutex(sem->count_lock);

	return retval;
}

int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	int retval;

	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	/* A timeout of 0 is an easy case */
	if ( timeout == 0 ) {
		return SDL_SemTryWait(sem);
	}

	SDL_LockMutex(sem->count_lock);
	++sem->waiters_count;
	retval = 0;
	while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
		retval = SDL_CondWaitTimeout(sem->count_nonzero,
		                             sem->count_lock, timeout);
	}
	--sem->waiters_count;
	--sem->count;
	SDL_UnlockMutex(sem->count_lock);

	return retval;
}

int SDL_SemWait(SDL_sem *sem)
{
	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}

Uint32 SDL_SemValue(SDL_sem *sem)
{
	Uint32 value;
	
	value = 0;
	if ( sem ) {
		SDL_LockMutex(sem->count_lock);
		value = sem->count;
		SDL_UnlockMutex(sem->count_lock);
	}
	return value;
}

int SDL_SemPost(SDL_sem *sem)
{
	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	SDL_LockMutex(sem->count_lock);
	if ( sem->waiters_count > 0 ) {
		SDL_CondSignal(sem->count_nonzero);
	}
	++sem->count;
	SDL_UnlockMutex(sem->count_lock);

	return 0;
}

#endif /* DISABLE_THREADS */