ObjFW  Check-in [85b8efadbc]

Overview
Comment:Fix --disable-threads.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 85b8efadbce4c5a6f4da22ff1eef57a9555b92ef14b4aef50d8be8e58e6ec9cb
User & Date: js on 2013-01-12 20:21:17
Other Links: manifest | tags
Context
2013-01-12
20:32
Fix code used when atomic ops are unavailable. check-in: 20aea410be user: js tags: trunk
20:21
Fix --disable-threads. check-in: 85b8efadbc user: js tags: trunk
18:52
Better way to conditionally compile files. check-in: 9c2c934851 user: js tags: trunk
Changes

Modified Doxyfile from [35f708c3da] to [295329e516].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
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_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_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 src/OFApplication.m from [acafbd9a66] to [9620cd4f32].

22
23
24
25
26
27
28

29

30
31
32

33
34
35
36
37
38
39

#include <signal.h>

#import "OFApplication.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFDictionary.h"

#import "OFThread.h"

#import "OFRunLoop.h"

#import "autorelease.h"


#if defined(__MACH__) && !defined(OF_IOS)
# include <crt_externs.h>
#elif defined(_WIN32)
# include <windows.h>

extern int _CRT_glob;







>
|
>



>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#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"

#if defined(__MACH__) && !defined(OF_IOS)
# include <crt_externs.h>
#elif defined(_WIN32)
# include <windows.h>

extern int _CRT_glob;
373
374
375
376
377
378
379

380
381




382
383
384
385
386
387
388
389
}

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


	[OFThread OF_createMainThread];
	runLoop = [OFRunLoop currentRunLoop];




	[OFRunLoop OF_setMainRunLoop];

	objc_autoreleasePoolPop(pool);

	pool = objc_autoreleasePoolPush();
	[delegate applicationDidFinishLaunching];
	objc_autoreleasePoolPop(pool);








>


>
>
>
>
|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
}

- (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];

	objc_autoreleasePoolPop(pool);

	pool = objc_autoreleasePoolPush();
	[delegate applicationDidFinishLaunching];
	objc_autoreleasePoolPop(pool);

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

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

#include <stdlib.h>

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

#import "macros.h"
#ifndef OF_COMPILER_TLS
# import "threading.h"

# import "OFInitializationFailedException.h"
#endif

#import "autorelease.h"

#define MAX_CACHE_SIZE 0x20

#ifdef OF_COMPILER_TLS
static __thread OFAutoreleasePool **cache = NULL;


#else
static of_tlskey_t cacheKey;
#endif

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

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

+ alloc
{
#ifndef OF_COMPILER_TLS
	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_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++) {
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
139
140
141
- (void)drain
{
	[self dealloc];
}

- (void)dealloc
{
#ifndef OF_COMPILER_TLS
	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);

#ifndef OF_COMPILER_TLS
		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_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
	}

Modified src/OFBlock.m from [9f16b74f72] to [7f1306bf32].

17
18
19
20
21
22
23

24
25
26
27
28
29
30
#include "config.h"

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#if defined(OF_OBJFW_RUNTIME)

# import "runtime-private.h"
#elif defined(OF_APPLE_RUNTIME)
# import <objc/runtime.h>
#endif

#import "OFBlock.h"








>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "config.h"

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#if defined(OF_OBJFW_RUNTIME)
# import "runtime.h"
# import "runtime-private.h"
#elif defined(OF_APPLE_RUNTIME)
# import <objc/runtime.h>
#endif

#import "OFBlock.h"

Modified src/OFObject.h from [7c5fd9c3d2] to [a016fafbe2].

680
681
682
683
684
685
686

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


/*!
 * @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_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
 */
806
807
808
809
810
811
812

813
814
815
816
817
818
819
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay;


/*!
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned NO. It should return a target
 *	  to which the message should be forwarded.
 *
 * @note When the message should not be forwarded, you should not return nil,







>







807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay;
#endif

/*!
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned NO. It should return a target
 *	  to which the message should be forwarded.
 *
 * @note When the message should not be forwarded, you should not return nil,

Modified src/OFObject.m from [f14f82d06a] to [431202d1e9].

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"

#import "OFThread.h"

#import "OFRunLoop.h"
#import "OFAutoreleasePool.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"







>
|
>







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

#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"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
619
620
621
622
623
624
625

626
627
628
629
630
631
632
					 object: object1
					 object: object2
					repeats: NO];

	objc_autoreleasePoolPop(pool);
}


- (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_THREADS
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	  waitUntilDone: (BOOL)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
777
778
779
780
781
782
783

784
785
786
787
788
789
790
							  selector: selector
							    object: object1
							    object: object2
							   repeats: NO]];

	objc_autoreleasePoolPop(pool);
}


- (const char*)typeEncodingForSelector: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	return objc_get_type_encoding(object_getClass(self), selector);
#else
	Method m;







>







780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
							  selector: selector
							    object: object1
							    object: object2
							   repeats: NO]];

	objc_autoreleasePoolPop(pool);
}
#endif

- (const char*)typeEncodingForSelector: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	return objc_get_type_encoding(object_getClass(self), selector);
#else
	Method m;

Modified src/OFRunLoop.h from [2abdc87418] to [f2e88dae39].

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

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

@class OFSortedList;

@class OFMutex;

@class OFTimer;
@class OFMutableDictionary;

/*!
 * @brief A class providing a run loop for the application and its processes.
 */
@interface OFRunLoop: OFObject
{
	OFSortedList *timersQueue;

	OFMutex *timersQueueLock;

	OFStreamObserver *streamObserver;
	OFMutableDictionary *readQueues;
}

/*!
 * @brief Returns the main run loop.
 *
 * @return The main run loop
 */
+ (OFRunLoop*)mainRunLoop;

/*!
 * @brief Returns the run loop for the current thread.
 *
 * @return The run loop for the current thread
 */
+ (OFRunLoop*)currentRunLoop;

+ (void)OF_setMainRunLoop;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer







>

>









>

>


















|







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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

#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;
}

/*!
 * @brief Returns the main run loop.
 *
 * @return The main run loop
 */
+ (OFRunLoop*)mainRunLoop;

/*!
 * @brief Returns the run loop for the current thread.
 *
 * @return The run loop for the current thread
 */
+ (OFRunLoop*)currentRunLoop;

+ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer

Modified src/OFRunLoop.m from [37689eeb3f] to [1f0d5617f1].

16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
32

#include "config.h"

#include <assert.h>

#import "OFRunLoop.h"
#import "OFDictionary.h"

#import "OFThread.h"
#import "OFSortedList.h"

#import "OFMutex.h"
#import "OFTimer.h"
#import "OFDate.h"

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

static OFRunLoop *mainRunLoop = nil;







>
|
|
>
|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#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"

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

static OFRunLoop *mainRunLoop = nil;
132
133
134
135
136
137
138

139



140
141
142
143
144
145
146
147
148
149
150
151
152
153
+ (OFRunLoop*)mainRunLoop
{
	return [[mainRunLoop retain] autorelease];
}

+ (OFRunLoop*)currentRunLoop
{

	return [[OFThread currentThread] runLoop];



}

+ (void)OF_setMainRunLoop
{
	void *pool = objc_autoreleasePoolPush();
	mainRunLoop = [[self currentRunLoop] retain];
	objc_autoreleasePoolPop(pool);
}

#define ADD(type, code)							\
	void *pool = objc_autoreleasePoolPush();			\
	OFRunLoop *runLoop = [self currentRunLoop];			\
	OFList *queue = [runLoop->readQueues objectForKey: stream];	\
	type *queueItem;						\







>

>
>
>


|

<
|
<







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150

151
152
153
154
155
156
157
+ (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
{

	mainRunLoop = [runLoop retain];

}

#define ADD(type, code)							\
	void *pool = objc_autoreleasePoolPush();			\
	OFRunLoop *runLoop = [self currentRunLoop];			\
	OFList *queue = [runLoop->readQueues objectForKey: stream];	\
	type *queueItem;						\
281
282
283
284
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

- init
{
	self = [super init];

	@try {
		timersQueue = [[OFSortedList alloc] init];

		timersQueueLock = [[OFMutex alloc] init];


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

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

	return self;
}

- (void)dealloc
{
	[timersQueue release];

	[timersQueueLock release];

	[streamObserver release];
	[readQueues release];

	[super dealloc];
}

- (void)addTimer: (OFTimer*)timer
{

	[timersQueueLock lock];
	@try {

		[timersQueue insertObject: timer];

	} @finally {
		[timersQueueLock unlock];
	}


	[timer OF_setInRunLoop: self];

	[streamObserver cancel];
}

- (void)OF_removeTimer: (OFTimer*)timer
{

	[timersQueueLock lock];
	@try {

		of_list_object_t *iter;

		for (iter = [timersQueue firstListObject]; iter != NULL;
		    iter = iter->next) {
			if ([iter->object isEqual: timer]) {
				[timersQueue removeListObject: iter];
				break;
			}
		}

	} @finally {
		[timersQueueLock unlock];
	}

}

- (void)streamIsReadyForReading: (OFStream*)stream
{
	OFList *queue = [readQueues objectForKey: stream];
	of_list_object_t *listObject;








>

>
















>

>








>


>

>



>








>


>









>



>







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
361
362
363
364

- 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
{
	OFList *queue = [readQueues objectForKey: stream];
	of_list_object_t *listObject;

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
598
599
600

601
602

603

604
605
606

607
608
609
610
611
612
613
{
	for (;;) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;


		[timersQueueLock lock];
		@try {

			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;

		} @finally {
			[timersQueueLock unlock];
		}


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


		[timersQueueLock lock];
		@try {

			nextTimer = [[timersQueue firstObject] fireDate];

		} @finally {
			[timersQueueLock unlock];
		}


		/* Watch for stream events until the next timer is due */
		if (nextTimer != nil) {
			double timeout = [nextTimer timeIntervalSinceNow];

			if (timeout > 0)
				[streamObserver observeWithTimeout: timeout];







>


>














>



>




>


>

>



>







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
634
635
636
637
{
	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) {
			double timeout = [nextTimer timeIntervalSinceNow];

			if (timeout > 0)
				[streamObserver observeWithTimeout: timeout];

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

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;

@class OFMutex;


/*!
 * @brief A protocol that needs to be implemented by delegates for
 *	  OFStreamObserver.
 */
@protocol OFStreamObserverDelegate <OFObject>
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS







>

>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 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.
 */
@protocol OFStreamObserverDelegate <OFObject>
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
82
83
84
85
86
87
88

89

90
91
92
93
94
95
96
	OFMutableArray *queue;
	OFDataArray *queueInfo, *queueFDs;
	id <OFStreamObserverDelegate> delegate;
	int cancelFD[2];
#ifdef _WIN32
	struct sockaddr_in cancelAddr;
#endif

	OFMutex *mutex;

}

#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
99
100
	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

/*!

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

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
- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate_
{
	delegate = delegate_;
}

- (void)addStreamForReading: (OFStream*)stream
{

	[mutex lock];
	@try {

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

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

	} @finally {
		[mutex unlock];
	}


	[self cancel];
}

- (void)addStreamForWriting: (OFStream*)stream
{

	[mutex lock];
	@try {

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

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

	} @finally {
		[mutex unlock];
	}


	[self cancel];
}

- (void)removeStreamForReading: (OFStream*)stream
{

	[mutex lock];
	@try {

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

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

	} @finally {
		[mutex unlock];
	}


#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
{

	[mutex lock];
	@try {

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

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

	} @finally {
		[mutex unlock];
	}


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







>


>






>



>






>


>






>



>






>


>






>



>











>


>






>



>







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
- (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
286
287
288
289
290
291
292

293
294

295
296
297
298
299
300
301
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)OF_processQueue
{

	[mutex lock];
	@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];







>


>







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];
348
349
350
351
352
353
354

355
356
357

358
359
360
361
362
363
364
				assert(0);
			}
		}

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

	} @finally {
		[mutex unlock];
	}

}

- (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];
#ifdef OF_THREADS
	} @finally {
		[mutex unlock];
	}
#endif
}

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

Modified src/OFTCPSocket.h from [29c6e8f03f] to [e5d525cdbe].

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
162
163
164
165
 *
 * @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;


/*!
 * @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
 * @param selector The selector to call on the target. The signature must be
 *		   void (OFTCPSocket *socket, OFException *exception).
 */
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector;

#ifdef OF_HAVE_BLOCKS
/*!
 * @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 block The block to execute once the connection has been established
 */
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		     block: (of_tcpsocket_async_connect_block_t)block;

#endif

/*!
 * @brief Bind the socket on the specified port and host.
 *
 * @param host The host to bind to. Use @"0.0.0.0" for IPv4 or @"::" for IPv6
 *	       to bind to all.







>















|










>







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
162
163
164
165
166
167
 *
 * @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
 * @param selector The selector to call on the target. The signature must be
 *		   void (OFTCPSocket *socket, OFException *exception).
 */
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector;

# ifdef OF_HAVE_BLOCKS
/*!
 * @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 block The block to execute once the connection has been established
 */
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		     block: (of_tcpsocket_async_connect_block_t)block;
# endif
#endif

/*!
 * @brief Bind the socket on the specified port and host.
 *
 * @param host The host to bind to. Use @"0.0.0.0" for IPv4 or @"::" for IPv6
 *	       to bind to all.

Modified src/OFTCPSocket.m from [4724c73932] to [e458e43209].

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"

#import "OFThread.h"

#import "OFTimer.h"
#import "OFRunLoop.h"

#import "OFAcceptFailedException.h"
#import "OFAlreadyConnectedException.h"
#import "OFAddressTranslationFailedException.h"
#import "OFBindFailedException.h"







>
|
>







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 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"
#import "OFAddressTranslationFailedException.h"
#import "OFBindFailedException.h"
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
}

Class of_tls_socket_class = Nil;

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


@interface OFTCPSocket_ConnectThread: OFThread
{
	OFThread *sourceThread;
	OFTCPSocket *sock;
	OFString *host;
	uint16_t port;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_tcpsocket_async_connect_block_t connectBlock;
#endif
	OFException *exception;
}

- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector;
#ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		 block: (of_tcpsocket_async_connect_block_t)block;
#endif
@end

@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_







>








|

|









|





|







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
}

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;
	SEL selector;
# ifdef OF_HAVE_BLOCKS
	of_tcpsocket_async_connect_block_t connectBlock;
# endif
	OFException *exception;
}

- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		 block: (of_tcpsocket_async_connect_block_t)block;
# endif
@end

@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
		[self release];
		@throw e;
	}

	return self;
}

#ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_
		 block: (of_tcpsocket_async_connect_block_t)block_
{
	self = [super init];







|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
		[self release];
		@throw e;
	}

	return self;
}

# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_
		 block: (of_tcpsocket_async_connect_block_t)block_
{
	self = [super init];
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
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#endif

- (void)dealloc
{
	[sourceThread release];
	[sock release];
	[host release];
	[target release];
#ifdef OF_HAVE_BLOCKS
	[connectBlock release];
#endif
	[exception release];

	[super dealloc];
}

- (void)didConnect
{
	[self join];

#ifdef OF_HAVE_BLOCKS
	if (connectBlock != NULL)
		connectBlock(sock, exception);
	else {
#endif
		void (*func)(id, SEL, OFTCPSocket*, OFException*) =
		    (void(*)(id, SEL, OFTCPSocket*, OFException*))[target
		    methodForSelector: selector];

		func(target, selector, sock, exception);
#ifdef OF_HAVE_BLOCKS
	}
#endif
}

- (id)main
{
	void *pool = objc_autoreleasePoolPush();

	@try {







|







|

|









|



|





|

|







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
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
# endif

- (void)dealloc
{
	[sourceThread release];
	[sock release];
	[host release];
	[target release];
# ifdef OF_HAVE_BLOCKS
	[connectBlock release];
# endif
	[exception release];

	[super dealloc];
}

- (void)didConnect
{
	[self join];

# ifdef OF_HAVE_BLOCKS
	if (connectBlock != NULL)
		connectBlock(sock, exception);
	else {
# endif
		void (*func)(id, SEL, OFTCPSocket*, OFException*) =
		    (void(*)(id, SEL, OFTCPSocket*, OFException*))[target
		    methodForSelector: selector];

		func(target, selector, sock, exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

- (id)main
{
	void *pool = objc_autoreleasePoolPush();

	@try {
206
207
208
209
210
211
212

213
214
215
216
217
218
219
		waitUntilDone: NO];

	objc_autoreleasePoolPop(pool);

	return nil;
}
@end


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







>







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
		waitUntilDone: NO];

	objc_autoreleasePoolPop(pool);

	return nil;
}
@end
#endif

@implementation OFTCPSocket
#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO)
+ (void)initialize
{
	if (self == [OFTCPSocket class])
		mutex = [[OFMutex alloc] init];
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
				  port: port];

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


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

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			  target: target
			selector: selector] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

#ifdef OF_HAVE_BLOCKS
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		     block: (of_tcpsocket_async_connect_block_t)block
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			   block: block] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

#endif

- (uint16_t)bindToHost: (OFString*)host
		  port: (uint16_t)port
{
	const int one = 1;
	union {







>


















|















>







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
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
				  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();

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			  target: target
			selector: selector] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

# ifdef OF_HAVE_BLOCKS
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
		     block: (of_tcpsocket_async_connect_block_t)block
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			   block: block] autorelease] start];

	objc_autoreleasePoolPop(pool);
}
# endif
#endif

- (uint16_t)bindToHost: (OFString*)host
		  port: (uint16_t)port
{
	const int one = 1;
	union {

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

14
15
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

43


44
45
46
47
48
49
50
 * file.
 */

#import "OFObject.h"

@class OFTimer;
@class OFDate;
@class OFCondition;

@class OFRunLoop;


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

/*!
 * @brief A class for creating and firing timers.
 */
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *fireDate;
	double interval;
	id target, object1, object2;
	SEL selector;
	uint8_t arguments;
	BOOL repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t block;
#endif
	BOOL isValid, done;

	OFCondition *condition;


	OFRunLoop *inRunLoop;
}

#ifdef OF_HAVE_PROPERTIES
@property (retain) OFDate *fireDate;
#endif








|
>
|
>



















|
>

>
>







14
15
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
43
44
45
46
47
48
49
50
51
52
53
54
55
 * file.
 */

#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

/*!
 * @brief A class for creating and firing timers.
 */
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *fireDate;
	double interval;
	id target, object1, object2;
	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
@property (retain) OFDate *fireDate;
#endif

306
307
308
309
310
311
312

313
314
315
316

317
318
319
 *	  repeating timer.
 *
 * @return The time interval in which the timer will repeat, if it is a
 *	   repeating timer
 */
- (double)timeInterval;


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


- (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_THREADS
/*!
 * @brief Waits until the timer fired.
 */
- (void)waitUntilDone;
#endif

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

Modified src/OFTimer.m from [301033f339] to [1f8783cad4].

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"

#import "OFCondition.h"


#import "OFInvalidArgumentException.h"

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

@implementation OFTimer







>
|
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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"

@implementation OFTimer
231
232
233
234
235
236
237

238

239
240
241
242
243
244
245
		target = [target_ retain];
		selector = selector_;
		object1 = [object1_ retain];
		object2 = [object2_ retain];
		arguments = arguments_;
		repeats = repeats_;
		isValid = YES;

		condition = [[OFCondition alloc] init];

	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







>

>







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
		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;
	}

	return self;
}
305
306
307
308
309
310
311

312

313
314
315
316
317
318
319

	@try {
		fireDate = [fireDate_ retain];
		interval = interval_;
		repeats = repeats_;
		block = [block_ copy];
		isValid = YES;

		condition = [[OFCondition alloc] init];

	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







>

>







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

	@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;
	}

	return self;
}
330
331
332
333
334
335
336

337

338
339
340
341
342
343
344
	[fireDate release];
	[target release];
	[object1 release];
	[object2 release];
#ifdef OF_HAVE_BLOCKS
	[block release];
#endif

	[condition release];


	[super dealloc];
}

- (of_comparison_result_t)compare: (id <OFComparing>)object_
{
	OFTimer *otherTimer;







>

>







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
	[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_
{
	OFTimer *otherTimer;
376
377
378
379
380
381
382

383
384
385
386
387
388
389

390
391
392
393
394
395
396
				     withObject: object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif


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


	if (repeats && isValid) {
		OFDate *old = fireDate;
		fireDate = [[OFDate alloc]
		    initWithTimeIntervalSinceNow: interval];
		[old release];








>







>







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
				     withObject: object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

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

	if (repeats && isValid) {
		OFDate *old = fireDate;
		fireDate = [[OFDate alloc]
		    initWithTimeIntervalSinceNow: interval];
		[old release];

434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452
453
454

455
456
457
458
459
460
}

- (BOOL)isValid
{
	return isValid;
}


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

		[condition wait];
	} @finally {
		[condition unlock];
	}
}


- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop_
{
	OF_SETTER(inRunLoop, inRunLoop_, YES, 0)
}
@end







>














>






444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
}

- (BOOL)isValid
{
	return isValid;
}

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

		[condition wait];
	} @finally {
		[condition unlock];
	}
}
#endif

- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop_
{
	OF_SETTER(inRunLoop, inRunLoop_, YES, 0)
}
@end

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

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

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

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

#ifndef OF_COMPILER_TLS
# import "threading.h"
#endif
#import "macros.h"

#import "autorelease.h"

#ifdef OF_COMPILER_TLS
static __thread id *objects = NULL;
static __thread id *top = NULL;
static __thread size_t size = 0;


#else

static of_tlskey_t objectsKey, topKey, sizeKey;




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()
{
#ifndef OF_COMPILER_TLS
	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)
{
#ifndef OF_COMPILER_TLS
	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;
	}

#ifndef OF_COMPILER_TLS
	OF_ENSURE(of_tlskey_set(topKey, top));
	OF_ENSURE(of_tlskey_set(objectsKey, objects));
#endif
}

id
_objc_rootAutorelease(id object)
{
#ifndef OF_COMPILER_TLS
	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;

#ifndef OF_COMPILER_TLS
		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);

#ifndef OF_COMPILER_TLS
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
#endif

		top = objects + diff;
	}

	*top = object;
	top++;

#ifndef OF_COMPILER_TLS
	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_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;
}

Modified src/exceptions/Makefile from [de8d20daa5] to [08074185ef].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
include ../../extra.mk

STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
STATIC_LIB_NOINST = ${EXCEPTIONS_A}

SRCS = OFAcceptFailedException.m		\
       OFAddressTranslationFailedException.m	\
       OFAllocFailedException.m			\
       OFAlreadyConnectedException.m		\
       OFBindFailedException.m			\
       OFChangeDirectoryFailedException.m	\
       OFChangeFileModeFailedException.m	\
       OFChangeFileOwnerFailedException.m	\
       OFConditionBroadcastFailedException.m	\
       OFConditionSignalFailedException.m	\
       OFConditionStillWaitingException.m	\
       OFConditionWaitFailedException.m		\
       OFConnectionFailedException.m		\
       OFCopyFileFailedException.m		\
       OFCreateDirectoryFailedException.m	\
       OFDeleteDirectoryFailedException.m	\
       OFDeleteFileFailedException.m		\
       OFEnumerationMutationException.m		\
       OFException.m				\













<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13




14
15
16
17
18
19
20
include ../../extra.mk

STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
STATIC_LIB_NOINST = ${EXCEPTIONS_A}

SRCS = OFAcceptFailedException.m		\
       OFAddressTranslationFailedException.m	\
       OFAllocFailedException.m			\
       OFAlreadyConnectedException.m		\
       OFBindFailedException.m			\
       OFChangeDirectoryFailedException.m	\
       OFChangeFileModeFailedException.m	\
       OFChangeFileOwnerFailedException.m	\




       OFConnectionFailedException.m		\
       OFCopyFileFailedException.m		\
       OFCreateDirectoryFailedException.m	\
       OFDeleteDirectoryFailedException.m	\
       OFDeleteFileFailedException.m		\
       OFEnumerationMutationException.m		\
       OFException.m				\
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58








59
60
61
62
63
64
65
       OFReadFailedException.m			\
       OFReadOrWriteFailedException.m		\
       OFRenameFileFailedException.m		\
       OFSeekFailedException.m			\
       OFSetOptionFailedException.m		\
       OFStillLockedException.m			\
       OFSymlinkFailedException.m		\
       OFThreadJoinFailedException.m		\
       OFThreadStartFailedException.m		\
       OFThreadStillRunningException.m		\
       OFTruncatedDataException.m		\
       OFUnboundNamespaceException.m		\
       OFUnlockFailedException.m		\
       OFUnsupportedProtocolException.m		\
       OFUnsupportedVersionException.m		\
       OFWriteFailedException.m









INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I.. -I../.. -I../runtime
LD = ${OBJC}







<
<
<





|
>
>
>
>
>
>
>
>







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
       OFReadFailedException.m			\
       OFReadOrWriteFailedException.m		\
       OFRenameFileFailedException.m		\
       OFSeekFailedException.m			\
       OFSetOptionFailedException.m		\
       OFStillLockedException.m			\
       OFSymlinkFailedException.m		\



       OFTruncatedDataException.m		\
       OFUnboundNamespaceException.m		\
       OFUnlockFailedException.m		\
       OFUnsupportedProtocolException.m		\
       OFUnsupportedVersionException.m		\
       OFWriteFailedException.m			\
       ${USE_SRCS_THREADS}
SRCS_THREADS = OFConditionBroadcastFailedException.m	\
	       OFConditionSignalFailedException.m	\
	       OFConditionStillWaitingException.m	\
	       OFConditionWaitFailedException.m		\
	       OFThreadJoinFailedException.m		\
	       OFThreadStartFailedException.m		\
	       OFThreadStillRunningException.m

INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I.. -I../.. -I../runtime
LD = ${OBJC}

Modified src/runtime/Makefile from [6581fa5019] to [a83e963f98].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
       ${LOOKUP_S}		\
       property.m		\
       protocol.m		\
       selector.m		\
       sparsearray.m		\
       static-instances.m	\
       synchronized.m		\

       threading.m
INCLUDES = runtime.h

include ../../buildsys.mk

CPPFLAGS += -I. -I.. -I../..
LD = ${OBJC}







>
|






13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
       ${LOOKUP_S}		\
       property.m		\
       protocol.m		\
       selector.m		\
       sparsearray.m		\
       static-instances.m	\
       synchronized.m		\
       ${USE_SRCS_THREADS}
SRCS_THREADS = threading.m
INCLUDES = runtime.h

include ../../buildsys.mk

CPPFLAGS += -I. -I.. -I../..
LD = ${OBJC}

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

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * 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 "threading.h"

struct objc_abi_class {
	struct objc_abi_class *metaclass;
	const char *superclass;
	const char *name;
	unsigned long version;
	unsigned long info;







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * 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.
 */

#include "config.h"

struct objc_abi_class {
	struct objc_abi_class *metaclass;
	const char *superclass;
	const char *name;
	unsigned long version;
	unsigned long info;
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#else
struct objc_sparsearray_level2 {
	const void *buckets[256];
	BOOL empty;
};
#endif

typedef struct {
	of_mutex_t mutex;
	of_thread_t owner;
	int count;
} objc_mutex_t;

extern void objc_register_all_categories(struct objc_abi_symtab*);
extern struct objc_category** objc_categories_for_class(Class);
extern void objc_free_all_categories(void);
extern void objc_initialize_class(Class);
extern void objc_update_dtable(Class);
extern void objc_register_all_classes(struct objc_abi_symtab*);
extern Class objc_classname_to_class(const char*);







<
<
<
<
<
<







119
120
121
122
123
124
125






126
127
128
129
130
131
132
#else
struct objc_sparsearray_level2 {
	const void *buckets[256];
	BOOL empty;
};
#endif







extern void objc_register_all_categories(struct objc_abi_symtab*);
extern struct objc_category** objc_categories_for_class(Class);
extern void objc_free_all_categories(void);
extern void objc_initialize_class(Class);
extern void objc_update_dtable(Class);
extern void objc_register_all_classes(struct objc_abi_symtab*);
extern Class objc_classname_to_class(const char*);
151
152
153
154
155
156
157

158
159
160





161
162
163
164
165
166
167
    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*);

extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);






static inline void*
objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx)
{
#ifdef OF_SELUID24
	uint8_t i = idx >> 16;
	uint8_t j = idx >>  8;







>



>
>
>
>
>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    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()
#endif

static inline void*
objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx)
{
#ifdef OF_SELUID24
	uint8_t i = idx >> 16;
	uint8_t j = idx >>  8;

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

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
43
44

45
46
47
48
49
50
51
#include "config.h"

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

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


#import "threading.h"

struct lock_s {
	id	      object;
	int	      count;
	of_rmutex_t   rmutex;
	struct lock_s *next;
} *locks = NULL;

static of_mutex_t mutex;

static void __attribute__((constructor))
init(void)
{
	if (!of_mutex_new(&mutex))
		OBJC_ERROR("Failed to create mutex!")
}


int
objc_sync_enter(id object)
{

	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) {







>
>
|
















>




>







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
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "config.h"

#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;
} *locks = NULL;

static of_mutex_t mutex;

static void __attribute__((constructor))
init(void)
{
	if (!of_mutex_new(&mutex))
		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) {
77
78
79
80
81
82
83

84
85
86
87
88
89
90

91
92
93
94
95
96
97
	locks = lock;

	if (!of_mutex_unlock(&mutex))
		OBJC_ERROR("Failed to unlock mutex!");

	if (!of_rmutex_lock(&lock->rmutex))
		OBJC_ERROR("Failed to lock mutex!");


	return 0;
}

int
objc_sync_exit(id object)
{

	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) {







>







>







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
	locks = lock;

	if (!of_mutex_unlock(&mutex))
		OBJC_ERROR("Failed to unlock mutex!");

	if (!of_rmutex_lock(&lock->rmutex))
		OBJC_ERROR("Failed to lock mutex!");
#endif

	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) {
117
118
119
120
121
122
123



124
		if (!of_mutex_unlock(&mutex))
			OBJC_ERROR("Failed to unlock mutex!");

		return 0;
	}

	OBJC_ERROR("objc_sync_exit() was called for an object not locked!");



}







>
>
>

123
124
125
126
127
128
129
130
131
132
133
		if (!of_mutex_unlock(&mutex))
			OBJC_ERROR("Failed to unlock mutex!");

		return 0;
	}

	OBJC_ERROR("objc_sync_exit() was called for an object not locked!");
#else
	return 0;
#endif
}