Don't create thread at start
[nativeclient.git] / service_runtime / nacl_desc_base.c
blobd07e3f9cd211408f516d7f4d325cba7315d0f4ef
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 Service Runtime. I/O Descriptor / Handle abstraction. Memory
34 * mapping using descriptors.
37 #include <stdlib.h>
39 #include "native_client/include/portability.h"
41 #include "native_client/service_runtime/nacl_config.h"
42 #include "native_client/service_runtime/nacl_log.h"
43 #include "native_client/service_runtime/nacl_desc_base.h"
44 #include "native_client/service_runtime/nacl_sync_checked.h"
45 #include "native_client/service_runtime/sel_util.h"
48 * This file contains base class code for NaClDesc.
50 * The implementation for following subclasses are elsewhere, but here
51 * is an enumeration of them with a brief description:
53 * NaClDescIoDesc is the subclass that wraps host-OS descriptors
54 * provided by NaClHostDesc (which gives an OS-independent abstraction
55 * for host-OS descriptors).
57 * NaClDescImcDesc is the subclass that wraps IMC descriptors.
59 * NaClDescMutex and NaClDescCondVar are the subclasses that
60 * wrap the non-transferrable synchronization objects.
62 * These NaClDesc objects are impure in that they know about the
63 * virtual memory subsystem restriction of requiring mappings to occur
64 * in NACL_MAP_PAGESIZE (64KB) chunks, so the Map and Unmap virtual
65 * functions, at least, will enforce this restriction.
68 int NaClDescCtor(struct NaClDesc *ndp)
70 /* this should be a compile-time test */
71 if (0 != (sizeof(struct NaClInternalHeader) & 0xf)) {
72 NaClLog(LOG_FATAL,
73 "Internal error. NaClInternalHeader size not a"
74 " multiple of 16\n");
76 ndp->ref_count = 1;
77 return NaClMutexCtor(&ndp->mu);
80 void NaClDescDtor(struct NaClDesc *ndp)
82 if (0 != ndp->ref_count) {
83 NaClLog(LOG_FATAL, ("NaClDescDtor invoked on a generic descriptor"
84 " at 0x%08x with non-zero reference count (%d)\n"),
85 (uintptr_t) ndp,
86 ndp->ref_count);
88 NaClLog(4, "NaClDescDtor(0x%08x), refcount 0, destroying.\n",
89 (uintptr_t) ndp);
90 NaClMutexDtor(&ndp->mu);
93 struct NaClDesc *NaClDescRef(struct NaClDesc *ndp)
95 NaClLog(4, "NaClDescRef(0x%08x).\n",
96 (uintptr_t) ndp);
97 NaClXMutexLock(&ndp->mu);
98 if (0 == ++ndp->ref_count) {
99 NaClLog(LOG_FATAL, "NaClDescRef integer overflow\n");
101 NaClXMutexUnlock(&ndp->mu);
102 return ndp;
105 void NaClDescUnref(struct NaClDesc *ndp)
107 int destroy;
109 NaClLog(4, "NaClDescUnref(0x%08x).\n",
110 (uintptr_t) ndp);
111 NaClXMutexLock(&ndp->mu);
112 if (0 == ndp->ref_count) {
113 NaClLog(LOG_FATAL, "NaClDescUnref on 0x%08x, refcount already zero!\n",
114 (uintptr_t) ndp);
116 destroy = (0 == --ndp->ref_count);
117 NaClXMutexUnlock(&ndp->mu);
118 if (destroy) {
119 (*ndp->vtbl->Dtor)(ndp);
120 free(ndp);
124 int (*NaClDescInternalize[NACL_DESC_TYPE_MAX])(struct NaClDesc **,
125 struct NaClDescXferState *) = {
126 NaClDescDirInternalize,
127 NaClDescIoInternalize,
128 NaClDescConnCapInternalize,
129 NaClDescImcBoundDescInternalize,
130 NaClDescImcDescInternalize,
131 NaClDescImcShmInternalize,
132 NaClDescMutexInternalize,
133 NaClDescCondVarInternalize,
136 char const *NaClDescTypeString(enum NaClDescTypeTag type_tag)
138 /* default functions for the vtable - return NOT_IMPLEMENTED */
139 switch (type_tag) {
140 #define MAP(E) case E: do { return #E; } while (0)
141 MAP(NACL_DESC_DIR);
142 MAP(NACL_DESC_HOST_IO);
143 MAP(NACL_DESC_CONN_CAP);
144 MAP(NACL_DESC_BOUND_SOCKET);
145 MAP(NACL_DESC_CONNECTED_SOCKET);
146 MAP(NACL_DESC_SHM);
147 MAP(NACL_DESC_MUTEX);
148 MAP(NACL_DESC_CONDVAR);
149 MAP(NACL_DESC_SEMAPHORE);
151 return "BAD TYPE TAG";
153 void NaClDescDtorNotImplemented(struct NaClDesc *vself)
155 NaClLog(LOG_FATAL, "Must implement a destructor!\n");
158 int NaClDescMapNotImplemented(struct NaClDesc *vself,
159 struct NaClDescEffector *effp,
160 void *start_addr,
161 size_t len,
162 int prot,
163 int flags,
164 off_t offset)
166 NaClLog(LOG_ERROR,
167 "Map method is not implemented for object of type %s\n",
168 NaClDescTypeString(vself->vtbl->typeTag));
169 return -NACL_ABI_EINVAL;
172 int NaClDescUnmapUnsafeNotImplemented(struct NaClDesc *vself,
173 struct NaClDescEffector *effp,
174 void *start_addr,
175 size_t len)
177 NaClLog(LOG_ERROR,
178 "Map method is not implemented for object of type %s\n",
179 NaClDescTypeString(vself->vtbl->typeTag));
180 return -NACL_ABI_EINVAL;
183 int NaClDescUnmapNotImplemented(struct NaClDesc *vself,
184 struct NaClDescEffector *effp,
185 void *start_addr,
186 size_t len)
188 NaClLog(LOG_ERROR,
189 "Unmap method is not implemented for object of type %s\n",
190 NaClDescTypeString(vself->vtbl->typeTag));
191 return -NACL_ABI_EINVAL;
194 ssize_t NaClDescReadNotImplemented(struct NaClDesc *vself,
195 struct NaClDescEffector *effp,
196 void *buf,
197 size_t len)
199 NaClLog(LOG_ERROR,
200 "Read method is not implemented for object of type %s\n",
201 NaClDescTypeString(vself->vtbl->typeTag));
202 return -NACL_ABI_EINVAL;
205 ssize_t NaClDescWriteNotImplemented(struct NaClDesc *vself,
206 struct NaClDescEffector *effp,
207 void const *buf,
208 size_t len)
210 NaClLog(LOG_ERROR,
211 "Write method is not implemented for object of type %s\n",
212 NaClDescTypeString(vself->vtbl->typeTag));
213 return -NACL_ABI_EINVAL;
216 int NaClDescSeekNotImplemented(struct NaClDesc *vself,
217 struct NaClDescEffector *effp,
218 off_t offset,
219 int whence)
221 NaClLog(LOG_ERROR,
222 "Seek method is not implemented for object of type %s\n",
223 NaClDescTypeString(vself->vtbl->typeTag));
224 return -NACL_ABI_EINVAL;
227 int NaClDescIoctlNotImplemented(struct NaClDesc *vself,
228 struct NaClDescEffector *effp,
229 int request,
230 void *arg)
232 NaClLog(LOG_ERROR,
233 "Ioctl method is not implemented for object of type %s\n",
234 NaClDescTypeString(vself->vtbl->typeTag));
235 return -NACL_ABI_EINVAL;
238 int NaClDescFstatNotImplemented(struct NaClDesc *vself,
239 struct NaClDescEffector *effp,
240 struct nacl_abi_stat *statbuf)
242 NaClLog(LOG_ERROR,
243 "Fstat method is not implemented for object of type %s\n",
244 NaClDescTypeString(vself->vtbl->typeTag));
245 return -NACL_ABI_EINVAL;
248 int NaClDescCloseNotImplemented(struct NaClDesc *vself,
249 struct NaClDescEffector *effp)
251 NaClLog(LOG_ERROR,
252 "Close method is not implemented for object of type %s\n",
253 NaClDescTypeString(vself->vtbl->typeTag));
254 return -NACL_ABI_EINVAL;
257 ssize_t NaClDescGetdentsNotImplemented(struct NaClDesc *vself,
258 struct NaClDescEffector *effp,
259 void *dirp,
260 size_t count)
262 NaClLog(LOG_ERROR,
263 "Getdents method is not implemented for object of type %s\n",
264 NaClDescTypeString(vself->vtbl->typeTag));
265 return -NACL_ABI_EINVAL;
268 int NaClDescExternalizeSizeNotImplemented(struct NaClDesc *vself,
269 size_t *nbytes,
270 size_t *nhandles)
272 NaClLog(LOG_ERROR,
273 "ExternalizeSize method is not implemented for object of type %s\n",
274 NaClDescTypeString(vself->vtbl->typeTag));
275 return -NACL_ABI_EINVAL;
278 int NaClDescExternalizeNotImplemented(struct NaClDesc *vself,
279 struct NaClDescXferState *xfer)
281 NaClLog(LOG_ERROR,
282 "Externalize method is not implemented for object of type %s\n",
283 NaClDescTypeString(vself->vtbl->typeTag));
284 return -NACL_ABI_EINVAL;
287 int NaClDescLockNotImplemented(struct NaClDesc *vself,
288 struct NaClDescEffector *effp)
290 NaClLog(LOG_ERROR,
291 "Lock method is not implemented for object of type %s\n",
292 NaClDescTypeString(vself->vtbl->typeTag));
293 return -NACL_ABI_EINVAL;
296 int NaClDescTryLockNotImplemented(struct NaClDesc *vself,
297 struct NaClDescEffector *effp)
299 NaClLog(LOG_ERROR,
300 "TryLock method is not implemented for object of type %s\n",
301 NaClDescTypeString(vself->vtbl->typeTag));
302 return -NACL_ABI_EINVAL;
305 int NaClDescUnlockNotImplemented(struct NaClDesc *vself,
306 struct NaClDescEffector *effp)
308 NaClLog(LOG_ERROR,
309 "Unlock method is not implemented for object of type %s\n",
310 NaClDescTypeString(vself->vtbl->typeTag));
311 return -NACL_ABI_EINVAL;
314 int NaClDescWaitNotImplemented(struct NaClDesc *vself,
315 struct NaClDescEffector *effp,
316 struct NaClDesc *mutex)
318 NaClLog(LOG_ERROR,
319 "Wait method is not implemented for object of type %s\n",
320 NaClDescTypeString(vself->vtbl->typeTag));
321 return -NACL_ABI_EINVAL;
324 int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc *vself,
325 struct NaClDescEffector *effp,
326 struct NaClDesc *mutex,
327 struct nacl_abi_timespec *ts)
329 NaClLog(LOG_ERROR,
330 "TimedWaitAbs method is not implemented for object of type %s\n",
331 NaClDescTypeString(vself->vtbl->typeTag));
332 return -NACL_ABI_EINVAL;
335 int NaClDescSignalNotImplemented(struct NaClDesc *vself,
336 struct NaClDescEffector *effp)
338 NaClLog(LOG_ERROR,
339 "Signal method is not implemented for object of type %s\n",
340 NaClDescTypeString(vself->vtbl->typeTag));
341 return -NACL_ABI_EINVAL;
344 int NaClDescBroadcastNotImplemented(struct NaClDesc *vself,
345 struct NaClDescEffector *effp)
347 NaClLog(LOG_ERROR,
348 "Broadcast method is not implemented for object of type %s\n",
349 NaClDescTypeString(vself->vtbl->typeTag));
350 return -NACL_ABI_EINVAL;
353 int NaClDescSendMsgNotImplemented(struct NaClDesc *vself,
354 struct NaClDescEffector *effp,
355 struct NaClMessageHeader *dgram,
356 int flags)
358 NaClLog(LOG_ERROR,
359 "SendMsg method is not implemented for object of type %s\n",
360 NaClDescTypeString(vself->vtbl->typeTag));
361 return -NACL_ABI_EINVAL;
364 int NaClDescRecvMsgNotImplemented(struct NaClDesc *vself,
365 struct NaClDescEffector *effp,
366 struct NaClMessageHeader *dgram,
367 int flags)
369 NaClLog(LOG_ERROR,
370 "RecvMsg method is not implemented for object of type %s\n",
371 NaClDescTypeString(vself->vtbl->typeTag));
372 return -NACL_ABI_EINVAL;
375 int NaClDescConnectAddrNotImplemented(struct NaClDesc *vself,
376 struct NaClDescEffector *effp)
378 NaClLog(LOG_ERROR,
379 "ConnectAddr method is not implemented for object of type %s\n",
380 NaClDescTypeString(vself->vtbl->typeTag));
381 return -NACL_ABI_EINVAL;
384 int NaClDescAcceptConnNotImplemented(struct NaClDesc *vself,
385 struct NaClDescEffector *effp)
387 NaClLog(LOG_ERROR,
388 "AcceptConn method is not implemented for object of type %s\n",
389 NaClDescTypeString(vself->vtbl->typeTag));
390 return -NACL_ABI_EINVAL;
393 int NaClDescPostNotImplemented(struct NaClDesc *vself,
394 struct NaClDescEffector *effp)
396 NaClLog(LOG_ERROR,
397 "Post method is not implemented for object of type %s\n",
398 NaClDescTypeString(vself->vtbl->typeTag));
399 return -NACL_ABI_EINVAL;
402 int NaClDescSemWaitNotImplemented(struct NaClDesc *vself,
403 struct NaClDescEffector *effp)
405 NaClLog(LOG_ERROR,
406 "SemWait method is not implemented for object of type %s\n",
407 NaClDescTypeString(vself->vtbl->typeTag));
408 return -NACL_ABI_EINVAL;
411 int NaClDescGetValueNotImplemented(struct NaClDesc *vself,
412 struct NaClDescEffector *effp)
414 NaClLog(LOG_ERROR,
415 "GetValue method is not implemented for object of type %s\n",
416 NaClDescTypeString(vself->vtbl->typeTag));
417 return -NACL_ABI_EINVAL;