Index: src/trusted/service_runtime/nacl_app_thread.c |
diff --git a/src/trusted/service_runtime/nacl_app_thread.c b/src/trusted/service_runtime/nacl_app_thread.c |
index aecf3bc8e58fd37f2d90833aac4f845e2800becd..86bb5c1fa5ceeba511823c9b9bb85e9b8852b691 100644 |
--- a/src/trusted/service_runtime/nacl_app_thread.c |
+++ b/src/trusted/service_runtime/nacl_app_thread.c |
@@ -7,6 +7,9 @@ |
/* |
* NaCl Server Runtime user thread state. |
*/ |
+ |
+#include <string.h> |
+ |
#include "native_client/src/shared/platform/aligned_malloc.h" |
#include "native_client/src/shared/platform/nacl_check.h" |
#include "native_client/src/shared/platform/nacl_exit.h" |
@@ -21,10 +24,10 @@ |
#include "native_client/src/trusted/service_runtime/nacl_syscall_common.h" |
-void WINAPI NaClThreadLauncher(void *state) { |
+void WINAPI NaClAppThreadLauncher(void *state) { |
struct NaClAppThread *natp = (struct NaClAppThread *) state; |
uint32_t thread_idx; |
- NaClLog(4, "NaClThreadLauncher: entered\n"); |
+ NaClLog(4, "NaClAppThreadLauncher: entered\n"); |
NaClSignalStackRegister(natp->signal_stack); |
@@ -141,7 +144,6 @@ struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, |
uint32_t user_tls1, |
uint32_t user_tls2) { |
struct NaClAppThread *natp; |
- int rv; |
uint32_t tls_idx; |
natp = NaClAlignedMalloc(sizeof *natp, __alignof(struct NaClAppThread)); |
@@ -158,6 +160,8 @@ struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, |
*/ |
natp->nap = nap; |
natp->thread_num = -1; /* illegal index */ |
+ natp->host_thread_is_defined = 0; |
+ memset(&natp->host_thread, 0, sizeof(natp->host_thread)); |
/* |
* Even though we don't know what segment base/range should gs/r9/nacl_tls_idx |
@@ -198,16 +202,8 @@ struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, |
natp->fault_signal = 0; |
natp->dynamic_delete_generation = 0; |
+ return natp; |
- rv = NaClThreadCtor(&natp->thread, |
- NaClThreadLauncher, |
- (void *) natp, |
- NACL_KERN_STACK_SIZE); |
- if (rv != 0) { |
- return natp; /* Success */ |
- } |
- |
- NaClMutexDtor(&natp->suspend_mu); |
cleanup_mu: |
NaClMutexDtor(&natp->mu); |
if (NULL != natp->signal_stack) { |
@@ -220,14 +216,46 @@ struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, |
} |
+int NaClAppThreadSpawn(struct NaClApp *nap, |
+ uintptr_t usr_entry, |
+ uintptr_t usr_stack_ptr, |
+ uint32_t user_tls1, |
+ uint32_t user_tls2) { |
+ struct NaClAppThread *natp = NaClAppThreadMake(nap, usr_entry, usr_stack_ptr, |
+ user_tls1, user_tls2); |
+ if (natp == NULL) { |
+ return 0; |
+ } |
+ /* |
+ * We set host_thread_is_defined assuming, for now, that |
+ * NaClThreadCtor() will succeed. |
+ */ |
+ natp->host_thread_is_defined = 1; |
+ if (!NaClThreadCtor(&natp->host_thread, NaClAppThreadLauncher, (void *) natp, |
+ NACL_KERN_STACK_SIZE)) { |
+ /* |
+ * No other thread saw the NaClAppThread, so it is OK that |
+ * host_thread was not initialized despite host_thread_is_defined |
+ * being set. |
+ */ |
+ natp->host_thread_is_defined = 0; |
+ NaClAppThreadDelete(natp); |
+ return 0; |
+ } |
+ return 1; |
+} |
+ |
+ |
void NaClAppThreadDelete(struct NaClAppThread *natp) { |
/* |
* the thread must not be still running, else this crashes the system |
*/ |
+ if (natp->host_thread_is_defined) { |
+ NaClThreadDtor(&natp->host_thread); |
+ } |
free(natp->suspended_registers); |
NaClMutexDtor(&natp->suspend_mu); |
- NaClThreadDtor(&natp->thread); |
NaClSignalStackFree(natp->signal_stack); |
natp->signal_stack = NULL; |
NaClTlsFree(natp); |