Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoushik Dutta <koushd@gmail.com>2010-09-30 08:15:42 +0400
committerGeoff Norton <grompf@sublimeintervention.com>2010-10-01 20:33:18 +0400
commitc45cae8a26d869dc9db7513f0564229189ae03f7 (patch)
treea23cb453e48ea565b17eba17e3067116f788e673 /libgc/pthread_stop_world.c
parent0e8579212966de44911c628212ac321538890e9d (diff)
Work around Android's pthread/kernel_id/fork bug to fix mono multithreading and GC_stop_world in processes that have been forked.
Diffstat (limited to 'libgc/pthread_stop_world.c')
-rw-r--r--libgc/pthread_stop_world.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c
index 04eb3712c26..603aff78662 100644
--- a/libgc/pthread_stop_world.c
+++ b/libgc/pthread_stop_world.c
@@ -314,6 +314,22 @@ void GC_push_all_stacks()
pthread_t GC_stopping_thread;
int GC_stopping_pid;
+#ifdef PLATFORM_ANDROID
+int android_thread_kill(pid_t tid, int sig)
+{
+ int ret;
+ int old_errno = errno;
+
+ ret = tkill(tid, sig);
+ if (ret < 0) {
+ ret = errno;
+ errno = old_errno;
+ }
+
+ return ret;
+}
+#endif
+
/* We hold the allocation lock. Suspend all threads that might */
/* still be running. Return the number of suspend signals that */
/* were sent. */
@@ -337,8 +353,12 @@ int GC_suspend_all()
#if DEBUG_THREADS
GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
#endif
-
+
+#ifndef PLATFORM_ANDROID
result = pthread_kill(p -> id, SIG_SUSPEND);
+#else
+ result = android_thread_kill(p -> kernel_id, SIG_SUSPEND);
+#endif
switch(result) {
case ESRCH:
/* Not really there anymore. Possible? */
@@ -465,8 +485,12 @@ static void pthread_start_world()
#if DEBUG_THREADS
GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
#endif
-
+
+#ifndef PLATFORM_ANDROID
result = pthread_kill(p -> id, SIG_THR_RESTART);
+#else
+ result = android_thread_kill(p -> kernel_id, SIG_THR_RESTART);
+#endif
switch(result) {
case ESRCH:
/* Not really there anymore. Possible? */