Index: TODO ================================================================== --- TODO +++ TODO @@ -1,9 +1,8 @@ Test if autorelease pool releases everything correctly when thread is ended Proper UTF-8 support! -Tests for OFArray. Tests for OFFile. Tests for OFNumber. Tests for readLine:. Serialization Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -158,10 +158,11 @@ AC_CHECK_HEADER(objc/runtime.h, [AC_DEFINE(HAVE_OBJC_RUNTIME_H, 1, [Whether we have objc/runtime.h])]) AC_CHECK_FUNC(objc_sync_enter,, [ + AC_SUBST(OBJC_SYNC, "objc_sync") AC_SUBST(OBJC_SYNC_M, "objc_sync.m") AC_DEFINE(NEED_OBJC_SYNC_INIT, 1, [Whether objc_sync_init needs to be called])]) test x"$GCC" = x"yes" && CFLAGS="$CFLAGS -Werror" Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -1,7 +1,8 @@ ASPRINTF_C = @ASPRINTF_C@ +OBJC_SYNC = @OBJC_SYNC@ OBJC_SYNC_M = @OBJC_SYNC_M@ OFPLUGIN = @OFPLUGIN@ OFPLUGIN_M = @OFPLUGIN_M@ WS2_LIBS = @WS2_LIBS@ TESTS = @TESTS@ TEST_LAUNCHER = @TEST_LAUNCHER@ Index: src/objc_sync.m ================================================================== --- src/objc_sync.m +++ src/objc_sync.m @@ -129,19 +129,19 @@ } int objc_sync_enter(id obj) { - size_t i; + int i; if (obj == nil) return 0; if (!mutex_lock(&mutex)) return 1; - for (i = 0; i < num_locks; i++) { + for (i = num_locks - 1; i >= 0; i--) { if (locks[i].obj == obj) { if (thread_is_current(locks[i].thread)) locks[i].recursion++; else { /* Make sure objc_sync_exit doesn't free it */ @@ -213,19 +213,19 @@ } int objc_sync_exit(id obj) { - size_t i; + int i; if (obj == nil) return 0; if (!mutex_lock(&mutex)) return 1; - for (i = 0; i < num_locks; i++) { + for (i = num_locks - 1; i >= 0; i--) { if (locks[i].obj == obj) { if (locks[i].recursion > 0 && thread_is_current(locks[i].thread)) { locks[i].recursion--; Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -9,8 +9,9 @@ ${OFPLUGIN} \ OFString \ OFTCPSocket \ OFThread \ OFList \ - OFXMLFactory + OFXMLFactory \ + ${OBJC_SYNC} include ../buildsys.mk ADDED tests/objc_sync/Makefile Index: tests/objc_sync/Makefile ================================================================== --- tests/objc_sync/Makefile +++ tests/objc_sync/Makefile @@ -0,0 +1,25 @@ +PROG_NOINST = objc_sync${PROG_SUFFIX} +SRCS = objc_sync.m + +include ../../buildsys.mk +include ../../extra.mk + +CPPFLAGS += -I../../src -I../.. +LIBS := -L../../src -lobjfw ${LIBS} + +.PHONY: run + +all: run +run: ${PROG_NOINST} + rm -f libobjfw.so.0 libobjfw.so.0.1 libobjfw.dll libobjfw.dylib + ln -s ../../src/libobjfw.so libobjfw.so.0 + ln -s ../../src/libobjfw.so libobjfw.so.0.1 + if test -f ../../src/libobjfw.dll; then \ + ln ../../src/libobjfw.dll libobjfw.dll; \ + fi + ln -s ../../src/libobjfw.dylib libobjfw.dylib + LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ + DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ + ${TEST_LAUNCHER} ./${PROG_NOINST}; EXIT=$$?; \ + rm -f libobjfw.so.0 libobjfw.so.0.1 libobjfw.dll libobjfw.dylib; \ + exit $$EXIT ADDED tests/objc_sync/objc_sync.m Index: tests/objc_sync/objc_sync.m ================================================================== --- tests/objc_sync/objc_sync.m +++ tests/objc_sync/objc_sync.m @@ -0,0 +1,40 @@ +#include + +#import "OFString.h" +#import "OFThread.h" + +OFObject *lock; + +@interface MyThread: OFThread +- main; +@end + +@implementation MyThread +- main +{ + printf("[%s] Entering #1\n", [object cString]); + @synchronized (lock) { + printf("[%s] Entering #2\n", [object cString]); + @synchronized (lock) { + printf("[%s] Hello!\n", [object cString]); + } + printf("[%s] Left #2\n", [object cString]); + } + printf("[%s] Left #1\n", [object cString]); + + return nil; +} +@end + +int +main() +{ + lock = [[OFObject alloc] init]; + MyThread *t1 = [MyThread threadWithObject: @"A"]; + MyThread *t2 = [MyThread threadWithObject: @"B"]; + + [t1 join]; + [t2 join]; + + return 0; +}