* Headers/Additions/GNUstepBase/GSObjCRuntime.h/m

(GSAllocateMutexAt): New function.
        (_GSObjCRuntimeInitializer): Define local support class.

        * Headers/Additions/GNUstepBase/objc-gnu2next.h: Fixed minor
        whitespace issues.
        (objc_mutex_t, objc_mutex_allocate, objc_mutex_deallocate)
        (objc_mutex_lock, objc_mutex_unlock, objc_mutex_trylock):
        Declare
        for the NeXT runtime.
        * Source/Additions/GSNextRuntime.m
        (objc_mutex_allocate, objc_mutex_deallocate)
        (objc_mutex_lock, objc_mutex_unlock, objc_mutex_trylock):
        Implement for NeXT runtime.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19249 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Ayers 2004-05-06 15:25:01 +00:00
parent abc7709a49
commit 7c202de0d1
5 changed files with 162 additions and 2 deletions

View file

@ -1,3 +1,19 @@
2004-05-06 David Ayers <d.ayers@inode.at>
* Headers/Additions/GNUstepBase/GSObjCRuntime.h/m
(GSAllocateMutexAt): New function.
(_GSObjCRuntimeInitializer): Define local support class.
* Headers/Additions/GNUstepBase/objc-gnu2next.h: Fixed minor
whitespace issues.
(objc_mutex_t, objc_mutex_allocate, objc_mutex_deallocate)
(objc_mutex_lock, objc_mutex_unlock, objc_mutex_trylock): Declare
for the NeXT runtime.
* Source/Additions/GSNextRuntime.m
(objc_mutex_allocate, objc_mutex_deallocate)
(objc_mutex_lock, objc_mutex_unlock, objc_mutex_trylock):
Implement for NeXT runtime.
2004-05-06 Mateu Batle
* Tools/gdomap.c: mingw fixes.

View file

@ -468,6 +468,31 @@ GSObjCZone(NSObject *obj);
GS_EXPORT void *
GSAutoreleasedBuffer(unsigned size);
/**
* Allocate a new objc_mutex_t and store it in the location
* pointed to by request. A mutex is only created if the value
* pointed to by request is NULL. This function is thread safe
* in the sense that multiple threads my call this function with the same
* value of request and only one will actually set the mutex.
* It is the users responsibility that no one else attempts to set
* the mutex pointed to. This function should be
* used with objc_mutex_t variables which were statically initialized
* to NULL like:
* <example>
* void function (void)
* {
* static objc_mutex_t my_lock = NULL;
* if (my_lock == NULL)
* GSAllocateMutexAt(&my_lock);
* objc_mutex_lock(my_lock);
* do_work ();
* objc_mutex_unlock(my_lock);
* }
* </example>
*/
GS_EXPORT void
GSAllocateMutexAt(objc_mutex_t *request);
/** Returns a system error message on a variety of systems
*/
GS_EXPORT const char *

View file

@ -36,8 +36,8 @@
#include <ctype.h>
#include <stdio.h>
/* Disable builtin functions for gcc < 3.x since it triggers a bad bug (even some 3.x versions may have this
bug) */
/* Disable builtin functions for gcc < 3.x since it triggers a bad bug
(even some 3.x versions may have this bug). */
#if __GNUC__ < 3
#define __builtin_apply(a,b,c) 0
#define __builtin_apply_args() 0
@ -192,6 +192,16 @@ extern void *(*_objc_realloc)(void *, size_t);
extern void *(*_objc_calloc)(size_t, size_t);
extern void (*_objc_free)(void *);
/* threading functions */
typedef void *objc_mutex_t;
objc_mutex_t objc_mutex_allocate (void);
int objc_mutex_deallocate (objc_mutex_t mutex);
int objc_mutex_lock (objc_mutex_t mutex);
int objc_mutex_unlock (objc_mutex_t mutex);
int objc_mutex_trylock (objc_mutex_t mutex);
/* encoding functions */
extern int objc_sizeof_type(const char* type);
extern int objc_alignof_type(const char* type);

View file

@ -593,3 +593,59 @@ objc_set_error_handler(objc_error_handler func)
return temp;
}
/*
* Functions for threading support.
*/
/* This currently assumes that the NeXT Runtime is using pthreads
as the underlying thread support. This is true for 'modern' NeXT
Runtime implementations but it may not be for older versions. */
#include <pthread.h>
objc_mutex_t
objc_mutex_allocate(void)
{
pthread_mutex_t *p;
p = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
if (pthread_mutex_init(p, NULL) != 0)
{
abort();
}
return (objc_mutex_t)p;
}
int
objc_mutex_deallocate(objc_mutex_t mutex)
{
int ret;
pthread_mutex_t *p = (pthread_mutex_t *)mutex;
ret = pthread_mutex_destroy(p);
if (ret == 0)
{
free(p);
}
return ret;
}
int
objc_mutex_lock(objc_mutex_t mutex)
{
pthread_mutex_t *p = (pthread_mutex_t *)mutex;
return pthread_mutex_lock(p);
}
int
objc_mutex_unlock (objc_mutex_t mutex)
{
pthread_mutex_t *p = (pthread_mutex_t *)mutex;
return pthread_mutex_unlock(p);
}
int
objc_mutex_trylock (objc_mutex_t mutex)
{
pthread_mutex_t *p = (pthread_mutex_t *)mutex;
return pthread_mutex_trylock(p);
}

View file

@ -59,6 +59,59 @@
@end
#endif
static objc_mutex_t local_lock = NULL;
/* This class it intended soley for thread safe / +load safe
initialization of the local lock.
It's a root class so it won't trigger the initialization
of any other class. */
@interface _GSObjCRuntimeInitializer /* Root Class */
{
Class isa;
}
+ (Class)class;
@end
@implementation _GSObjCRuntimeInitializer
+ (void)initialize
{
if (local_lock == NULL)
{
local_lock = objc_mutex_allocate();
}
}
+ (Class)class
{
return self;
}
@end
void
GSAllocateMutexAt(objc_mutex_t *request)
{
if (request == NULL)
{
/* This could be called very early in process
initialization so many things may not have
been setup correctly yet. */
fprintf(stderr,
"Error: GSAllocateMutexAt() called with NULL pointer.\n");
abort();
}
if (local_lock == NULL)
{
/* Initialize in a thread safe way. */
[_GSObjCRuntimeInitializer class];
}
objc_mutex_lock(local_lock);
if (*request == NULL)
{
*request = objc_mutex_allocate();
}
objc_mutex_unlock(local_lock);
}
/** Deprecated ... use GSObjCFindVariable() */
BOOL
GSFindInstanceVariable(id obj, const char *name,