mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
* 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:
parent
abc7709a49
commit
7c202de0d1
5 changed files with 162 additions and 2 deletions
16
ChangeLog
16
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue