summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Benkard <code@mail.matthias.benkard.de>2008-02-07 23:11:34 +0100
committerMatthias Benkard <code@mail.matthias.benkard.de>2008-02-07 23:11:34 +0100
commit742c6f32e038c90967e15f4740fcdacda1ad0f1f (patch)
treea9ec7095d62dcdfcd0b6f49d7d5a128f5ba0dbf1
parent0659e7a29136823cba53c05fa94df2db29a3ddbc (diff)
Objective-C layer: Implement locking using semaphores.
darcs-hash:3a1f9d1f6597b32c20efcd7ab2cf2721c1bdfe43
-rw-r--r--Objective-C/libobjcl.h15
-rw-r--r--Objective-C/libobjcl.m53
-rw-r--r--configure.ac2
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 <sys/sem.h>
+/* 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);
}
@@ -559,14 +561,61 @@ 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])