[SDL] What are threads allowed to do?

Bob Pendleton bob at pendleton.com
Mon Jan 24 14:30:53 PST 2005


You might want to repost your patch in a message with a title that says
there is a patch in it. This is the kind of thing that Sam needs to
looks at.

BTW, moving from 16 bit unicode to 32 bit unicode is on the wish list
for version 1.3 or later.

		Bob Pendleton

On Mon, 2005-01-24 at 16:46 -0500, Albert Cahalan wrote:
> On Mon, 2005-01-24 at 12:40 -0500, Albert Cahalan wrote:
> > On Mon, 2005-01-24 at 09:03 -0600, Bob Pendleton wrote:
> 
> > > What does that mean to an SDL programmer? It means that you can have 10
> > > threads reading 10 files, but only one thread can be decoding a ttf font
> > > at a time.
> > 
> > This is awful. I looked over libSDL_ttf and didn't find anything
> > significant. What did I miss? I saw:
> > 
> > a. error text might get corrupted (but no crash)
> > b. can't do simultaneous TTF_Init() calls (no problem)
> > 
> > Regarding #a, note that libSDL_ttf does not pass '%'
> > in error strings. So the unsafe vararg stuff in SDL's
> > error handling would not be involved.
> 
> Found it!
> 
> FreeType keeps a buffer around to fast scan line conversion.
> This buffer is not static within FreeType, so FreeType itself
> is thread-safe. The buffer must be in the FT_Library struct or
> hanging off it. The libSDL_ttf code shares this struct with
> all fonts that it opens.
> 
> I'm including a patch (not tested) that should improve the
> situation greatly. Please apply it. Please also be sure to
> fully document the remaining problems. I think they are:
> 
> a. SDL error messages might get messed up
> b. the byteswap setting is obviously global
> c. each thread will need a private TTF_Font
> 
> (in the man pages, the wiki pages, the info pages...)
> 
> BTW, the wide character handling is kind of broken anyway.
> Full Unicode version 2.x requires 32-bit characters.
> The early-adopter systems using 16-bit have had to switch
> to the nasty UTF-16 encoding. Perhaps all the 16-bit stuff
> should just be removed. The gcc compiler provides some help;
> you can put __attribute__((deprecated)) in a header file to
> warn users about the obsolete interface.
> 
> Anyway, here's the patch:
> 
> ////////////////////////////////////////////////////////////////////////
> diff -Naurd old/SDL_ttf.c new/SDL_ttf.c
> --- old/SDL_ttf.c	2005-01-24 16:11:26.000000000 -0500
> +++ new/SDL_ttf.c	2005-01-24 16:28:21.000000000 -0500
> @@ -90,6 +90,7 @@
>  struct _TTF_Font {
>  	/* Freetype2 maintains all sorts of useful info itself */
>  	FT_Face face;
> +	FT_Library library;
>  
>  	/* We'll cache these ourselves */
>  	int height;
> @@ -122,10 +123,7 @@
>  	int font_size_family;
>  };
>  
> -/* The FreeType font engine/library */
> -static FT_Library library;
> -static int TTF_initialized = 0;
> -static int TTF_byteswapped = 0;
> +static int TTF_byteswapped;
>  
>  /* UNICODE string utilities */
>  static __inline__ int UNICODE_strlen(const Uint16 *text)
> @@ -205,21 +203,10 @@
>  #endif /* USE_FREETYPE_ERRORS */
>  }
>  
> +/* this exists only to maintain the ABI */
>  int TTF_Init( void )
>  {
> -	int status = 0;
> -
> -	if ( ! TTF_initialized ) {
> -		FT_Error error = FT_Init_FreeType( &library );
> -		if ( error ) {
> -			TTF_SetFTError("Couldn't init FreeType engine", error);
> -			status = -1;
> -		}
> -	}
> -	if ( status == 0 ) {
> -		++TTF_initialized;
> -	}
> -	return status;
> +	return 0;
>  }
>  
>  static unsigned long RWread(
> @@ -245,11 +232,6 @@
>  	FT_Stream stream;
>  	int position;
>  
> -	if ( ! TTF_initialized ) {
> -		TTF_SetError( "Library not initialized" );
> -		return NULL;
> -	}
> -
>  	/* Check to make sure we can seek in this stream */
>  	position = SDL_RWtell(src);
>  	if ( position < 0 ) {
> @@ -267,6 +249,13 @@
>  	font->src = src;
>  	font->freesrc = freesrc;
>  
> +	FT_Error error = FT_Init_FreeType( &font->library );
> +	if ( error ) {
> +		TTF_SetFTError("Couldn't init FreeType engine", error);
> +		free( font );
> +		return NULL;
> +	}
> +
>  	stream = (FT_Stream)malloc(sizeof(*stream));
>  	if ( stream == NULL ) {
>  		TTF_SetError( "Out of memory" );
> @@ -275,7 +264,7 @@
>  	}
>  	memset(stream, 0, sizeof(*stream));
>  
> -	stream->memory = library->memory;
> +	stream->memory = font->library->memory;
>  	stream->read = RWread;
>  	stream->descriptor.pointer = src;
>  	stream->pos = (unsigned long)position;
> @@ -286,7 +275,7 @@
>  	font->args.flags = FT_OPEN_STREAM;
>  	font->args.stream = stream;
>  
> -	error = FT_Open_Face( library, &font->args, index, &font->face );
> +	error = FT_Open_Face( font->library, &font->args, index, &font->face );
>  	if( error ) {
>  		TTF_SetFTError( "Couldn't load font file", error );
>  		TTF_CloseFont( font );
> @@ -668,6 +657,7 @@
>  	if ( font->freesrc ) {
>  		SDL_RWclose( font->src );
>  	}
> +	FT_Done_FreeType( font->library );
>  	free( font );
>  }
>  
> @@ -849,10 +839,6 @@
>  	FT_UInt prev_index = 0;
>  
>  	/* Initialize everything to 0 */
> -	if ( ! TTF_initialized ) {
> -		TTF_SetError( "Library not initialized" );
> -		return -1;
> -	}
>  	status = 0;
>  	minx = maxx = 0;
>  	miny = maxy = 0;
> @@ -1735,14 +1721,10 @@
>  
>  void TTF_Quit( void )
>  {
> -	if ( TTF_initialized ) {
> -		if ( --TTF_initialized == 0 ) {
> -			FT_Done_FreeType( library );
> -		}
> -	}
> +	return;
>  }
>  
>  int TTF_WasInit( void )
>  {
> -	return TTF_initialized;
> +	return 1;  // this is a don't-care value to satisfy the ABI
>  }
> 
> ////////////////////////////////////////////////////////////////////////
> 
> 
> 
> _______________________________________________
> SDL mailing list
> SDL at libsdl.org
> http://www.libsdl.org/mailman/listinfo/sdl
> 





More information about the SDL mailing list