Don't create thread at start
[nativeclient.git] / service_runtime / linux / nacl_threads.c
blob1c0aa4cedf30906c9b9b4cc070c0f25f4cd7e102
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Server Runtime threads implementation layer.
36 /* get the XSI-compliant version of strerror_r */
37 #define _XOPEN_SOURCE 600
38 #include <string.h>
40 #include <stdlib.h>
41 #include <sys/types.h>
42 #include <signal.h>
43 #include <pthread.h>
44 #include <limits.h>
46 * PTHREAD_STACK_MIN should come from pthread.h as documented, but is
47 * actually pulled in by limits.h.
50 #include "native_client/service_runtime/nacl_config.h"
51 #include "native_client/service_runtime/nacl_threads.h"
52 #include "native_client/service_runtime/nacl_log.h"
54 #if NACL_KERN_STACK_SIZE < PTHREAD_STACK_MIN
55 # error "NaCl service runtime stack size is smaller than PTHREAD_STACK_MIN"
56 #endif
59 * Even if ctor fails, it should be okay -- and required -- to invoke
60 * the dtor on it.
62 int NaClThreadCtor(struct NaClThread *ntp,
63 void (*start_fn)(void *),
64 void *state,
65 size_t stack_size)
67 pthread_attr_t attr;
68 int code;
69 int rv;
70 char err_string[1024];
72 rv = 0;
74 if (stack_size < PTHREAD_STACK_MIN) {
75 stack_size = PTHREAD_STACK_MIN;
77 if (0 != (code = pthread_attr_init(&attr))) {
78 NaClLog(LOG_ERROR,
79 "NaClThreadCtor: pthread_atr_init returned %d",
80 code);
81 goto done;
83 if (0 != (code = pthread_attr_setstacksize(&attr, stack_size))) {
84 NaClLog(LOG_ERROR,
85 "NaClThreadCtor: pthread_attr_setstacksize returned %d (%s)",
86 code,
87 (strerror_r(code, err_string, sizeof err_string) == 0
88 ? err_string
89 : "UNKNOWN"));
90 goto done_attr_dtor;
92 if (0 !=
93 (code = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) {
94 NaClLog(LOG_ERROR,
95 "nacl_thread: pthread_attr_setdetachstate returned %d (%s)",
96 code,
97 (strerror_r(code, err_string, sizeof err_string) == 0
98 ? err_string
99 : "UNKNOWN"));
100 goto done_attr_dtor;
102 if (0 != (code = pthread_create(&ntp->tid,
103 &attr,
104 (void *(*)(void *)) start_fn,
105 state))) {
106 NaClLog(LOG_ERROR,
107 "nacl_thread: pthread_create returned %d (%s)",
108 code,
109 (strerror_r(code, err_string, sizeof err_string) == 0
110 ? err_string
111 : "UNKNOWN"));
112 goto done_attr_dtor;
114 rv = 1;
115 done_attr_dtor:
116 (void) pthread_attr_destroy(&attr); /* often a noop */
117 done:
118 return rv;
121 void NaClThreadDtor(struct NaClThread *ntp)
124 * The threads that we create are not joinable, and we cannot tell
125 * when they are truly gone. Fortunately, the threads themselves
126 * and the underlying thread library are responsible for ensuring
127 * that resources such as the thread stack are properly released.
131 void NaClThreadExit(void)
133 pthread_exit((void *) 0);
136 void NaClThreadKill(struct NaClThread *target)
138 pthread_kill(target->tid, SIGKILL);
141 int NaClTsdKeyCreate(struct NaClTsdKey *tsdp)
143 int errcode;
145 errcode = pthread_key_create(&tsdp->key, (void (*)(void *)) NULL);
146 /* returns zero on success, error code on failure */
147 if (0 != errcode) {
148 NaClLog(LOG_ERROR,
149 "NaClTsdKeyCreate: could not create new key, error code %d",
150 errcode);
152 return 0 == errcode;
155 int NaClTsdSetSpecific(struct NaClTsdKey *tsdp,
156 void const *ptr)
158 int errcode;
160 errcode = pthread_setspecific(tsdp->key, ptr);
161 /* returns zero on success, error code on failure */
162 if (0 != errcode) {
163 NaClLog(LOG_ERROR,
164 "NaClTsdSetSpecific: could not set new value, error code %d",
165 errcode);
167 return 0 == errcode;
170 void *NaClTsdGetSpecific(struct NaClTsdKey *tsdp)
172 return pthread_getspecific(tsdp->key);