From 742c6f32e038c90967e15f4740fcdacda1ad0f1f Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Thu, 7 Feb 2008 23:11:34 +0100 Subject: Objective-C layer: Implement locking using semaphores. darcs-hash:3a1f9d1f6597b32c20efcd7ab2cf2721c1bdfe43 --- Objective-C/libobjcl.h | 15 ++++++++++++++ Objective-C/libobjcl.m | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 2 ++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/Objective-C/libobjcl.h b/Objective-C/libobjcl.h index 270af45..afe9f56 100644 --- a/Objective-C/libobjcl.h +++ b/Objective-C/libobjcl.h @@ -43,6 +43,18 @@ typedef Ivar IVAR_T; typedef struct objc_ivar *IVAR_T; #endif +#ifdef HAVE_SYS_SEM_H +#include +/* According to the Single Unix Specification, Version 3, the semun + union type must be defined by the application writer as follows: */ +union semun +{ + int val; /* Value for SETVAL */ + struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ + unsigned short *array; /* Array for GETALL, SETALL */ +}; +#endif + extern NSException *objcl_oom_exception; extern id objcl_current_exception; extern void *objcl_current_exception_lock; @@ -159,3 +171,6 @@ objcl_acquire_lock (void *lock); void objcl_release_lock (void *lock); + +void +objcl_initialise_lock (void **lock); diff --git a/Objective-C/libobjcl.m b/Objective-C/libobjcl.m index 3cbf3e5..3242fcf 100644 --- a/Objective-C/libobjcl.m +++ b/Objective-C/libobjcl.m @@ -65,6 +65,8 @@ objcl_initialise_runtime (void) #ifdef __NEXT_RUNTIME__ PyObjC_SetupRuntimeCompat (); #endif + + objcl_initialise_lock (&objcl_current_exception_lock); } @@ -558,15 +560,62 @@ objcl_create_imp (IMP callback, } +void +objcl_initialise_lock (void **lock) +{ +#ifdef HAVE_SYS_SEM_H + int sem; + union semun initop; + + sem = semget (IPC_PRIVATE, 1, IPC_CREAT | 0600); + *lock = malloc (sizeof (int)); + *((int *) *lock) = sem; + + initop.val = 1; + semctl (sem, 0, SETVAL, initop); +#else +#warning "I do not know how to do locking on this platform." +#endif +} + + void objcl_acquire_lock (void *lock) { -#warning "FIXME" +#ifdef HAVE_SYS_SEM_H + struct sembuf op; + op.sem_num = 0; op.sem_op = +1; op.sem_flg = 0; + + if ((semop (*((int *) lock), &op, 1)) < 0) + { + [[NSException exceptionWithName: @"MLKLockLossage" + reason: @"Acquiring the exception lock failed (don't ask me why)." + userInfo: nil] raise]; + } + + TRACE (@"Exception buffer locked."); +#else +#warning "I do not know how to do locking on this platform." +#endif } void objcl_release_lock (void *lock) { -#warning "FIXME" +#ifdef HAVE_SYS_SEM_H + struct sembuf op; + op.sem_num = 0; op.sem_op = +1; op.sem_flg = 0; + + if ((semop (*((int *) lock), &op, 1)) < 0) + { + [[NSException exceptionWithName: @"MLKLockLossage" + reason: @"Acquiring the exception lock failed (don't ask me why)." + userInfo: nil] raise]; + } + + TRACE (@"Exception buffer unlocked."); +#else +#warning "I do not know how to do locking on this platform." +#endif } diff --git a/configure.ac b/configure.ac index 9ea32af..1a2b245 100644 --- a/configure.ac +++ b/configure.ac @@ -31,6 +31,8 @@ if test x$HAVE_LIBFFI = x1; then AC_CHECK_HEADERS([ffi.h ffi/ffi.h], [HAVE_ANY_FFI_H=1; break]) fi +AC_CHECK_HEADERS([sys/sem.h]) + AC_SUBST(HAVE_ANY_FFI_H) AC_SUBST(HAVE_LIBFFI) AC_CONFIG_HEADERS([config.h]) -- cgit v1.2.3