ObjFW  Check-in [b8ce2359f3]

Overview
Comment:Clean up the feature #ifdef mess.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b8ce2359f3f2f48ad55787a44fac264d042433094b75802ec6192fb031748280
User & Date: js on 2013-01-12 20:53:54
Other Links: manifest | tags
Context
2013-01-13
00:54
OFTCPSocket: Define AI_* to 0 if missing. check-in: 5c6bc745b5 user: js tags: trunk
2013-01-12
20:53
Clean up the feature #ifdef mess. check-in: b8ce2359f3 user: js tags: trunk
20:32
Fix code used when atomic ops are unavailable. check-in: 20aea410be user: js tags: trunk
Changes

Modified Doxyfile from [295329e516] to [594baeb063].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PROJECT_NAME = "ObjFW"
OUTPUT_DIRECTORY = docs/
INPUT = src src/exceptions
FILE_PATTERNS = *.h *.m
HTML_OUTPUT = .
GENERATE_LATEX = NO
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = YES
PREDEFINED = OF_HAVE_PROPERTIES		\
	     OF_HAVE_BLOCKS		\
	     OF_THREADS			\
	     OF_SENTINEL		\
	     OF_RETURNS_RETAINED	\
	     OF_RETURNS_NOT_RETAINED	\
	     OF_RETURNS_INNER_POINTER	\
	     OF_CONSUMED		\
	     OF_WEAK_UNAVAILABLE
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
IGNORE_PREFIX = OF of_










|









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PROJECT_NAME = "ObjFW"
OUTPUT_DIRECTORY = docs/
INPUT = src src/exceptions
FILE_PATTERNS = *.h *.m
HTML_OUTPUT = .
GENERATE_LATEX = NO
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = YES
PREDEFINED = OF_HAVE_PROPERTIES		\
	     OF_HAVE_BLOCKS		\
	     OF_HAVE_THREADS		\
	     OF_SENTINEL		\
	     OF_RETURNS_RETAINED	\
	     OF_RETURNS_NOT_RETAINED	\
	     OF_RETURNS_INNER_POINTER	\
	     OF_CONSUMED		\
	     OF_WEAK_UNAVAILABLE
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
IGNORE_PREFIX = OF of_

Modified configure.ac from [d7fb42e5f4] to [ab8f1d8c4e].

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
	AC_SUBST(EXCEPTIONS_EXCEPTIONS_A, "exceptions/exceptions.a")
])

AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins])
AS_IF([test x"$PLUGIN_SUFFIX" != x""], [
	AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}')
	AC_SUBST(TESTPLUGIN, "plugin")
	AC_DEFINE(OF_PLUGINS, 1, [Whether we have plugin support])
])

objc_runtime="ObjFW runtime"
AC_CHECK_HEADER(objc/objc.h)
AC_MSG_CHECKING(which Objective C runtime to use)
AC_ARG_ENABLE(runtime,
	AS_HELP_STRING([--enable-runtime], [use the included runtime]))







|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
	AC_SUBST(EXCEPTIONS_EXCEPTIONS_A, "exceptions/exceptions.a")
])

AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins])
AS_IF([test x"$PLUGIN_SUFFIX" != x""], [
	AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}')
	AC_SUBST(TESTPLUGIN, "plugin")
	AC_DEFINE(OF_HAVE_PLUGINS, 1, [Whether we have plugin support])
])

objc_runtime="ObjFW runtime"
AC_CHECK_HEADER(objc/objc.h)
AC_MSG_CHECKING(which Objective C runtime to use)
AC_ARG_ENABLE(runtime,
	AS_HELP_STRING([--enable-runtime], [use the included runtime]))
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
	])
	AC_MSG_RESULT($ac_cv_snprintf_useful_ret)
])
test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \
	AC_MSG_ERROR(No asprintf and no snprintf returning required space!)

AC_CHECK_FUNC(arc4random, [
	AC_DEFINE(OF_HAVE_ARC4RANDOM, 1, [Whether we have arc4random()])
], [
	AC_CHECK_FUNC(random, [
		AC_DEFINE(OF_HAVE_RANDOM, 1, [Whether we have random()])
	])
])

AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")

AC_ARG_ENABLE(threads,
	AS_HELP_STRING([--disable-threads], [disable thread support]))







|


|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
	])
	AC_MSG_RESULT($ac_cv_snprintf_useful_ret)
])
test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \
	AC_MSG_ERROR(No asprintf and no snprintf returning required space!)

AC_CHECK_FUNC(arc4random, [
	AC_DEFINE(HAVE_ARC4RANDOM, 1, [Whether we have arc4random()])
], [
	AC_CHECK_FUNC(random, [
		AC_DEFINE(HAVE_RANDOM, 1, [Whether we have random()])
	])
])

AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")

AC_ARG_ENABLE(threads,
	AS_HELP_STRING([--disable-threads], [disable thread support]))
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
			])
		], [
			AC_MSG_ERROR(No supported threads found!)
		])
		;;
	esac

	AC_DEFINE(OF_THREADS, 1, [Whether we have threads])
	AC_SUBST(USE_SRCS_THREADS, '${SRCS_THREADS}')
	AC_SUBST(USE_INCLUDES_THREADS, '${INCLUDES_THREADS}')

	AC_MSG_CHECKING(whether __thread works)
	AC_TRY_LINK([
		/* It seems __thread is buggy with GCC 4.1 */
		#if __GNUC__ == 4 && __GNUC_MINOR__ < 2
		# error buggy
		#endif

		__thread int x = 0;
	], [
		x++;
	], [
		AC_MSG_RESULT(yes)
		AC_DEFINE(OF_COMPILER_TLS, 1, [Whether __thread works])
	], [
		AC_MSG_RESULT(no)
	])

	atomic_ops="none"

	AC_MSG_CHECKING(whether we have an atomic ops assembly implementation)







|















|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
			])
		], [
			AC_MSG_ERROR(No supported threads found!)
		])
		;;
	esac

	AC_DEFINE(OF_HAVE_THREADS, 1, [Whether we have threads])
	AC_SUBST(USE_SRCS_THREADS, '${SRCS_THREADS}')
	AC_SUBST(USE_INCLUDES_THREADS, '${INCLUDES_THREADS}')

	AC_MSG_CHECKING(whether __thread works)
	AC_TRY_LINK([
		/* It seems __thread is buggy with GCC 4.1 */
		#if __GNUC__ == 4 && __GNUC_MINOR__ < 2
		# error buggy
		#endif

		__thread int x = 0;
	], [
		x++;
	], [
		AC_MSG_RESULT(yes)
		AC_DEFINE(OF_HAVE_COMPILER_TLS, 1, [Whether __thread works])
	], [
		AC_MSG_RESULT(no)
	])

	atomic_ops="none"

	AC_MSG_CHECKING(whether we have an atomic ops assembly implementation)
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
], [
	dnl We can only have one thread - therefore everything is atomic
	atomic_ops="not needed"
])

AC_MSG_CHECKING(for atomic operations)
AS_IF([test x"$atomic_ops" != x"none"], [
	AC_DEFINE(OF_ATOMIC_OPS, 1, [Whether we have atomic operations])
	AC_SUBST(ATOMIC_H, "atomic.h")
])
AC_MSG_RESULT($atomic_ops)

AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket")
AC_CHECK_LIB(network, socket, LIBS="$LIBS -lnetwork")
AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32")







|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
], [
	dnl We can only have one thread - therefore everything is atomic
	atomic_ops="not needed"
])

AC_MSG_CHECKING(for atomic operations)
AS_IF([test x"$atomic_ops" != x"none"], [
	AC_DEFINE(OF_HAVE_ATOMIC_OPS, 1, [Whether we have atomic operations])
	AC_SUBST(ATOMIC_H, "atomic.h")
])
AC_MSG_RESULT($atomic_ops)

AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket")
AC_CHECK_LIB(network, socket, LIBS="$LIBS -lnetwork")
AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32")
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
	AC_SUBST(OFSTREAMOBSERVER_KQUEUE_M, "OFStreamObserver_kqueue.m")
])
AC_CHECK_HEADER(poll.h, [
	AC_DEFINE(HAVE_POLL_H, 1, [Whether we have poll.h])
	AC_SUBST(OFSTREAMOBSERVER_POLL_M, "OFStreamObserver_poll.m")
])
AC_CHECK_HEADERS(sys/select.h, [
	AC_DEFINE(OF_HAVE_SYS_SELECT_H, 1, [Whether we have sys/select.h])
	AC_SUBST(OFSTREAMOBSERVER_SELECT_M, "OFStreamObserver_select.m")
])
case "$host_os" in
	mingw*)
		AC_SUBST(OFSTREAMOBSERVER_SELECT_M,
			"OFStreamObserver_select.m")
		;;







|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
	AC_SUBST(OFSTREAMOBSERVER_KQUEUE_M, "OFStreamObserver_kqueue.m")
])
AC_CHECK_HEADER(poll.h, [
	AC_DEFINE(HAVE_POLL_H, 1, [Whether we have poll.h])
	AC_SUBST(OFSTREAMOBSERVER_POLL_M, "OFStreamObserver_poll.m")
])
AC_CHECK_HEADERS(sys/select.h, [
	AC_DEFINE(HAVE_SYS_SELECT_H, 1, [Whether we have sys/select.h])
	AC_SUBST(OFSTREAMOBSERVER_SELECT_M, "OFStreamObserver_select.m")
])
case "$host_os" in
	mingw*)
		AC_SUBST(OFSTREAMOBSERVER_SELECT_M,
			"OFStreamObserver_select.m")
		;;

Modified src/OFApplication.m from [9620cd4f32] to [af4f6fe02e].

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

#include <signal.h>

#import "OFApplication.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFDictionary.h"
#ifdef OF_THREADS
# import "OFThread.h"
#endif
#import "OFRunLoop.h"

#import "autorelease.h"
#import "macros.h"








|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

#include <signal.h>

#import "OFApplication.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_THREADS
# import "OFThread.h"
#endif
#import "OFRunLoop.h"

#import "autorelease.h"
#import "macros.h"

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
}

- (void)run
{
	void *pool = objc_autoreleasePoolPush();
	OFRunLoop *runLoop;

#ifdef OF_THREADS
	[OFThread OF_createMainThread];
	runLoop = [OFRunLoop currentRunLoop];
#else
	runLoop = [[[OFRunLoop alloc] init] autorelease];
#endif

	[OFRunLoop OF_setMainRunLoop: runLoop];







|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
}

- (void)run
{
	void *pool = objc_autoreleasePoolPush();
	OFRunLoop *runLoop;

#ifdef OF_HAVE_THREADS
	[OFThread OF_createMainThread];
	runLoop = [OFRunLoop currentRunLoop];
#else
	runLoop = [[[OFRunLoop alloc] init] autorelease];
#endif

	[OFRunLoop OF_setMainRunLoop: runLoop];

Modified src/OFAutoreleasePool.m from [5c43e2c904] to [b51231d742].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

#include <stdlib.h>

#import "OFAutoreleasePool.h"
#import "OFArray.h"

#import "macros.h"
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
# import "threading.h"

# import "OFInitializationFailedException.h"
#endif

#import "autorelease.h"

#define MAX_CACHE_SIZE 0x20

#if defined(OF_COMPILER_TLS)
static __thread OFAutoreleasePool **cache = NULL;
#elif defined(OF_THREADS)
static of_tlskey_t cacheKey;
#else
static OFAutoreleasePool **cache = NULL;
#endif

@implementation OFAutoreleasePool
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
+ (void)initialize
{
	if (self != [OFAutoreleasePool class])
		return;

	if (!of_tlskey_new(&cacheKey))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}
#endif

+ alloc
{
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif

	if (cache != NULL) {
		unsigned i;

		for (i = 0; i < MAX_CACHE_SIZE; i++) {







|









|

|






|













|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

#include <stdlib.h>

#import "OFAutoreleasePool.h"
#import "OFArray.h"

#import "macros.h"
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
# import "threading.h"

# import "OFInitializationFailedException.h"
#endif

#import "autorelease.h"

#define MAX_CACHE_SIZE 0x20

#if defined(OF_HAVE_COMPILER_TLS)
static __thread OFAutoreleasePool **cache = NULL;
#elif defined(OF_HAVE_THREADS)
static of_tlskey_t cacheKey;
#else
static OFAutoreleasePool **cache = NULL;
#endif

@implementation OFAutoreleasePool
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
+ (void)initialize
{
	if (self != [OFAutoreleasePool class])
		return;

	if (!of_tlskey_new(&cacheKey))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}
#endif

+ alloc
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif

	if (cache != NULL) {
		unsigned i;

		for (i = 0; i < MAX_CACHE_SIZE; i++) {
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
- (void)drain
{
	[self dealloc];
}

- (void)dealloc
{
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif

	if (ignoreRelease)
		return;

	ignoreRelease = YES;

	objc_autoreleasePoolPop(pool);

	if (cache == NULL) {
		cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
		if (!of_tlskey_set(cacheKey, cache)) {
			free(cache);
			cache = NULL;
		}
#endif
	}








|













|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
- (void)drain
{
	[self dealloc];
}

- (void)dealloc
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif

	if (ignoreRelease)
		return;

	ignoreRelease = YES;

	objc_autoreleasePoolPop(pool);

	if (cache == NULL) {
		cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		if (!of_tlskey_set(cacheKey, cache)) {
			free(cache);
			cache = NULL;
		}
#endif
	}

Modified src/OFBlock.m from [7f1306bf32] to [069bfaafeb].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

#import "OFBlock.h"

#import "OFAllocFailedException.h"
#import "OFInitializationFailedException.h"

#import "macros.h"
#ifdef OF_ATOMIC_OPS
# import "atomic.h"
#endif
#ifdef OF_THREADS
# import "threading.h"
#endif

typedef struct of_block_byref_t of_block_byref_t;
struct of_block_byref_t {
	Class isa;
	of_block_byref_t *forwarding;







|


|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

#import "OFBlock.h"

#import "OFAllocFailedException.h"
#import "OFInitializationFailedException.h"

#import "macros.h"
#ifdef OF_HAVE_ATOMIC_OPS
# import "atomic.h"
#endif
#ifdef OF_HAVE_THREADS
# import "threading.h"
#endif

typedef struct of_block_byref_t of_block_byref_t;
struct of_block_byref_t {
	Class isa;
	of_block_byref_t *forwarding;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# endif
#endif

static struct {
	Class isa;
} alloc_failed_exception;

#if !defined(OF_ATOMIC_OPS) && defined(OF_THREADS)
# define NUM_SPINLOCKS 8	/* needs to be a power of 2 */
# define SPINLOCK_HASH(p) ((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1)
static of_spinlock_t spinlocks[NUM_SPINLOCKS];
#endif

void*
_Block_copy(const void *block_)







|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# endif
#endif

static struct {
	Class isa;
} alloc_failed_exception;

#ifndef OF_HAVE_ATOMIC_OPS
# define NUM_SPINLOCKS 8	/* needs to be a power of 2 */
# define SPINLOCK_HASH(p) ((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1)
static of_spinlock_t spinlocks[NUM_SPINLOCKS];
#endif

void*
_Block_copy(const void *block_)
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
			block->descriptor->copy_helper(copy, block);

		return copy;
	}

	if (object_getClass((id)block) == (Class)&_NSConcreteMallocBlock) {
#if defined(OF_ATOMIC_OPS)
		of_atomic_inc_int(&block->flags);
#else
		unsigned hash = SPINLOCK_HASH(block);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		block->flags++;
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
			block->descriptor->copy_helper(copy, block);

		return copy;
	}

	if (object_getClass((id)block) == (Class)&_NSConcreteMallocBlock) {
#ifdef OF_HAVE_ATOMIC_OPS
		of_atomic_inc_int(&block->flags);
#else
		unsigned hash = SPINLOCK_HASH(block);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		block->flags++;
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
_Block_release(const void *block_)
{
	of_block_literal_t *block = (of_block_literal_t*)block_;

	if (object_getClass((id)block) != (Class)&_NSConcreteMallocBlock)
		return;

#ifdef OF_ATOMIC_OPS
	if ((of_atomic_dec_int(&block->flags) & OF_BLOCK_REFCOUNT_MASK) == 0) {
		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
			block->descriptor->dispose_helper(block);

		free(block);
	}
#else







|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
_Block_release(const void *block_)
{
	of_block_literal_t *block = (of_block_literal_t*)block_;

	if (object_getClass((id)block) != (Class)&_NSConcreteMallocBlock)
		return;

#ifdef OF_HAVE_ATOMIC_OPS
	if ((of_atomic_dec_int(&block->flags) & OF_BLOCK_REFCOUNT_MASK) == 0) {
		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
			block->descriptor->dispose_helper(block);

		free(block);
	}
#else
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
	memcpy(&_NSConcreteMallocBlock, tmp, sizeof(_NSConcreteMallocBlock));
	free(tmp);
	objc_registerClassPair((Class)&_NSConcreteMallocBlock);
# endif
}
#endif

#if !defined(OF_ATOMIC_OPS)
+ (void)initialize
{
	size_t i;

	for (i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			@throw [OFInitializationFailedException







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
	memcpy(&_NSConcreteMallocBlock, tmp, sizeof(_NSConcreteMallocBlock));
	free(tmp);
	objc_registerClassPair((Class)&_NSConcreteMallocBlock);
# endif
}
#endif

#ifndef OF_HAVE_ATOMIC_OPS
+ (void)initialize
{
	size_t i;

	for (i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			@throw [OFInitializationFailedException

Modified src/OFDate.m from [eda5b1ce39] to [a29328b01b].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

#include <sys/time.h>

#import "OFDate.h"
#import "OFString.h"
#import "OFDictionary.h"
#import "OFXMLElement.h"
#ifdef OF_THREADS
# import "OFMutex.h"
#endif
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"
#import "of_strptime.h"

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_THREADS)
static OFMutex *mutex;
#endif

#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	struct tm tm;							\







|














|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

#include <sys/time.h>

#import "OFDate.h"
#import "OFString.h"
#import "OFDictionary.h"
#import "OFXMLElement.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"
#import "of_strptime.h"

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
static OFMutex *mutex;
#endif

#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	struct tm tm;							\
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
									\
	if (localtime_r(&seconds_, &tm) == NULL)			\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	return tm.field;
#else
# ifdef OF_THREADS
#  define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	struct tm *tm;							\
									\
	if (seconds_ != floor(seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
									\
	if (localtime_r(&seconds_, &tm) == NULL)			\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	return tm.field;
#else
# ifdef OF_HAVE_THREADS
#  define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	struct tm *tm;							\
									\
	if (seconds_ != floor(seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
};

@implementation OFDate
#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_THREADS)
+ (void)initialize
{
	if (self == [OFDate class])
		mutex = [[OFMutex alloc] init];
}
#endif








|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
};

@implementation OFDate
#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
+ (void)initialize
{
	if (self == [OFDate class])
		mutex = [[OFMutex alloc] init];
}
#endif

521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
	if (seconds_ != floor(seconds))
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

#ifdef HAVE_GMTIME_R
	if (gmtime_r(&seconds_, &tm) == NULL)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_THREADS
	[mutex lock];

	@try {
# endif
		struct tm *tmp;

		if ((tmp = gmtime(&seconds_)) == NULL)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		tm = *tmp;
# ifdef OF_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];







|











|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
	if (seconds_ != floor(seconds))
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

#ifdef HAVE_GMTIME_R
	if (gmtime_r(&seconds_, &tm) == NULL)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
	[mutex lock];

	@try {
# endif
		struct tm *tmp;

		if ((tmp = gmtime(&seconds_)) == NULL)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		tm = *tmp;
# ifdef OF_HAVE_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
	if (seconds_ != floor(seconds))
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

#ifdef HAVE_LOCALTIME_R
	if (localtime_r(&seconds_, &tm) == NULL)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_THREADS
	[mutex lock];

	@try {
# endif
		struct tm *tmp;

		if ((tmp = localtime(&seconds_)) == NULL)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		tm = *tmp;
# ifdef OF_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];







|











|







571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
	if (seconds_ != floor(seconds))
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

#ifdef HAVE_LOCALTIME_R
	if (localtime_r(&seconds_, &tm) == NULL)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
	[mutex lock];

	@try {
# endif
		struct tm *tmp;

		if ((tmp = localtime(&seconds_)) == NULL)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		tm = *tmp;
# ifdef OF_HAVE_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];

Modified src/OFFile.m from [25d73bc7b8] to [9af0a75ec0].

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# include <pwd.h>
# include <grp.h>
#endif

#import "OFFile.h"
#import "OFString.h"
#import "OFArray.h"
#ifdef OF_THREADS
# import "threading.h"
#endif
#import "OFDate.h"
#import "OFApplication.h"
#import "OFSystemInfo.h"

#import "OFChangeDirectoryFailedException.h"







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# include <pwd.h>
# include <grp.h>
#endif

#import "OFFile.h"
#import "OFString.h"
#import "OFArray.h"
#ifdef OF_HAVE_THREADS
# import "threading.h"
#endif
#import "OFDate.h"
#import "OFApplication.h"
#import "OFSystemInfo.h"

#import "OFChangeDirectoryFailedException.h"
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#define DEFAULT_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
#define DIR_MODE DEFAULT_MODE | S_IXUSR | S_IXGRP | S_IXOTH

OFStream *of_stdin = nil;
OFStream *of_stdout = nil;
OFStream *of_stderr = nil;

#if defined(OF_THREADS) && !defined(_WIN32)
static of_mutex_t mutex;
#endif

static int parse_mode(const char *mode)
{
	if (!strcmp(mode, "r"))
		return O_RDONLY;







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#define DEFAULT_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
#define DIR_MODE DEFAULT_MODE | S_IXUSR | S_IXGRP | S_IXOTH

OFStream *of_stdin = nil;
OFStream *of_stdout = nil;
OFStream *of_stderr = nil;

#if defined(OF_HAVE_THREADS) && !defined(_WIN32)
static of_mutex_t mutex;
#endif

static int parse_mode(const char *mode)
{
	if (!strcmp(mode, "r"))
		return O_RDONLY;
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
	objc_autoreleasePoolPop(pool);
}

@interface OFFileSingleton: OFFile
@end

@implementation OFFile
#if defined(OF_THREADS) && !defined(_WIN32)
+ (void)initialize
{
	if (self != [OFFile class])
		return;

	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
	objc_autoreleasePoolPop(pool);
}

@interface OFFileSingleton: OFFile
@end

@implementation OFFile
#if defined(OF_HAVE_THREADS) && !defined(_WIN32)
+ (void)initialize
{
	if (self != [OFFile class])
		return;

	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
	uid_t uid = -1;
	gid_t gid = -1;

	if (owner == nil && group == nil)
		@throw [OFInvalidArgumentException exceptionWithClass: self
							     selector: _cmd];

# ifdef OF_THREADS
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exceptionWithClass: self];

	@try {
# endif
		if (owner != nil) {
			struct passwd *passwd;







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
	uid_t uid = -1;
	gid_t gid = -1;

	if (owner == nil && group == nil)
		@throw [OFInvalidArgumentException exceptionWithClass: self
							     selector: _cmd];

# ifdef OF_HAVE_THREADS
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exceptionWithClass: self];

	@try {
# endif
		if (owner != nil) {
			struct passwd *passwd;
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
				    exceptionWithClass: self
						  path: path
						 owner: owner
						 group: group];

			gid = group_->gr_gid;
		}
# ifdef OF_THREADS
	} @finally {
		if (!of_mutex_unlock(&mutex))
			@throw [OFUnlockFailedException
			    exceptionWithClass: self];
	}
# endif








|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
				    exceptionWithClass: self
						  path: path
						 owner: owner
						 group: group];

			gid = group_->gr_gid;
		}
# ifdef OF_HAVE_THREADS
	} @finally {
		if (!of_mutex_unlock(&mutex))
			@throw [OFUnlockFailedException
			    exceptionWithClass: self];
	}
# endif

Modified src/OFMapTable.m from [996b96d265] to [299f6d68b0].

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

		buckets = [self allocMemoryWithSize: sizeof(*buckets)
					      count: capacity];

		memset(buckets, 0, capacity * sizeof(*buckets));

		if (of_hash_seed != 0)
#if defined(OF_HAVE_ARC4RANDOM)
			rotate = arc4random() & 31;
#elif defined(OF_HAVE_RANDOM)
			rotate = random() & 31;
#else
			rotate = rand() & 31;
#endif
	} @catch (id e) {
		[self release];
		@throw e;







|

|







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

		buckets = [self allocMemoryWithSize: sizeof(*buckets)
					      count: capacity];

		memset(buckets, 0, capacity * sizeof(*buckets));

		if (of_hash_seed != 0)
#if defined(HAVE_ARC4RANDOM)
			rotate = arc4random() & 31;
#elif defined(HAVE_RANDOM)
			rotate = random() & 31;
#else
			rotate = rand() & 31;
#endif
	} @catch (id e) {
		[self release];
		@throw e;

Modified src/OFObject.h from [a016fafbe2] to [5d2293002c].

680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay;

#ifdef OF_THREADS
/*!
 * @brief Performs the specified selector on the specified thread.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param waitUntilDone Whether to wait until the perform finished
 */







|







680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay;

#ifdef OF_HAVE_THREADS
/*!
 * @brief Performs the specified selector on the specified thread.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param waitUntilDone Whether to wait until the perform finished
 */

Modified src/OFObject.m from [1c57171d5d] to [c05874ae6f].

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

#include <assert.h>

#include <sys/time.h>

#import "OFObject.h"
#import "OFTimer.h"
#ifdef OF_THREADS
# import "OFThread.h"
#endif
#import "OFRunLoop.h"
#import "OFAutoreleasePool.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

#include <assert.h>

#include <sys/time.h>

#import "OFObject.h"
#import "OFTimer.h"
#ifdef OF_HAVE_THREADS
# import "OFThread.h"
#endif
#import "OFRunLoop.h"
#import "OFAutoreleasePool.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#ifdef _WIN32
# include <windows.h>
#endif

#import "OFString.h"

#import "instance.h"
#if defined(OF_ATOMIC_OPS)
# import "atomic.h"
#elif defined(OF_THREADS)
# import "threading.h"
#endif

#if defined(OF_APPLE_RUNTIME) && !defined(__ppc64__)
extern id of_forward(id, SEL, ...);
extern struct stret of_forward_stret(id, SEL, ...);
#endif

struct pre_ivar {
	int32_t retainCount;
	struct pre_mem *firstMem, *lastMem;
#if !defined(OF_ATOMIC_OPS) && defined(OF_THREADS)
	of_spinlock_t retainCountSpinlock;
#endif
};

struct pre_mem {
	struct pre_mem *prev, *next;
	id owner;







|

|











|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#ifdef _WIN32
# include <windows.h>
#endif

#import "OFString.h"

#import "instance.h"
#if defined(OF_HAVE_ATOMIC_OPS)
# import "atomic.h"
#elif defined(OF_HAVE_THREADS)
# import "threading.h"
#endif

#if defined(OF_APPLE_RUNTIME) && !defined(__ppc64__)
extern id of_forward(id, SEL, ...);
extern struct stret of_forward_stret(id, SEL, ...);
#endif

struct pre_ivar {
	int32_t retainCount;
	struct pre_mem *firstMem, *lastMem;
#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	of_spinlock_t retainCountSpinlock;
#endif
};

struct pre_mem {
	struct pre_mem *prev, *next;
	id owner;
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
		@throw (id)&alloc_failed_exception;
	}

	((struct pre_ivar*)instance)->retainCount = 1;
	((struct pre_ivar*)instance)->firstMem = NULL;
	((struct pre_ivar*)instance)->lastMem = NULL;

#if !defined(OF_ATOMIC_OPS) && defined(OF_THREADS)
	if OF_UNLIKELY (!of_spinlock_new(
	    &((struct pre_ivar*)instance)->retainCountSpinlock)) {
		free(instance);
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}
#endif







|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
		@throw (id)&alloc_failed_exception;
	}

	((struct pre_ivar*)instance)->retainCount = 1;
	((struct pre_ivar*)instance)->firstMem = NULL;
	((struct pre_ivar*)instance)->lastMem = NULL;

#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	if OF_UNLIKELY (!of_spinlock_new(
	    &((struct pre_ivar*)instance)->retainCountSpinlock)) {
		free(instance);
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}
#endif
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
	objc_setForwardHandler(of_forward, of_forward_stret);
#endif

#ifdef HAVE_OBJC_ENUMERATIONMUTATION
	objc_setEnumerationMutationHandler(enumeration_mutation_handler);
#endif

#if defined(OF_HAVE_ARC4RANDOM)
	of_hash_seed = arc4random();
#elif defined(OF_HAVE_RANDOM)
	struct timeval t;
	gettimeofday(&t, NULL);
	srandom((unsigned)(t.tv_sec ^ t.tv_usec));
	of_hash_seed = (uint32_t)((random() << 16) | (random() & 0xFFFF));
#else
	struct timeval t;
	gettimeofday(&t, NULL);







|

|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
	objc_setForwardHandler(of_forward, of_forward_stret);
#endif

#ifdef HAVE_OBJC_ENUMERATIONMUTATION
	objc_setEnumerationMutationHandler(enumeration_mutation_handler);
#endif

#if defined(HAVE_ARC4RANDOM)
	of_hash_seed = arc4random();
#elif defined(HAVE_RANDOM)
	struct timeval t;
	gettimeofday(&t, NULL);
	srandom((unsigned)(t.tv_sec ^ t.tv_usec));
	of_hash_seed = (uint32_t)((random() << 16) | (random() & 0xFFFF));
#else
	struct timeval t;
	gettimeofday(&t, NULL);
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
					 object: object1
					 object: object2
					repeats: NO];

	objc_autoreleasePoolPop(pool);
}

#ifdef OF_THREADS
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	  waitUntilDone: (BOOL)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self







|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
					 object: object1
					 object: object2
					repeats: NO];

	objc_autoreleasePoolPop(pool);
}

#ifdef OF_HAVE_THREADS
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	  waitUntilDone: (BOOL)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
{
	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: selector];
}

- retain
{
#if defined(OF_ATOMIC_OPS)
	of_atomic_inc_32(&PRE_IVARS->retainCount);
#elif defined(OF_THREADS)
	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
	PRE_IVARS->retainCount++;
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
#else
	PRE_IVARS->retainCount++;
#endif

	return self;
}

- (unsigned int)retainCount
{
	assert(PRE_IVARS->retainCount >= 0);
	return PRE_IVARS->retainCount;
}

- (void)release
{
#if defined(OF_ATOMIC_OPS)
	if (of_atomic_dec_32(&PRE_IVARS->retainCount) <= 0)
		[self dealloc];
#elif defined(OF_THREADS)
	size_t c;

	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
	c = --PRE_IVARS->retainCount;
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));

	if (c == 0)
		[self dealloc];
#else
	if (--PRE_IVARS->retainCount == 0)
		[self dealloc];
#endif
}

- autorelease
{
	return _objc_rootAutorelease(self);
}







|

|



<
<













|


|








<
<
<







967
968
969
970
971
972
973
974
975
976
977
978
979


980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004



1005
1006
1007
1008
1009
1010
1011
{
	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: selector];
}

- retain
{
#if defined(OF_HAVE_ATOMIC_OPS)
	of_atomic_inc_32(&PRE_IVARS->retainCount);
#else
	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
	PRE_IVARS->retainCount++;
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));


#endif

	return self;
}

- (unsigned int)retainCount
{
	assert(PRE_IVARS->retainCount >= 0);
	return PRE_IVARS->retainCount;
}

- (void)release
{
#if defined(OF_HAVE_ATOMIC_OPS)
	if (of_atomic_dec_32(&PRE_IVARS->retainCount) <= 0)
		[self dealloc];
#else
	size_t c;

	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
	c = --PRE_IVARS->retainCount;
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));

	if (c == 0)
		[self dealloc];



#endif
}

- autorelease
{
	return _objc_rootAutorelease(self);
}

Modified src/OFRunLoop.h from [f2e88dae39] to [1730eaf461].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#import "OFObject.h"
#import "OFStream.h"
#import "OFStreamObserver.h"
#import "OFTCPSocket.h"

@class OFSortedList;
#ifdef OF_THREADS
@class OFMutex;
#endif
@class OFTimer;
@class OFMutableDictionary;

/*!
 * @brief A class providing a run loop for the application and its processes.
 */
@interface OFRunLoop: OFObject
{
	OFSortedList *timersQueue;
#ifdef OF_THREADS
	OFMutex *timersQueueLock;
#endif
	OFStreamObserver *streamObserver;
	OFMutableDictionary *readQueues;
}

/*!







|











|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#import "OFObject.h"
#import "OFStream.h"
#import "OFStreamObserver.h"
#import "OFTCPSocket.h"

@class OFSortedList;
#ifdef OF_HAVE_THREADS
@class OFMutex;
#endif
@class OFTimer;
@class OFMutableDictionary;

/*!
 * @brief A class providing a run loop for the application and its processes.
 */
@interface OFRunLoop: OFObject
{
	OFSortedList *timersQueue;
#ifdef OF_HAVE_THREADS
	OFMutex *timersQueueLock;
#endif
	OFStreamObserver *streamObserver;
	OFMutableDictionary *readQueues;
}

/*!

Modified src/OFRunLoop.m from [1f0d5617f1] to [9373453d76].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

#include "config.h"

#include <assert.h>

#import "OFRunLoop.h"
#import "OFDictionary.h"
#ifdef OF_THREADS
# import "OFThread.h"
# import "OFMutex.h"
#endif
#import "OFSortedList.h"
#import "OFTimer.h"
#import "OFDate.h"








|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

#include "config.h"

#include <assert.h>

#import "OFRunLoop.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_THREADS
# import "OFThread.h"
# import "OFMutex.h"
#endif
#import "OFSortedList.h"
#import "OFTimer.h"
#import "OFDate.h"

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
+ (OFRunLoop*)mainRunLoop
{
	return [[mainRunLoop retain] autorelease];
}

+ (OFRunLoop*)currentRunLoop
{
#ifdef OF_THREADS
	return [[OFThread currentThread] runLoop];
#else
	return [self mainRunLoop];
#endif
}

+ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
+ (OFRunLoop*)mainRunLoop
{
	return [[mainRunLoop retain] autorelease];
}

+ (OFRunLoop*)currentRunLoop
{
#ifdef OF_HAVE_THREADS
	return [[OFThread currentThread] runLoop];
#else
	return [self mainRunLoop];
#endif
}

+ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

- init
{
	self = [super init];

	@try {
		timersQueue = [[OFSortedList alloc] init];
#ifdef OF_THREADS
		timersQueueLock = [[OFMutex alloc] init];
#endif

		streamObserver = [[OFStreamObserver alloc] init];
		[streamObserver setDelegate: self];

		readQueues = [[OFMutableDictionary alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[timersQueue release];
#ifdef OF_THREADS
	[timersQueueLock release];
#endif
	[streamObserver release];
	[readQueues release];

	[super dealloc];
}

- (void)addTimer: (OFTimer*)timer
{
#ifdef OF_THREADS
	[timersQueueLock lock];
	@try {
#endif
		[timersQueue insertObject: timer];
#ifdef OF_THREADS
	} @finally {
		[timersQueueLock unlock];
	}
#endif

	[timer OF_setInRunLoop: self];

	[streamObserver cancel];
}

- (void)OF_removeTimer: (OFTimer*)timer
{
#ifdef OF_THREADS
	[timersQueueLock lock];
	@try {
#endif
		of_list_object_t *iter;

		for (iter = [timersQueue firstListObject]; iter != NULL;
		    iter = iter->next) {
			if ([iter->object isEqual: timer]) {
				[timersQueue removeListObject: iter];
				break;
			}
		}
#ifdef OF_THREADS
	} @finally {
		[timersQueueLock unlock];
	}
#endif
}

- (void)streamIsReadyForReading: (OFStream*)stream







|


















|










|




|












|












|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

- init
{
	self = [super init];

	@try {
		timersQueue = [[OFSortedList alloc] init];
#ifdef OF_HAVE_THREADS
		timersQueueLock = [[OFMutex alloc] init];
#endif

		streamObserver = [[OFStreamObserver alloc] init];
		[streamObserver setDelegate: self];

		readQueues = [[OFMutableDictionary alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[timersQueue release];
#ifdef OF_HAVE_THREADS
	[timersQueueLock release];
#endif
	[streamObserver release];
	[readQueues release];

	[super dealloc];
}

- (void)addTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
	[timersQueueLock lock];
	@try {
#endif
		[timersQueue insertObject: timer];
#ifdef OF_HAVE_THREADS
	} @finally {
		[timersQueueLock unlock];
	}
#endif

	[timer OF_setInRunLoop: self];

	[streamObserver cancel];
}

- (void)OF_removeTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
	[timersQueueLock lock];
	@try {
#endif
		of_list_object_t *iter;

		for (iter = [timersQueue firstListObject]; iter != NULL;
		    iter = iter->next) {
			if ([iter->object isEqual: timer]) {
				[timersQueue removeListObject: iter];
				break;
			}
		}
#ifdef OF_HAVE_THREADS
	} @finally {
		[timersQueueLock unlock];
	}
#endif
}

- (void)streamIsReadyForReading: (OFStream*)stream
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
{
	for (;;) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;

#ifdef OF_THREADS
		[timersQueueLock lock];
		@try {
#endif
			of_list_object_t *listObject =
			    [timersQueue firstListObject];

			if (listObject != NULL &&
			    [[listObject->object fireDate] compare: now] !=
			    OF_ORDERED_DESCENDING) {
				timer =
				    [[listObject->object retain] autorelease];

				[timersQueue removeListObject: listObject];

				[timer OF_setInRunLoop: nil];
			} else
				timer = nil;
#ifdef OF_THREADS
		} @finally {
			[timersQueueLock unlock];
		}
#endif

		if ([timer isValid])
			[timer fire];

#ifdef OF_THREADS
		[timersQueueLock lock];
		@try {
#endif
			nextTimer = [[timersQueue firstObject] fireDate];
#ifdef OF_THREADS
		} @finally {
			[timersQueueLock unlock];
		}
#endif

		/* Watch for stream events until the next timer is due */
		if (nextTimer != nil) {







|

















|








|




|







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
{
	for (;;) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;

#ifdef OF_HAVE_THREADS
		[timersQueueLock lock];
		@try {
#endif
			of_list_object_t *listObject =
			    [timersQueue firstListObject];

			if (listObject != NULL &&
			    [[listObject->object fireDate] compare: now] !=
			    OF_ORDERED_DESCENDING) {
				timer =
				    [[listObject->object retain] autorelease];

				[timersQueue removeListObject: listObject];

				[timer OF_setInRunLoop: nil];
			} else
				timer = nil;
#ifdef OF_HAVE_THREADS
		} @finally {
			[timersQueueLock unlock];
		}
#endif

		if ([timer isValid])
			[timer fire];

#ifdef OF_HAVE_THREADS
		[timersQueueLock lock];
		@try {
#endif
			nextTimer = [[timersQueue firstObject] fireDate];
#ifdef OF_HAVE_THREADS
		} @finally {
			[timersQueueLock unlock];
		}
#endif

		/* Watch for stream events until the next timer is due */
		if (nextTimer != nil) {

Modified src/OFStreamObserver.h from [16966241ea] to [b07d550270].

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# include <windows.h>
#endif

@class OFStream;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFDataArray;
#ifdef OF_THREADS
@class OFMutex;
#endif

/*!
 * @brief A protocol that needs to be implemented by delegates for
 *	  OFStreamObserver.
 */







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# include <windows.h>
#endif

@class OFStream;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFDataArray;
#ifdef OF_HAVE_THREADS
@class OFMutex;
#endif

/*!
 * @brief A protocol that needs to be implemented by delegates for
 *	  OFStreamObserver.
 */
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
	OFMutableArray *queue;
	OFDataArray *queueInfo, *queueFDs;
	id <OFStreamObserverDelegate> delegate;
	int cancelFD[2];
#ifdef _WIN32
	struct sockaddr_in cancelAddr;
#endif
#ifdef OF_THREADS
	OFMutex *mutex;
#endif
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFStreamObserverDelegate> delegate;
#endif







|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
	OFMutableArray *queue;
	OFDataArray *queueInfo, *queueFDs;
	id <OFStreamObserverDelegate> delegate;
	int cancelFD[2];
#ifdef _WIN32
	struct sockaddr_in cancelAddr;
#endif
#ifdef OF_HAVE_THREADS
	OFMutex *mutex;
#endif
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFStreamObserverDelegate> delegate;
#endif

Modified src/OFStreamObserver.m from [b904df7bb8] to [b6d33523f1].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFStream.h"
#import "OFDataArray.h"
#ifdef _WIN32
# import "OFTCPSocket.h"
#endif
#ifdef OF_THREADS
# import "OFMutex.h"
#endif

#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#ifdef HAVE_POLL_H







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFStream.h"
#import "OFDataArray.h"
#ifdef _WIN32
# import "OFTCPSocket.h"
#endif
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif

#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#ifdef HAVE_POLL_H
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202

203
204
205

206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223

224
225
226

227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244

245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270

271
272
273

274
275
276
277
278
279
280
#endif

		maxFD = cancelFD[0];
		FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
						 count: maxFD + 1];
		FDToStream[cancelFD[0]] = nil;

#ifdef OF_THREADS
		mutex = [[OFMutex alloc] init];
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	close(cancelFD[0]);
	close(cancelFD[1]);

	[readStreams release];
	[writeStreams release];
	[queue release];
	[queueInfo release];
	[queueFDs release];
#ifdef OF_THREADS
	[mutex release];
#endif

	[super dealloc];
}

- (id <OFStreamObserverDelegate>)delegate
{
	return delegate;
}

- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate_
{
	delegate = delegate_;
}

- (void)addStreamForReading: (OFStream*)stream
{
#ifdef OF_THREADS
	[mutex lock];
	@try {
#endif

		int qi = QUEUE_ADD | QUEUE_READ;
		int fd = [stream fileDescriptorForReading];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
#ifdef OF_THREADS
	} @finally {

		[mutex unlock];
	}
#endif


	[self cancel];
}

- (void)addStreamForWriting: (OFStream*)stream
{
#ifdef OF_THREADS
	[mutex lock];
	@try {
#endif

		int qi = QUEUE_ADD | QUEUE_WRITE;
		int fd = [stream fileDescriptorForWriting];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
#ifdef OF_THREADS
	} @finally {

		[mutex unlock];
	}
#endif


	[self cancel];
}

- (void)removeStreamForReading: (OFStream*)stream
{
#ifdef OF_THREADS
	[mutex lock];
	@try {
#endif

		int qi = QUEUE_REMOVE | QUEUE_READ;
		int fd = [stream fileDescriptorForReading];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
#ifdef OF_THREADS
	} @finally {

		[mutex unlock];
	}
#endif


#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
#endif
}

- (void)removeStreamForWriting: (OFStream*)stream
{
#ifdef OF_THREADS
	[mutex lock];
	@try {
#endif

		int qi = QUEUE_REMOVE | QUEUE_WRITE;
		int fd = [stream fileDescriptorForWriting];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
#ifdef OF_THREADS
	} @finally {

		[mutex unlock];
	}
#endif


#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
#endif







|




















|


















|

<

>






<

>

<

>






|

<

>






<

>

<

>






|

<

>






<

>

<

>











|

<

>






<

>

<

>







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200

201
202
203

204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221

222
223
224

225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242

243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268

269
270
271

272
273
274
275
276
277
278
279
280
#endif

		maxFD = cancelFD[0];
		FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
						 count: maxFD + 1];
		FDToStream[cancelFD[0]] = nil;

#ifdef OF_HAVE_THREADS
		mutex = [[OFMutex alloc] init];
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	close(cancelFD[0]);
	close(cancelFD[1]);

	[readStreams release];
	[writeStreams release];
	[queue release];
	[queueInfo release];
	[queueFDs release];
#ifdef OF_HAVE_THREADS
	[mutex release];
#endif

	[super dealloc];
}

- (id <OFStreamObserverDelegate>)delegate
{
	return delegate;
}

- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate_
{
	delegate = delegate_;
}

- (void)addStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];

#endif
	@try {
		int qi = QUEUE_ADD | QUEUE_READ;
		int fd = [stream fileDescriptorForReading];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];

	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];

#endif
	}

	[self cancel];
}

- (void)addStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];

#endif
	@try {
		int qi = QUEUE_ADD | QUEUE_WRITE;
		int fd = [stream fileDescriptorForWriting];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];

	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];

#endif
	}

	[self cancel];
}

- (void)removeStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];

#endif
	@try {
		int qi = QUEUE_REMOVE | QUEUE_READ;
		int fd = [stream fileDescriptorForReading];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];

	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];

#endif
	}

#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
#endif
}

- (void)removeStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];

#endif
	@try {
		int qi = QUEUE_REMOVE | QUEUE_WRITE;
		int fd = [stream fileDescriptorForWriting];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];

	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];

#endif
	}

#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
#endif
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)OF_processQueue
{
#ifdef OF_THREADS
	[mutex lock];
	@try {
#endif

		OFStream **queueObjects = [queue objects];
		int *queueInfoItems = [queueInfo items];
		int *queueFDsItems = [queueFDs items];
		size_t i, count = [queue count];

		for (i = 0; i < count; i++) {
			OFStream *stream = queueObjects[i];







|

<

>







302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)OF_processQueue
{
#ifdef OF_HAVE_THREADS
	[mutex lock];

#endif
	@try {
		OFStream **queueObjects = [queue objects];
		int *queueInfoItems = [queueInfo items];
		int *queueFDsItems = [queueFDs items];
		size_t i, count = [queue count];

		for (i = 0; i < count; i++) {
			OFStream *stream = queueObjects[i];
366
367
368
369
370
371
372
373
374

375
376
377

378
379
380
381
382
383
384
				assert(0);
			}
		}

		[queue removeAllObjects];
		[queueInfo removeAllItems];
		[queueFDs removeAllItems];
#ifdef OF_THREADS
	} @finally {

		[mutex unlock];
	}
#endif

}

- (void)observe
{
	[self observeWithTimeout: -1];
}








<

>

<

>







366
367
368
369
370
371
372

373
374
375

376
377
378
379
380
381
382
383
384
				assert(0);
			}
		}

		[queue removeAllObjects];
		[queueInfo removeAllItems];
		[queueFDs removeAllItems];

	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];

#endif
	}
}

- (void)observe
{
	[self observeWithTimeout: -1];
}

Modified src/OFStreamObserver_select.h from [47937d91a0] to [ef59e082ab].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#ifdef OF_HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif

#import "OFStreamObserver.h"

@interface OFStreamObserver_select: OFStreamObserver
{
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
}
@end







|












17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif

#import "OFStreamObserver.h"

@interface OFStreamObserver_select: OFStreamObserver
{
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
}
@end

Modified src/OFTCPSocket.h from [e5d525cdbe] to [80ab9c568a].

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 */
- (void)connectToHost: (OFString*)host
		 port: (uint16_t)port;

#ifdef OF_THREADS
/*!
 * @brief Asyncronously connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 * @param target The target on which to call the selector once the connection
 *		 has been established







|







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 */
- (void)connectToHost: (OFString*)host
		 port: (uint16_t)port;

#ifdef OF_HAVE_THREADS
/*!
 * @brief Asyncronously connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 * @param target The target on which to call the selector once the connection
 *		 has been established

Modified src/OFTCPSocket.m from [e458e43209] to [5685b5bf99].

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# include <arpa/inet.h>
# include <netdb.h>
#endif

#import "OFTCPSocket.h"
#import "OFTCPSocket+SOCKS5.h"
#import "OFString.h"
#ifdef OF_THREADS
# import "OFThread.h"
#endif
#import "OFTimer.h"
#import "OFRunLoop.h"

#import "OFAcceptFailedException.h"
#import "OFAlreadyConnectedException.h"







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# include <arpa/inet.h>
# include <netdb.h>
#endif

#import "OFTCPSocket.h"
#import "OFTCPSocket+SOCKS5.h"
#import "OFString.h"
#ifdef OF_HAVE_THREADS
# import "OFThread.h"
#endif
#import "OFTimer.h"
#import "OFRunLoop.h"

#import "OFAcceptFailedException.h"
#import "OFAlreadyConnectedException.h"
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#import "autorelease.h"
#import "macros.h"

#ifndef INVALID_SOCKET
# define INVALID_SOCKET -1
#endif

#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
# import "OFMutex.h"
# import "OFDataArray.h"

static OFMutex *mutex = nil;
#endif

#ifdef _WIN32







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#import "autorelease.h"
#import "macros.h"

#ifndef INVALID_SOCKET
# define INVALID_SOCKET -1
#endif

#if defined(OF_HAVE_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
# import "OFMutex.h"
# import "OFDataArray.h"

static OFMutex *mutex = nil;
#endif

#ifdef _WIN32
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
}

Class of_tls_socket_class = Nil;

static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;

#ifdef OF_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
	OFThread *sourceThread;
	OFTCPSocket *sock;
	OFString *host;
	uint16_t port;
	id target;







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
}

Class of_tls_socket_class = Nil;

static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;

#ifdef OF_HAVE_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
	OFThread *sourceThread;
	OFTCPSocket *sock;
	OFString *host;
	uint16_t port;
	id target;
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

	return nil;
}
@end
#endif

@implementation OFTCPSocket
#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
+ (void)initialize
{
	if (self == [OFTCPSocket class])
		mutex = [[OFMutex alloc] init];
}
#endif








|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

	return nil;
}
@end
#endif

@implementation OFTCPSocket
#if defined(OF_HAVE_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
+ (void)initialize
{
	if (self == [OFTCPSocket class])
		mutex = [[OFMutex alloc] init];
}
#endif

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

	freeaddrinfo(res0);
#else
	BOOL connected = NO;
	struct hostent *he;
	struct sockaddr_in addr;
	char **ip;
# ifdef OF_THREADS
	OFDataArray *addrlist;

	addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)];
	[mutex lock];
# endif

	if ((he = gethostbyname([host cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE])) == NULL) {
# ifdef OF_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = OF_BSWAP16_IF_LE(port);

	if (he->h_addrtype != AF_INET ||
	    (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
# ifdef OF_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
								  host: host
								  port: port];
	}

# ifdef OF_THREADS
	@try {
		for (ip = he->h_addr_list; *ip != NULL; ip++)
			[addrlist addItem: ip];

		/* Add the terminating NULL */
		[addrlist addItem: ip];
	} @catch (id e) {







|








|















|










|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

	freeaddrinfo(res0);
#else
	BOOL connected = NO;
	struct hostent *he;
	struct sockaddr_in addr;
	char **ip;
# ifdef OF_HAVE_THREADS
	OFDataArray *addrlist;

	addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)];
	[mutex lock];
# endif

	if ((he = gethostbyname([host cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE])) == NULL) {
# ifdef OF_HAVE_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = OF_BSWAP16_IF_LE(port);

	if (he->h_addrtype != AF_INET ||
	    (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
# ifdef OF_HAVE_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
								  host: host
								  port: port];
	}

# ifdef OF_HAVE_THREADS
	@try {
		for (ip = he->h_addr_list; *ip != NULL; ip++)
			[addrlist addItem: ip];

		/* Add the terminating NULL */
		[addrlist addItem: ip];
	} @catch (id e) {
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
		if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
			continue;

		connected = YES;
		break;
	}

# ifdef OF_THREADS
	[addrlist release];
# endif

	if (!connected) {
		close(sock);
		sock = INVALID_SOCKET;
	}







|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
		if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
			continue;

		connected = YES;
		break;
	}

# ifdef OF_HAVE_THREADS
	[addrlist release];
# endif

	if (!connected) {
		close(sock);
		sock = INVALID_SOCKET;
	}
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
				  port: port];

	if (SOCKS5Host != nil)
		[self OF_SOCKS5ConnectToHost: destinationHost
					port: destinationPort];
}

#ifdef OF_THREADS
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector
{
	void *pool = objc_autoreleasePoolPush();








|







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
				  port: port];

	if (SOCKS5Host != nil)
		[self OF_SOCKS5ConnectToHost: destinationHost
					port: destinationPort];
}

#ifdef OF_HAVE_THREADS
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector
{
	void *pool = objc_autoreleasePoolPush();

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
							    port: port];
	}

	freeaddrinfo(res);
#else
	struct hostent *he;

# ifdef OF_THREADS
	[mutex lock];
# endif

	if ((he = gethostbyname([host cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE])) == NULL) {
# ifdef OF_THREADS
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];
	}

	memset(&addr, 0, sizeof(addr));
	addr.in.sin_family = AF_INET;
	addr.in.sin_port = OF_BSWAP16_IF_LE(port);

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {
# ifdef OF_THREADS
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];
	}

	memcpy(&addr.in.sin_addr.s_addr, he->h_addr_list[0], he->h_length);

# ifdef OF_THREADS
	[mutex unlock];
# endif
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];







|





|













|










|







527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
							    port: port];
	}

	freeaddrinfo(res);
#else
	struct hostent *he;

# ifdef OF_HAVE_THREADS
	[mutex lock];
# endif

	if ((he = gethostbyname([host cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE])) == NULL) {
# ifdef OF_HAVE_THREADS
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];
	}

	memset(&addr, 0, sizeof(addr));
	addr.in.sin_family = AF_INET;
	addr.in.sin_port = OF_BSWAP16_IF_LE(port);

	if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) {
# ifdef OF_HAVE_THREADS
		[mutex unlock];
# endif
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];
	}

	memcpy(&addr.in.sin_addr.s_addr, he->h_addr_list[0], he->h_length);

# ifdef OF_HAVE_THREADS
	[mutex unlock];
# endif
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

		return [OFString stringWithCString: host
					  encoding: OF_STRING_ENCODING_NATIVE];
	} @finally {
		[self freeMemory: host];
	}
#else
# ifdef OF_THREADS
	[mutex lock];

	@try {
# endif
		host = inet_ntoa(((struct sockaddr_in*)sockAddr)->sin_addr);

		if (host == NULL)
			@throw [OFAddressTranslationFailedException
			    exceptionWithClass: [self class]];

		return [OFString stringWithCString: host
					  encoding: OF_STRING_ENCODING_NATIVE];
# ifdef OF_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	/* Get rid of a warning, never reached anyway */







|












|







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

		return [OFString stringWithCString: host
					  encoding: OF_STRING_ENCODING_NATIVE];
	} @finally {
		[self freeMemory: host];
	}
#else
# ifdef OF_HAVE_THREADS
	[mutex lock];

	@try {
# endif
		host = inet_ntoa(((struct sockaddr_in*)sockAddr)->sin_addr);

		if (host == NULL)
			@throw [OFAddressTranslationFailedException
			    exceptionWithClass: [self class]];

		return [OFString stringWithCString: host
					  encoding: OF_STRING_ENCODING_NATIVE];
# ifdef OF_HAVE_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	/* Get rid of a warning, never reached anyway */

Modified src/OFTimer.h from [2f990ddaf1] to [b48acf13c1].

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 */

#import "OFObject.h"

@class OFTimer;
@class OFDate;
@class OFRunLoop;
#ifdef OF_THREADS
@class OFCondition;
#endif

#ifdef OF_HAVE_BLOCKS
typedef void (^of_timer_block_t)(OFTimer*);
#endif








|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 */

#import "OFObject.h"

@class OFTimer;
@class OFDate;
@class OFRunLoop;
#ifdef OF_HAVE_THREADS
@class OFCondition;
#endif

#ifdef OF_HAVE_BLOCKS
typedef void (^of_timer_block_t)(OFTimer*);
#endif

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	SEL selector;
	uint8_t arguments;
	BOOL repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t block;
#endif
	BOOL isValid;
#ifdef OF_THREADS
	OFCondition *condition;
	BOOL done;
#endif
	OFRunLoop *inRunLoop;
}

#ifdef OF_HAVE_PROPERTIES







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	SEL selector;
	uint8_t arguments;
	BOOL repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t block;
#endif
	BOOL isValid;
#ifdef OF_HAVE_THREADS
	OFCondition *condition;
	BOOL done;
#endif
	OFRunLoop *inRunLoop;
}

#ifdef OF_HAVE_PROPERTIES
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
 *	  repeating timer.
 *
 * @return The time interval in which the timer will repeat, if it is a
 *	   repeating timer
 */
- (double)timeInterval;

#ifdef OF_THREADS
/*!
 * @brief Waits until the timer fired.
 */
- (void)waitUntilDone;
#endif

- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop;
@end







|








311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
 *	  repeating timer.
 *
 * @return The time interval in which the timer will repeat, if it is a
 *	   repeating timer
 */
- (double)timeInterval;

#ifdef OF_HAVE_THREADS
/*!
 * @brief Waits until the timer fired.
 */
- (void)waitUntilDone;
#endif

- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop;
@end

Modified src/OFTimer.m from [1f8783cad4] to [0fd41ebc3f].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdlib.h>

#include <assert.h>

#import "OFTimer.h"
#import "OFDate.h"
#import "OFRunLoop.h"
#ifdef OF_THREADS
# import "OFCondition.h"
#endif

#import "OFInvalidArgumentException.h"

#import "autorelease.h"
#import "macros.h"







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdlib.h>

#include <assert.h>

#import "OFTimer.h"
#import "OFDate.h"
#import "OFRunLoop.h"
#ifdef OF_HAVE_THREADS
# import "OFCondition.h"
#endif

#import "OFInvalidArgumentException.h"

#import "autorelease.h"
#import "macros.h"
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
		target = [target_ retain];
		selector = selector_;
		object1 = [object1_ retain];
		object2 = [object2_ retain];
		arguments = arguments_;
		repeats = repeats_;
		isValid = YES;
#ifdef OF_THREADS
		condition = [[OFCondition alloc] init];
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}








|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
		target = [target_ retain];
		selector = selector_;
		object1 = [object1_ retain];
		object2 = [object2_ retain];
		arguments = arguments_;
		repeats = repeats_;
		isValid = YES;
#ifdef OF_HAVE_THREADS
		condition = [[OFCondition alloc] init];
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

	@try {
		fireDate = [fireDate_ retain];
		interval = interval_;
		repeats = repeats_;
		block = [block_ copy];
		isValid = YES;
# ifdef OF_THREADS
		condition = [[OFCondition alloc] init];
# endif
	} @catch (id e) {
		[self release];
		@throw e;
	}








|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

	@try {
		fireDate = [fireDate_ retain];
		interval = interval_;
		repeats = repeats_;
		block = [block_ copy];
		isValid = YES;
# ifdef OF_HAVE_THREADS
		condition = [[OFCondition alloc] init];
# endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
	[fireDate release];
	[target release];
	[object1 release];
	[object2 release];
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif
#ifdef OF_THREADS
	[condition release];
#endif

	[super dealloc];
}

- (of_comparison_result_t)compare: (id <OFComparing>)object_







|







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
	[fireDate release];
	[target release];
	[object1 release];
	[object2 release];
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif
#ifdef OF_HAVE_THREADS
	[condition release];
#endif

	[super dealloc];
}

- (of_comparison_result_t)compare: (id <OFComparing>)object_
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
				     withObject: object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

#ifdef OF_THREADS
	[condition lock];
	@try {
		done = YES;
		[condition signal];
	} @finally {
		[condition unlock];
	}







|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
				     withObject: object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

#ifdef OF_HAVE_THREADS
	[condition lock];
	@try {
		done = YES;
		[condition signal];
	} @finally {
		[condition unlock];
	}
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
}

- (BOOL)isValid
{
	return isValid;
}

#ifdef OF_THREADS
- (void)waitUntilDone
{
	[condition lock];
	@try {
		if (done) {
			done = NO;
			return;







|







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
}

- (BOOL)isValid
{
	return isValid;
}

#ifdef OF_HAVE_THREADS
- (void)waitUntilDone
{
	[condition lock];
	@try {
		if (done) {
			done = NO;
			return;

Modified src/ObjFW.h from [e5cbb2dc26] to [46c8ffd626].

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#import "OFAcceptFailedException.h"
#import "OFAddressTranslationFailedException.h"
#import "OFAlreadyConnectedException.h"
#import "OFBindFailedException.h"
#import "OFChangeDirectoryFailedException.h"
#import "OFChangeFileModeFailedException.h"
#import "OFChangeFileOwnerFailedException.h"
#ifdef OF_THREADS
# import "OFConditionBroadcastFailedException.h"
# import "OFConditionSignalFailedException.h"
# import "OFConditionStillWaitingException.h"
# import "OFConditionWaitFailedException.h"
#endif
#import "OFConnectionFailedException.h"
#import "OFCopyFileFailedException.h"







|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#import "OFAcceptFailedException.h"
#import "OFAddressTranslationFailedException.h"
#import "OFAlreadyConnectedException.h"
#import "OFBindFailedException.h"
#import "OFChangeDirectoryFailedException.h"
#import "OFChangeFileModeFailedException.h"
#import "OFChangeFileOwnerFailedException.h"
#ifdef OF_HAVE_THREADS
# import "OFConditionBroadcastFailedException.h"
# import "OFConditionSignalFailedException.h"
# import "OFConditionStillWaitingException.h"
# import "OFConditionWaitFailedException.h"
#endif
#import "OFConnectionFailedException.h"
#import "OFCopyFileFailedException.h"
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#import "OFReadFailedException.h"
#import "OFReadOrWriteFailedException.h"
#import "OFRenameFileFailedException.h"
#import "OFSeekFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFStillLockedException.h"
#import "OFSymlinkFailedException.h"
#ifdef OF_THREADS
# import "OFThreadJoinFailedException.h"
# import "OFThreadStartFailedException.h"
# import "OFThreadStillRunningException.h"
#endif
#import "OFTruncatedDataException.h"
#import "OFUnboundNamespaceException.h"
#import "OFUnlockFailedException.h"
#import "OFUnsupportedProtocolException.h"
#import "OFWriteFailedException.h"

#import "macros.h"

#ifdef OF_PLUGINS
# import "OFPlugin.h"
#endif

#ifdef OF_ATOMIC_OPS
# import "atomic.h"
#endif

#import "OFLocking.h"
#ifdef OF_THREADS
# import "threading.h"
# import "OFThread.h"
# import "OFThreadPool.h"
# import "OFTLSKey.h"
# import "OFMutex.h"
# import "OFRecursiveMutex.h"
# import "OFCondition.h"







|












|



|




|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#import "OFReadFailedException.h"
#import "OFReadOrWriteFailedException.h"
#import "OFRenameFileFailedException.h"
#import "OFSeekFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFStillLockedException.h"
#import "OFSymlinkFailedException.h"
#ifdef OF_HAVE_THREADS
# import "OFThreadJoinFailedException.h"
# import "OFThreadStartFailedException.h"
# import "OFThreadStillRunningException.h"
#endif
#import "OFTruncatedDataException.h"
#import "OFUnboundNamespaceException.h"
#import "OFUnlockFailedException.h"
#import "OFUnsupportedProtocolException.h"
#import "OFWriteFailedException.h"

#import "macros.h"

#ifdef OF_HAVE_PLUGINS
# import "OFPlugin.h"
#endif

#ifdef OF_HAVE_ATOMIC_OPS
# import "atomic.h"
#endif

#import "OFLocking.h"
#ifdef OF_HAVE_THREADS
# import "threading.h"
# import "OFThread.h"
# import "OFThreadPool.h"
# import "OFTLSKey.h"
# import "OFMutex.h"
# import "OFRecursiveMutex.h"
# import "OFCondition.h"

Modified src/atomic.h from [7c0142eaf1] to [368de22827].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifdef OF_HAVE_OSATOMIC
# include <libkern/OSAtomic.h>
#endif

static OF_INLINE int
of_atomic_add_int(volatile int *p, int i)
{
#if !defined(OF_THREADS)
	return (*p += i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "lock\n\t"
		    "xaddl	%0, %2\n\t"
		    "addl	%1, %0"







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifdef OF_HAVE_OSATOMIC
# include <libkern/OSAtomic.h>
#endif

static OF_INLINE int
of_atomic_add_int(volatile int *p, int i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p += i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "lock\n\t"
		    "xaddl	%0, %2\n\t"
		    "addl	%1, %0"
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_add_32(volatile int32_t *p, int32_t i)
{
#if !defined(OF_THREADS)
	return (*p += i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "addl	%1, %0"
	    : "+&r"(i)







|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_add_32(volatile int32_t *p, int32_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p += i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "addl	%1, %0"
	    : "+&r"(i)
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# error No atomic operations available!
#endif
}

static OF_INLINE void*
of_atomic_add_ptr(void* volatile *p, intptr_t i)
{
#if !defined(OF_THREADS)
	return (*(char* volatile*)p += i);
#elif defined(OF_X86_ASM)
	__asm__ (
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "addl	%1, %0"
	    : "+&r"(i)







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# error No atomic operations available!
#endif
}

static OF_INLINE void*
of_atomic_add_ptr(void* volatile *p, intptr_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*(char* volatile*)p += i);
#elif defined(OF_X86_ASM)
	__asm__ (
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "addl	%1, %0"
	    : "+&r"(i)
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# error No atomic operations available!
#endif
}

static OF_INLINE int
of_atomic_sub_int(volatile int *p, int i)
{
#if !defined(OF_THREADS)
	return (*p -= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "negl	%0\n\t"
		    "lock\n\t"
		    "xaddl	%0, %2\n\t"







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# error No atomic operations available!
#endif
}

static OF_INLINE int
of_atomic_sub_int(volatile int *p, int i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p -= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "negl	%0\n\t"
		    "lock\n\t"
		    "xaddl	%0, %2\n\t"
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_sub_32(volatile int32_t *p, int32_t i)
{
#if !defined(OF_THREADS)
	return (*p -= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "negl	%0\n\t"
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "subl	%1, %0"







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_sub_32(volatile int32_t *p, int32_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p -= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "negl	%0\n\t"
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "subl	%1, %0"
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# error No atomic operations available!
#endif
}

static OF_INLINE void*
of_atomic_sub_ptr(void* volatile *p, intptr_t i)
{
#if !defined(OF_THREADS)
	return (*(char* volatile*)p -= i);
#elif defined(OF_X86_ASM)
	__asm__ (
	    "negl	%0\n\t"
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "subl	%1, %0"







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# error No atomic operations available!
#endif
}

static OF_INLINE void*
of_atomic_sub_ptr(void* volatile *p, intptr_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*(char* volatile*)p -= i);
#elif defined(OF_X86_ASM)
	__asm__ (
	    "negl	%0\n\t"
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "subl	%1, %0"
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# error No atomic operations available!
#endif
}

static OF_INLINE int
of_atomic_inc_int(volatile int *p)
{
#if !defined(OF_THREADS)
	return ++*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int i;

	if (sizeof(int) == 4)
		__asm__ (
		    "xorl	%0, %0\n\t"







|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# error No atomic operations available!
#endif
}

static OF_INLINE int
of_atomic_inc_int(volatile int *p)
{
#if !defined(OF_HAVE_THREADS)
	return ++*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int i;

	if (sizeof(int) == 4)
		__asm__ (
		    "xorl	%0, %0\n\t"
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_inc_32(volatile int32_t *p)
{
#if !defined(OF_THREADS)
	return ++*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	uint32_t i;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "incl	%0\n\t"







|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_inc_32(volatile int32_t *p)
{
#if !defined(OF_HAVE_THREADS)
	return ++*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	uint32_t i;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "incl	%0\n\t"
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# error No atomic operations available!
#endif
}

static OF_INLINE int
of_atomic_dec_int(volatile int *p)
{
#if !defined(OF_THREADS)
	return --*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int i;

	if (sizeof(int) == 4)
		__asm__ (
		    "xorl	%0, %0\n\t"







|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# error No atomic operations available!
#endif
}

static OF_INLINE int
of_atomic_dec_int(volatile int *p)
{
#if !defined(OF_HAVE_THREADS)
	return --*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int i;

	if (sizeof(int) == 4)
		__asm__ (
		    "xorl	%0, %0\n\t"
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_dec_32(volatile int32_t *p)
{
#if !defined(OF_THREADS)
	return --*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	uint32_t i;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "decl	%0\n\t"







|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# error No atomic operations available!
#endif
}

static OF_INLINE int32_t
of_atomic_dec_32(volatile int32_t *p)
{
#if !defined(OF_HAVE_THREADS)
	return --*p;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	uint32_t i;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "decl	%0\n\t"
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# error No atomic operations available!
#endif
}

static OF_INLINE unsigned int
of_atomic_or_int(volatile unsigned int *p, unsigned int i)
{
#if !defined(OF_THREADS)
	return (*p |= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "0:\n\t"
		    "movl	%2, %0\n\t"
		    "movl	%2, %%eax\n\t"







|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# error No atomic operations available!
#endif
}

static OF_INLINE unsigned int
of_atomic_or_int(volatile unsigned int *p, unsigned int i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p |= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "0:\n\t"
		    "movl	%2, %0\n\t"
		    "movl	%2, %%eax\n\t"
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# error No atomic operations available!
#endif
}

static OF_INLINE uint32_t
of_atomic_or_32(volatile uint32_t *p, uint32_t i)
{
#if !defined(OF_THREADS)
	return (*p |= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "0:\n\t"
	    "movl	%2, %0\n\t"
	    "movl	%2, %%eax\n\t"
	    "orl	%1, %0\n\t"







|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# error No atomic operations available!
#endif
}

static OF_INLINE uint32_t
of_atomic_or_32(volatile uint32_t *p, uint32_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p |= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "0:\n\t"
	    "movl	%2, %0\n\t"
	    "movl	%2, %%eax\n\t"
	    "orl	%1, %0\n\t"
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# error No atomic operations available!
#endif
}

static OF_INLINE unsigned int
of_atomic_and_int(volatile unsigned int *p, unsigned int i)
{
#if !defined(OF_THREADS)
	return (*p &= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "0:\n\t"
		    "movl	%2, %0\n\t"
		    "movl	%2, %%eax\n\t"







|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# error No atomic operations available!
#endif
}

static OF_INLINE unsigned int
of_atomic_and_int(volatile unsigned int *p, unsigned int i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p &= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "0:\n\t"
		    "movl	%2, %0\n\t"
		    "movl	%2, %%eax\n\t"
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# error No atomic operations available!
#endif
}

static OF_INLINE uint32_t
of_atomic_and_32(volatile uint32_t *p, uint32_t i)
{
#if !defined(OF_THREADS)
	return (*p &= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "0:\n\t"
	    "movl	%2, %0\n\t"
	    "movl	%2, %%eax\n\t"
	    "andl	%1, %0\n\t"







|







537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# error No atomic operations available!
#endif
}

static OF_INLINE uint32_t
of_atomic_and_32(volatile uint32_t *p, uint32_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p &= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "0:\n\t"
	    "movl	%2, %0\n\t"
	    "movl	%2, %%eax\n\t"
	    "andl	%1, %0\n\t"
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
# error No atomic operations available!
#endif
}

static OF_INLINE unsigned int
of_atomic_xor_int(volatile unsigned int *p, unsigned int i)
{
#if !defined(OF_THREADS)
	return (*p ^= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "0:\n\t"
		    "movl	%2, %0\n\t"
		    "movl	%2, %%eax\n\t"







|







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
# error No atomic operations available!
#endif
}

static OF_INLINE unsigned int
of_atomic_xor_int(volatile unsigned int *p, unsigned int i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p ^= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	if (sizeof(int) == 4)
		__asm__ (
		    "0:\n\t"
		    "movl	%2, %0\n\t"
		    "movl	%2, %%eax\n\t"
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
# error No atomic operations available!
#endif
}

static OF_INLINE uint32_t
of_atomic_xor_32(volatile uint32_t *p, uint32_t i)
{
#if !defined(OF_THREADS)
	return (*p ^= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "0:\n\t"
	    "movl	%2, %0\n\t"
	    "movl	%2, %%eax\n\t"
	    "xorl	%1, %0\n\t"







|







620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
# error No atomic operations available!
#endif
}

static OF_INLINE uint32_t
of_atomic_xor_32(volatile uint32_t *p, uint32_t i)
{
#if !defined(OF_HAVE_THREADS)
	return (*p ^= i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "0:\n\t"
	    "movl	%2, %0\n\t"
	    "movl	%2, %%eax\n\t"
	    "xorl	%1, %0\n\t"
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_int(volatile int *p, int o, int n)
{
#if !defined(OF_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
	}

	return NO;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)







|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_int(volatile int *p, int o, int n)
{
#if !defined(OF_HAVE_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
	}

	return NO;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_32(volatile int32_t *p, int32_t o, int32_t n)
{
#if !defined(OF_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
	}

	return NO;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)







|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_32(volatile int32_t *p, int32_t o, int32_t n)
{
#if !defined(OF_HAVE_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
	}

	return NO;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_ptr(void* volatile *p, void *o, void *n)
{
#if !defined(OF_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
	}

	return NO;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)







|







717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_ptr(void* volatile *p, void *o, void *n)
{
#if !defined(OF_HAVE_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
	}

	return NO;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)

Modified src/autorelease.m from [221156b5cb] to [fd89fce383].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

#include <stdio.h>
#include <stdlib.h>

#import "OFObject.h"
#import "OFSystemInfo.h"

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
# import "threading.h"
#endif
#import "macros.h"

#import "autorelease.h"

#if defined(OF_COMPILER_TLS)
static __thread id *objects = NULL;
static __thread id *top = NULL;
static __thread size_t size = 0;
#elif defined(OF_THREADS)
static of_tlskey_t objectsKey, topKey, sizeKey;
#else
static id *objects = NULL;
static id *top = NULL;
static size_t size = 0;
#endif

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
static void __attribute__((constructor))
init(void)
{
	OF_ENSURE(of_tlskey_new(&objectsKey));
	OF_ENSURE(of_tlskey_new(&topKey));
	OF_ENSURE(of_tlskey_new(&sizeKey));
}
#endif

void*
objc_autoreleasePoolPush()
{
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
#endif
	ptrdiff_t offset = top - objects;

	return (void*)offset;
}

void
objc_autoreleasePoolPop(void *offset)
{
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
#endif
	id *pool = objects + (ptrdiff_t)offset;
	id *iter;

	for (iter = pool; iter < top; iter++)
		[*iter release];

	top = pool;

	if (top == objects) {
		free(objects);

		objects = NULL;
		top = NULL;
	}

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	OF_ENSURE(of_tlskey_set(topKey, top));
	OF_ENSURE(of_tlskey_set(objectsKey, objects));
#endif
}

id
_objc_rootAutorelease(id object)
{
#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
	size_t size = (size_t)(uintptr_t)of_tlskey_get(sizeKey);
#endif

	if (objects == NULL) {
		size = [OFSystemInfo pageSize];

		OF_ENSURE((objects = malloc(size)) != NULL);

		top = objects;

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
#endif
	}

	if ((uintptr_t)top >= (uintptr_t)objects + size) {
		ptrdiff_t diff = top - objects;

		size += [OFSystemInfo pageSize];
		OF_ENSURE((objects = realloc(objects, size)) != NULL);

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
#endif

		top = objects + diff;
	}

	*top = object;
	top++;

#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS)
	OF_ENSURE(of_tlskey_set(topKey, top));
#endif

	return object;
}







|






|



|







|












|











|


















|








|












|











|










|





18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

#include <stdio.h>
#include <stdlib.h>

#import "OFObject.h"
#import "OFSystemInfo.h"

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
# import "threading.h"
#endif
#import "macros.h"

#import "autorelease.h"

#if defined(OF_HAVE_COMPILER_TLS)
static __thread id *objects = NULL;
static __thread id *top = NULL;
static __thread size_t size = 0;
#elif defined(OF_HAVE_THREADS)
static of_tlskey_t objectsKey, topKey, sizeKey;
#else
static id *objects = NULL;
static id *top = NULL;
static size_t size = 0;
#endif

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
static void __attribute__((constructor))
init(void)
{
	OF_ENSURE(of_tlskey_new(&objectsKey));
	OF_ENSURE(of_tlskey_new(&topKey));
	OF_ENSURE(of_tlskey_new(&sizeKey));
}
#endif

void*
objc_autoreleasePoolPush()
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
#endif
	ptrdiff_t offset = top - objects;

	return (void*)offset;
}

void
objc_autoreleasePoolPop(void *offset)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
#endif
	id *pool = objects + (ptrdiff_t)offset;
	id *iter;

	for (iter = pool; iter < top; iter++)
		[*iter release];

	top = pool;

	if (top == objects) {
		free(objects);

		objects = NULL;
		top = NULL;
	}

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OF_ENSURE(of_tlskey_set(topKey, top));
	OF_ENSURE(of_tlskey_set(objectsKey, objects));
#endif
}

id
_objc_rootAutorelease(id object)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
	size_t size = (size_t)(uintptr_t)of_tlskey_get(sizeKey);
#endif

	if (objects == NULL) {
		size = [OFSystemInfo pageSize];

		OF_ENSURE((objects = malloc(size)) != NULL);

		top = objects;

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
#endif
	}

	if ((uintptr_t)top >= (uintptr_t)objects + size) {
		ptrdiff_t diff = top - objects;

		size += [OFSystemInfo pageSize];
		OF_ENSURE((objects = realloc(objects, size)) != NULL);

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
#endif

		top = objects + diff;
	}

	*top = object;
	top++;

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OF_ENSURE(of_tlskey_set(topKey, top));
#endif

	return object;
}

Modified src/objfw-defs.h.in from [2392df0876] to [8a8805198b].

1
2
3
4
5
6


7
8
9
10

11
12
13
14
15
16
17
18
#undef OF_APPLE_RUNTIME
#undef OF_ATOMIC_OPS
#undef OF_BIG_ENDIAN
#undef OF_COMPILER_TLS
#undef OF_FLOAT_BIG_ENDIAN
#undef OF_HAVE_ASPRINTF


#undef OF_HAVE_GCC_ATOMIC_OPS
#undef OF_HAVE_OSATOMIC
#undef OF_HAVE_OSATOMIC_64
#undef OF_HAVE_PTHREADS

#undef OF_HAVE_PTHREAD_SPINLOCKS
#undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
#undef OF_HAVE_SCHED_YIELD
#undef OF_HAVE_SYS_SELECT_H
#undef OF_OBJFW_RUNTIME
#undef OF_PLUGINS
#undef OF_THREADS
#undef SIZE_MAX

<

<


>
>




>



|

<
<

1

2

3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
#undef OF_APPLE_RUNTIME

#undef OF_BIG_ENDIAN

#undef OF_FLOAT_BIG_ENDIAN
#undef OF_HAVE_ASPRINTF
#undef OF_HAVE_ATOMIC_OPS
#undef OF_HAVE_COMPILER_TLS
#undef OF_HAVE_GCC_ATOMIC_OPS
#undef OF_HAVE_OSATOMIC
#undef OF_HAVE_OSATOMIC_64
#undef OF_HAVE_PTHREADS
#undef OF_HAVE_PLUGINS
#undef OF_HAVE_PTHREAD_SPINLOCKS
#undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
#undef OF_HAVE_SCHED_YIELD
#undef OF_HAVE_THREADS
#undef OF_OBJFW_RUNTIME


#undef SIZE_MAX

Modified src/runtime/property.m from [cf5d45ddd2] to [cf0f60e388].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

#import "runtime.h"
#import "runtime-private.h"

#import "OFObject.h"

#import "macros.h"
#ifdef OF_THREADS
# import "threading.h"
# define NUM_SPINLOCKS 8	/* needs to be a power of 2 */
# define SPINLOCK_HASH(p) ((unsigned)((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1))
static of_spinlock_t spinlocks[NUM_SPINLOCKS];
#endif

#ifdef OF_THREADS
static void __attribute__((constructor))
init(void)
{
	size_t i;

	for (i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			OBJC_ERROR("Failed to initialize spinlocks!")
}
#endif

id
objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic)
{
	if (atomic) {
		id *ptr = (id*)(void*)((char*)self + offset);
#ifdef OF_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		@try {
			return [[*ptr retain] autorelease];
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));







|






|
















|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

#import "runtime.h"
#import "runtime-private.h"

#import "OFObject.h"

#import "macros.h"
#ifdef OF_HAVE_THREADS
# import "threading.h"
# define NUM_SPINLOCKS 8	/* needs to be a power of 2 */
# define SPINLOCK_HASH(p) ((unsigned)((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1))
static of_spinlock_t spinlocks[NUM_SPINLOCKS];
#endif

#ifdef OF_HAVE_THREADS
static void __attribute__((constructor))
init(void)
{
	size_t i;

	for (i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			OBJC_ERROR("Failed to initialize spinlocks!")
}
#endif

id
objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic)
{
	if (atomic) {
		id *ptr = (id*)(void*)((char*)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		@try {
			return [[*ptr retain] autorelease];
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

void
objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, BOOL atomic,
    signed char copy)
{
	if (atomic) {
		id *ptr = (id*)(void*)((char*)self + offset);
#ifdef OF_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		@try {
#endif
			id old = *ptr;

			switch (copy) {
			case 0:
				*ptr = [value retain];
				break;
			case 2:
				*ptr = [value mutableCopy];
				break;
			default:
				*ptr = [value copy];
			}

			[old release];
#ifdef OF_THREADS
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
		}
#endif

		return;
	}







|



















|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

void
objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, BOOL atomic,
    signed char copy)
{
	if (atomic) {
		id *ptr = (id*)(void*)((char*)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		@try {
#endif
			id old = *ptr;

			switch (copy) {
			case 0:
				*ptr = [value retain];
				break;
			case 2:
				*ptr = [value mutableCopy];
				break;
			default:
				*ptr = [value copy];
			}

			[old release];
#ifdef OF_HAVE_THREADS
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
		}
#endif

		return;
	}
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

/* The following methods are only required for GCC >= 4.6 */
void
objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic,
    BOOL strong)
{
	if (atomic) {
#ifdef OF_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif
		memcpy(dest, src, size);
#ifdef OF_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif

		return;
	}

	memcpy(dest, src, size);
}

void
objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic,
    BOOL strong)
{
	if (atomic) {
#ifdef OF_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif
		memcpy(dest, src, size);
#ifdef OF_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif

		return;
	}

	memcpy(dest, src, size);
}







|





|














|





|








119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

/* The following methods are only required for GCC >= 4.6 */
void
objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic,
    BOOL strong)
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif
		memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif

		return;
	}

	memcpy(dest, src, size);
}

void
objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic,
    BOOL strong)
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif
		memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif

		return;
	}

	memcpy(dest, src, size);
}

Modified src/runtime/runtime-private.h from [29ce1db052] to [c43269a3b6].

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    struct objc_sparsearray*);
extern void objc_sparsearray_set(struct objc_sparsearray*, uint32_t,
    const void*);
extern void objc_sparsearray_free(struct objc_sparsearray*);
extern void objc_sparsearray_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab*);
extern void __objc_exec_class(struct objc_abi_module*);
#ifdef OF_THREADS
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
#else
# define objc_global_mutex_lock()
# define objc_global_mutex_unlock()
# define objc_global_mutex_free()







|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    struct objc_sparsearray*);
extern void objc_sparsearray_set(struct objc_sparsearray*, uint32_t,
    const void*);
extern void objc_sparsearray_free(struct objc_sparsearray*);
extern void objc_sparsearray_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab*);
extern void __objc_exec_class(struct objc_abi_module*);
#ifdef OF_HAVE_THREADS
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
#else
# define objc_global_mutex_lock()
# define objc_global_mutex_unlock()
# define objc_global_mutex_free()

Modified src/runtime/synchronized.m from [f3cec63a98] to [fcacd220fc].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#include <stdio.h>
#include <stdlib.h>

#import "runtime.h"
#import "runtime-private.h"

#ifdef OF_THREADS
# import "threading.h"

struct lock_s {
	id	      object;
	int	      count;
	of_rmutex_t   rmutex;
	struct lock_s *next;







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#include <stdio.h>
#include <stdlib.h>

#import "runtime.h"
#import "runtime-private.h"

#ifdef OF_HAVE_THREADS
# import "threading.h"

struct lock_s {
	id	      object;
	int	      count;
	of_rmutex_t   rmutex;
	struct lock_s *next;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
		OBJC_ERROR("Failed to create mutex!")
}
#endif

int
objc_sync_enter(id object)
{
#ifdef OF_THREADS
	struct lock_s *lock;

	if (!of_mutex_lock(&mutex))
		OBJC_ERROR("Failed to lock mutex!");

	/* Look if we already have a lock */
	for (lock = locks; lock != NULL; lock = lock->next) {







|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
		OBJC_ERROR("Failed to create mutex!")
}
#endif

int
objc_sync_enter(id object)
{
#ifdef OF_HAVE_THREADS
	struct lock_s *lock;

	if (!of_mutex_lock(&mutex))
		OBJC_ERROR("Failed to lock mutex!");

	/* Look if we already have a lock */
	for (lock = locks; lock != NULL; lock = lock->next) {
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

	return 0;
}

int
objc_sync_exit(id object)
{
#ifdef OF_THREADS
	struct lock_s *lock, *last = NULL;

	if (!of_mutex_lock(&mutex))
		OBJC_ERROR("Failed to lock mutex!");

	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object) {







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

	return 0;
}

int
objc_sync_exit(id object)
{
#ifdef OF_HAVE_THREADS
	struct lock_s *lock, *last = NULL;

	if (!of_mutex_lock(&mutex))
		OBJC_ERROR("Failed to lock mutex!");

	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object) {

Modified src/threading.h from [f6862f572a] to [ba948db4c9].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "objfw-defs.h"


#if !defined(OF_THREADS) || (!defined(OF_HAVE_PTHREADS) && !defined(_WIN32))
# error No threads available!
#endif

#import "macros.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>







>
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "objfw-defs.h"

#if !defined(OF_HAVE_THREADS) || \
    (!defined(OF_HAVE_PTHREADS) && !defined(_WIN32))
# error No threads available!
#endif

#import "macros.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
typedef CRITICAL_SECTION of_mutex_t;
typedef struct {
	HANDLE event;
	int count;
} of_condition_t;
#endif

#if defined(OF_ATOMIC_OPS)
# import "atomic.h"
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
typedef pthread_spinlock_t of_spinlock_t;
#else
typedef of_mutex_t of_spinlock_t;







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
typedef CRITICAL_SECTION of_mutex_t;
typedef struct {
	HANDLE event;
	int count;
} of_condition_t;
#endif

#if defined(OF_HAVE_ATOMIC_OPS)
# import "atomic.h"
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
typedef pthread_spinlock_t of_spinlock_t;
#else
typedef of_mutex_t of_spinlock_t;
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
	return TlsFree(key);
#endif
}

static OF_INLINE BOOL
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_init(spinlock, 0);
#else
	return of_mutex_new(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_ATOMIC_OPS)
	return of_atomic_cmpswap_int(spinlock, 0, 1);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_trylock(spinlock);
#else
	return of_mutex_trylock(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_ATOMIC_OPS)
# if defined(OF_HAVE_SCHED_YIELD) || defined(_WIN32)
	int i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock))
			return YES;








|












|











|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
	return TlsFree(key);
#endif
}

static OF_INLINE BOOL
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_init(spinlock, 0);
#else
	return of_mutex_new(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return of_atomic_cmpswap_int(spinlock, 0, 1);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_trylock(spinlock);
#else
	return of_mutex_trylock(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
# if defined(OF_HAVE_SCHED_YIELD) || defined(_WIN32)
	int i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock))
			return YES;

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
	return of_mutex_lock(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_ATOMIC_OPS)
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}







|












|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
	return of_mutex_lock(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}

static OF_INLINE BOOL
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}

Modified tests/TestsAppDelegate.m from [f102ecba6b] to [573b357575].

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
	[self dictionaryTests];
	[self listTests];
	[self setTests];
	[self dateTests];
	[self numberTests];
	[self streamTests];
	[self TCPSocketTests];
#ifdef OF_THREADS
	[self threadTests];
#endif
	[self URLTests];
#ifdef OF_THREADS
	[self HTTPClientTests];
#endif
	[self XMLParserTests];
	[self XMLNodeTests];
	[self XMLElementBuilderTests];
	[self serializationTests];
	[self JSONTests];
#ifdef OF_PLUGINS
	[self pluginTests];
#endif
	[self forwardingTests];
#ifdef OF_HAVE_PROPERTIES
	[self propertiesTests];
#endif

	[OFApplication terminateWithStatus: fails];
}
@end







|



|







|










132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
	[self dictionaryTests];
	[self listTests];
	[self setTests];
	[self dateTests];
	[self numberTests];
	[self streamTests];
	[self TCPSocketTests];
#ifdef OF_HAVE_THREADS
	[self threadTests];
#endif
	[self URLTests];
#ifdef OF_HAVE_THREADS
	[self HTTPClientTests];
#endif
	[self XMLParserTests];
	[self XMLNodeTests];
	[self XMLElementBuilderTests];
	[self serializationTests];
	[self JSONTests];
#ifdef OF_HAVE_PLUGINS
	[self pluginTests];
#endif
	[self forwardingTests];
#ifdef OF_HAVE_PROPERTIES
	[self propertiesTests];
#endif

	[OFApplication terminateWithStatus: fails];
}
@end