ObjFW  Check-in [c9bea2982f]

Overview
Comment:Simplify autoreleasing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c9bea2982f3d1b2ce2b00c65e18caf054fa153f3f3f82614ff82cd54c49262a4
User & Date: js on 2012-09-17 09:30:38
Other Links: manifest | tags
Context
2012-09-17
10:11
OFTimer: Fix -[initWith...block:]. check-in: 1550e4988b user: js tags: trunk
09:30
Simplify autoreleasing. check-in: c9bea2982f user: js tags: trunk
06:59
Only schedule valid timers for repeating. check-in: 6673513f33 user: js tags: trunk
Changes

Modified src/OFApplication.m from [e32044da23] to [5bede79f26].

292
293
294
295
296
297
298
299

300
301
302
303
304


305
306
307
308
309
310
311
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313







-
+





+
+







	REGISTER_SIGNAL(SIGUSR2)
#endif
#undef REGISTER_SIGNAL
}

- (void)run
{
	void *pool;
	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);

	[runLoop run];
}

Modified src/OFAutoreleasePool.h from [cce576bf12] to [5fa48ae30d].

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
35
36
37
38
39
40
41


42
43
44
45
46
47
48







-
-







 *	  thread-specific autorelease pool stack.
 *
 * \param object The object to add to the autorelease pool
 * \return The object
 */
+ (id)addObject: (id)object;

+ (void)OF_releaseAll;

/**
 * \brief Releases all objects in the autorelease pool.
 *
 * This does not free the memory allocated to store pointers to the objects in
 * the pool, so reusing the pool does not allocate any memory until the previous
 * number of objects is exceeded. It behaves this way to optimize loops that
 * always work with the same or similar number of objects and call relaseObjects

Modified src/OFAutoreleasePool.m from [f049b285d4] to [b7dda03eca].

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







-


-
+

-
-
-
-
-
-
-
-
-
-
-
-
-








-
+







#endif

#import "autorelease.h"

#define MAX_CACHE_SIZE 0x20

#ifdef OF_COMPILER_TLS
static __thread void *first = NULL;
static __thread OFAutoreleasePool **cache = NULL;
#else
static of_tlskey_t firstKey, cacheKey;
static of_tlskey_t cacheKey;
#endif

id
of_autorelease(id object)
{
#ifndef OF_COMPILER_TLS
	void *first = of_tlskey_get(firstKey);
#endif

	if (first == NULL)
		[[OFAutoreleasePool alloc] init];

	return _objc_rootAutorelease(object);
}

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

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

+ alloc
{
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
72
73
74
75
76
77
78

79









80
81
82
83
84
85
86




87
88







89
90
91
92
93
94
95







-
+
-
-
-
-
-
-
-
-
-







-
-
-
-


-
-
-
-
-
-
-







	}

	return [super alloc];
}

+ (id)addObject: (id)object
{
	return of_autorelease(object);
	return _objc_rootAutorelease(object);
}

+ (void)OF_releaseAll
{
#ifndef OF_COMPILER_TLS
	void *first = of_tlskey_get(firstKey);
#endif

	objc_autoreleasePoolPop(first);
}

- init
{
	self = [super init];

	@try {
#ifndef OF_COMPILER_TLS
		void *first = of_tlskey_get(firstKey);
#endif

		pool = objc_autoreleasePoolPush();

		if (first == NULL)
#ifdef OF_COMPILER_TLS
			first = pool;
#else
			OF_ENSURE(of_tlskey_set(firstKey, pool));
#endif

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

	return self;
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
124
125
126
127
128
129
130








131
132
133
134
135
136
137







-
-
-
-
-
-
-
-







#endif

	if (ignoreRelease)
		return;

	ignoreRelease = YES;

#ifdef OF_COMPILER_TLS
	if (first == pool)
		first = NULL;
#else
	if (of_tlskey_get(firstKey) == pool)
		OF_ENSURE(of_tlskey_set(firstKey, NULL));
#endif

	objc_autoreleasePoolPop(pool);

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

#ifndef OF_COMPILER_TLS
		if (!of_tlskey_set(cacheKey, cache)) {

Modified src/OFObject.m from [5b25661283] to [13e68b8637].

939
940
941
942
943
944
945
946

947
948
949
950
951
952
953
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953







-
+







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

- autorelease
{
	return of_autorelease(self);
	return _objc_rootAutorelease(self);
}

- self
{
	return self;
}

Modified src/OFThread.m from [e8774af2ab] to [5df0e5d983].

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







+










+




+
+









-
-
-
+
+
-






+
+
+
+
+
+
-
+
+







#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"
#import "OFThreadJoinFailedException.h"
#import "OFThreadStartFailedException.h"
#import "OFThreadStillRunningException.h"

#import "atomic.h"
#import "autorelease.h"
#import "threading.h"

static OFList *TLSKeys;
static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static id
call_main(id object)
{
	OFThread *thread = (OFThread*)object;
	void *pool;

	if (!of_tlskey_set(threadSelfKey, thread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: [thread class]];

	pool = objc_autoreleasePoolPush();

	/*
	 * Nasty workaround for thread implementations which can't return a
	 * value on join.
	 */
#ifdef OF_HAVE_BLOCKS
	if (thread->block != NULL)
		thread->returnValue = [thread->block(thread->object) retain];
	else
		thread->returnValue = [[thread main] retain];
#else
	thread->returnValue = [[thread main] retain];
#endif
		thread->returnValue = [[thread main] retain];
#endif

	[thread handleTermination];

	thread->running = OF_THREAD_WAITING_FOR_JOIN;

	[OFTLSKey callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
	/*
	 * As the values returned by objc_autoreleasePoolPush() in the ObjFW
	 * runtime are not actually pointers, but sequential numbers, 0 means
	 * we pop everything.
	 */
	[OFAutoreleasePool OF_releaseAll];
	objc_autoreleasePoolPop(0);
#endif

	[thread release];

	return 0;
}

@implementation OFThread
220
221
222
223
224
225
226






227


228
229
230
231
232
233
234
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250







+
+
+
+
+
+
-
+
+








		[thread handleTermination];

		thread->running = OF_THREAD_WAITING_FOR_JOIN;
	}

	[OFTLSKey callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
	/*
	 * As the values returned by objc_autoreleasePoolPush() in the ObjFW
	 * runtime are not actually pointers, but sequential numbers, 0 means
	 * we pop everything.
	 */
	[OFAutoreleasePool OF_releaseAll];
	objc_autoreleasePoolPop(0);
#endif

	[thread release];

	of_thread_exit();
}

+ (void)OF_createMainThread

Modified src/exceptions/OFException.m from [e04692d9ff] to [32b20ebef7].

58
59
60
61
62
63
64
65

66
67
68
69
70
58
59
60
61
62
63
64

65
66
67
68
69
70







-
+






- (OFString*)description
{
	if (description != nil)
		return description;

	description = [[OFString alloc] initWithFormat:
	    @"An exception of class %@ occurred in class %@",
	    @"An exception of class %@ occurred in class %@!",
	    object_getClass(self), inClass];

	return description;
}
@end