Index: src/nonsfi/linux/linux_pthread_private.c |
diff --git a/src/nonsfi/linux/linux_pthread_private.c b/src/nonsfi/linux/linux_pthread_private.c |
index ed3eaa0d6ba76714b9e185514331f4cc3ee5781f..3fb9f2ea4fee25ab0059b46d977b5982ffba8a14 100644 |
--- a/src/nonsfi/linux/linux_pthread_private.c |
+++ b/src/nonsfi/linux/linux_pthread_private.c |
@@ -18,6 +18,8 @@ |
#include "native_client/src/untrusted/nacl/nacl_thread.h" |
#include "native_client/src/untrusted/pthread/pthread_internal.h" |
+struct nacl_irt_thread_v0_2 __libnacl_irt_thread_v0_2; |
+ |
/* Convert a return value of a Linux syscall to the one of an IRT call. */ |
static uint32_t irt_return_call(uintptr_t result) { |
if (linux_is_error_result(result)) |
@@ -25,15 +27,17 @@ static uint32_t irt_return_call(uintptr_t result) { |
return 0; |
} |
-static int nacl_irt_thread_create(void (*start_func)(void), void *stack, |
- void *thread_ptr) { |
+static int nacl_irt_thread_create_v0_2(void (*start_func)(void), void *stack, |
+ void *thread_ptr, |
+ nacl_irt_tid_t *child_tid) { |
/* |
* We do not use CLONE_CHILD_CLEARTID as we do not want any |
* non-private futex signaling. Also, NaCl ABI does not require us |
* to signal the futex on stack_flag. |
*/ |
int flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
- CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS); |
+ CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | |
+ CLONE_PARENT_SETTID); |
/* |
* linux_clone_wrapper expects start_func's type is "int (*)(void *)". |
* Although |start_func| has type "void (*)(void)", the type mismatching |
@@ -42,7 +46,13 @@ static int nacl_irt_thread_create(void (*start_func)(void), void *stack, |
*/ |
return irt_return_call(linux_clone_wrapper( |
(uintptr_t) start_func, /* arg */ 0, flags, stack, |
- /* ptid */ NULL, thread_ptr, /* ctid */ NULL)); |
+ child_tid, thread_ptr, /* ctid */ NULL)); |
+} |
+ |
+static int nacl_irt_thread_create(void (*start_func)(void), void *stack, |
+ void *thread_ptr) { |
+ nacl_irt_tid_t child_tid; |
+ return nacl_irt_thread_create_v0_2(start_func, stack, thread_ptr, &child_tid); |
} |
static void nacl_irt_thread_exit(int32_t *stack_flag) { |
@@ -120,7 +130,7 @@ static void irt_start_thread() { |
* Based on code from src/untrusted/irt/irt_thread.c |
*/ |
int nacl_user_thread_create(void *(*start_func)(void *), void *stack, |
- void *thread_ptr) { |
+ void *thread_ptr, nacl_irt_tid_t *child_tid) { |
struct nc_combined_tdb *tdb; |
/* |
@@ -145,7 +155,8 @@ int nacl_user_thread_create(void *(*start_func)(void *), void *stack, |
tdb->tdb.start_func = start_func; |
tdb->tdb.state = thread_ptr; |
- return nacl_irt_thread_create(irt_start_thread, stack, irt_tp); |
+ return nacl_irt_thread_create_v0_2(irt_start_thread, stack, irt_tp, |
+ child_tid); |
} |
/* |
@@ -176,4 +187,10 @@ void __nc_initialize_interfaces(void) { |
nacl_irt_thread_nice, |
}; |
__libnacl_irt_thread = init; |
+ const struct nacl_irt_thread_v0_2 init_v0_2 = { |
+ nacl_irt_thread_create_v0_2, |
+ nacl_irt_thread_exit, |
+ nacl_irt_thread_nice, |
+ }; |
+ __libnacl_irt_thread_v0_2 = init_v0_2; |
} |