summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/OFThread.m28
-rw-r--r--src/threading.h11
2 files changed, 39 insertions, 0 deletions
diff --git a/src/OFThread.m b/src/OFThread.m
index c8f163d5..a772a06a 100644
--- a/src/OFThread.m
+++ b/src/OFThread.m
@@ -23,6 +23,10 @@
# include <windows.h>
#endif
+#if defined(OF_GNU_RUNTIME) || defined(OF_OLD_GNU_RUNTIME)
+# import <objc/thr.h>
+#endif
+
#import "OFThread.h"
#import "OFList.h"
#import "OFDate.h"
@@ -51,6 +55,10 @@ static of_tlskey_t thread_self;
static id
call_main(id obj)
{
+#if defined(OF_GNU_RUNTIME) || defined(OF_OLD_GNU_RUNTIME)
+ objc_thread_add();
+#endif
+
if (!of_tlskey_set(thread_self, obj))
@throw [OFInitializationFailedException
newWithClass: [obj class]];
@@ -70,6 +78,10 @@ call_main(id obj)
[obj release];
+#if defined(OF_GNU_RUNTIME) || defined(OF_OLD_GNU_RUNTIME)
+ objc_thread_remove();
+#endif
+
return 0;
}
@@ -209,6 +221,10 @@ call_main(id obj)
[thread release];
+#if defined(OF_GNU_RUNTIME) || defined(OF_OLD_GNU_RUNTIME)
+ objc_thread_remove();
+#endif
+
of_thread_exit();
}
@@ -244,6 +260,11 @@ call_main(id obj)
@throw [OFThreadStillRunningException newWithClass: isa
thread: self];
+ if (running == OF_THREAD_WAITING_FOR_JOIN) {
+ of_thread_detach(thread);
+ [retval release];
+ }
+
[self retain];
if (!of_thread_new(&thread, call_main, self)) {
@@ -272,6 +293,13 @@ call_main(id obj)
@throw [OFThreadStillRunningException newWithClass: isa
thread: self];
+ /*
+ * We should not be running anymore, but call detach in order to free
+ * the resources.
+ */
+ if (running == OF_THREAD_WAITING_FOR_JOIN)
+ of_thread_detach(thread);
+
[object release];
[retval release];
diff --git a/src/threading.h b/src/threading.h
index 1f3969b6..afe5b235 100644
--- a/src/threading.h
+++ b/src/threading.h
@@ -91,6 +91,17 @@ of_thread_join(of_thread_t thread)
#endif
}
+static OF_INLINE BOOL
+of_thread_detach(of_thread_t thread)
+{
+#if defined(OF_HAVE_PTHREADS)
+ return !pthread_detach(thread);
+#elif defined(_WIN32)
+ /* FIXME */
+ return YES;
+#endif
+}
+
static OF_INLINE void
of_thread_exit()
{