LCOV - code coverage report
Current view: directory - src/trusted/threading - nacl_thread_interface.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 101 90 89.1 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : #include "native_client/src/trusted/threading/nacl_thread_interface.h"
       8                 : 
       9                 : #include "native_client/src/include/nacl_compiler_annotations.h"
      10                 : 
      11                 : #include "native_client/src/shared/platform/nacl_check.h"
      12                 : #include "native_client/src/shared/platform/nacl_log.h"
      13                 : #include "native_client/src/shared/platform/nacl_threads.h"
      14                 : #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
      15                 : 
      16             546 : void WINAPI NaClThreadInterfaceStart(void *data) {
      17             546 :   struct NaClThreadInterface  *tif =
      18                 :       (struct NaClThreadInterface *) data;
      19             546 :   void                        *thread_return;
      20                 : 
      21             546 :   NaClLog(4,
      22                 :           ("Entered NaClThreadInterfaceStart: thread object 0x%"NACL_PRIxPTR
      23                 :            " starting.\n"),
      24                 :           (uintptr_t) tif);  /* NaClThreadId() implicitly printed */
      25             546 :   (*NACL_VTBL(NaClThreadInterface, tif)->LaunchCallback)(tif);
      26             546 :   thread_return = (*tif->fn_ptr)(tif);
      27             546 :   NaClLog(4,
      28                 :           ("NaClThreadInterfaceStart: thread object 0x%"NACL_PRIxPTR
      29                 :            " returned 0x%"NACL_PRIxPTR".\n"),
      30                 :           (uintptr_t) tif,
      31                 :           (uintptr_t) thread_return);  /* NaClThreadId() implicitly printed */
      32             546 :   (*NACL_VTBL(NaClThreadInterface, tif)->Exit)(tif, thread_return);
      33             546 :   NaClLog(LOG_FATAL,
      34                 :           "NaClThreadInterface: Exit member function did not exit thread\n");
      35             546 : }
      36                 : 
      37                 : int NaClThreadInterfaceCtor_protected(
      38             546 :     struct NaClThreadInterface    *self,
      39             546 :     NaClThreadIfFactoryFunction   factory,
      40             546 :     void                          *factory_data,
      41             546 :     NaClThreadIfStartFunction     fn_ptr,
      42             546 :     void                          *thread_data,
      43             546 :     size_t                        thread_stack_size) {
      44                 : 
      45             546 :   NaClLog(3, "Entered NaClThreadInterfaceThreadPlacementFactory\n");
      46             546 :   if (!NaClRefCountCtor((struct NaClRefCount *) self)) {
      47               0 :     NaClLog(3,
      48                 :             "NaClThreadInterfaceThreadPlacementFactory,"
      49                 :             " NaClRefCountCtor base class ctor failed\n");
      50               0 :     return 0;
      51                 :   }
      52                 : 
      53             546 :   self->factory = factory;
      54             546 :   self->factory_data = factory_data;
      55             546 :   self->thread_stack_size = thread_stack_size;
      56             546 :   self->fn_ptr = fn_ptr;
      57             546 :   self->thread_data = thread_data;
      58             546 :   self->thread_started = 0;
      59             546 :   NACL_VTBL(NaClRefCount, self) =
      60                 :       (struct NaClRefCountVtbl const *) &kNaClThreadInterfaceVtbl;
      61             546 :   NaClLog(3,
      62                 :           "Leaving NaClThreadInterfaceThreadPlacementFactory, returning 1\n");
      63             546 :   return 1;
      64             546 : }
      65                 : 
      66                 : int NaClThreadInterfaceThreadFactory(
      67              21 :     void                        *factory_data,
      68              21 :     NaClThreadIfStartFunction   fn_ptr,
      69              21 :     void                        *thread_data,
      70              21 :     size_t                      thread_stack_size,
      71              21 :     struct NaClThreadInterface  **out_new_thread) {
      72              21 :   struct NaClThreadInterface  *new_thread;
      73              21 :   int                         rv;
      74                 : 
      75              21 :   NaClLog(3, "Entered NaClThreadInterfaceThreadFactory\n");
      76              21 :   new_thread = malloc(sizeof *new_thread);
      77              21 :   if (NULL == new_thread) {
      78               0 :     NaClLog(3, "NaClThreadInterfaceThreadFactory: no memory!\n");
      79               0 :     return 0;
      80                 :   }
      81                 :   if (0 != (rv =
      82              21 :             NaClThreadInterfaceCtor_protected(
      83                 :                 new_thread,
      84                 :                 NaClThreadInterfaceThreadFactory,
      85                 :                 factory_data,
      86                 :                 fn_ptr,
      87                 :                 thread_data,
      88                 :                 thread_stack_size))) {
      89              21 :     *out_new_thread = new_thread;
      90              21 :     NaClLog(3,
      91                 :             "NaClThreadInterfaceThreadFactory: new thread object"
      92                 :             " 0x%"NACL_PRIxPTR" (not started)\n",
      93                 :             (uintptr_t) new_thread);
      94              21 :     new_thread = NULL;
      95              21 :   }
      96              21 :   free(new_thread);
      97              21 :   NaClLog(3,
      98                 :           "Leaving NaClThreadInterfaceThreadFactory, returning %d\n",
      99                 :           rv);
     100              21 :   return rv;
     101              21 : }
     102                 : 
     103               3 : void NaClThreadInterfaceDtor(struct NaClRefCount *vself) {
     104               3 :   struct NaClThreadInterface *self =
     105                 :       (struct NaClThreadInterface *) vself;
     106               9 :   CHECK(self->thread_started == 0);
     107               3 :   self->fn_ptr = NULL;
     108               3 :   self->thread_data = NULL;
     109               3 :   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
     110               3 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
     111               3 : }
     112                 : 
     113             546 : int NaClThreadInterfaceStartThread(struct NaClThreadInterface  *self) {
     114             546 :   int rv;
     115                 : 
     116             546 :   NaClLog(3,
     117                 :           "Entered NaClThreadInterfaceStartThread: self 0x%"NACL_PRIxPTR"\n",
     118                 :           (uintptr_t) self);
     119            1638 :   CHECK(self->thread_started == 0);
     120                 : 
     121             546 :   rv = NaClThreadCtor(&self->thread,
     122                 :                       NaClThreadInterfaceStart,
     123                 :                       self,
     124                 :                       self->thread_stack_size);
     125             546 :   if (rv) {
     126             546 :     self->thread_started = 1;
     127             546 :   }
     128             546 :   NaClLog(3, "Leaving NaClThreadInterfaceStartThread, rv=%d\n", rv);
     129             546 :   return rv;
     130                 : }
     131                 : 
     132                 : /*
     133                 :  * Default LaunchCallback does nothing.  We could have made this "pure
     134                 :  * virtual" by doing NaClLog(LOG_FATAL, ...) in the body (at least
     135                 :  * detected at runtime).
     136                 :  */
     137              21 : void NaClThreadInterfaceLaunchCallback(struct NaClThreadInterface *self) {
     138              21 :   NaClLog(3,
     139                 :           "NaClThreadInterfaceLaunchCallback: thread 0x%"NACL_PRIxPTR"\n",
     140                 :           (uintptr_t) self);
     141              21 : }
     142                 : 
     143               3 : void NaClThreadInterfaceExit(struct NaClThreadInterface *self,
     144               3 :                              void                       *exit_code) {
     145               6 :   UNREFERENCED_PARAMETER(exit_code);
     146                 : 
     147               3 :   NaClLog(3,
     148                 :           "NaClThreadInterfaceExit: thread 0x%"NACL_PRIxPTR"\n",
     149                 :           (uintptr_t) self);
     150               3 :   self->thread_started = 0;  /* on way out */
     151               3 :   NaClRefCountUnref((struct NaClRefCount *) self);
     152               3 :   NaClThreadExit();
     153               3 : }
     154                 : 
     155                 : struct NaClThreadInterfaceVtbl const kNaClThreadInterfaceVtbl = {
     156                 :   {
     157                 :     NaClThreadInterfaceDtor,
     158                 :   },
     159                 :   NaClThreadInterfaceStartThread,
     160                 :   NaClThreadInterfaceLaunchCallback,
     161                 :   NaClThreadInterfaceExit,
     162                 : };
     163                 : 
     164                 : int NaClThreadInterfaceConstructAndStartThread(
     165             546 :     NaClThreadIfFactoryFunction factory_fn,
     166             546 :     void                        *factory_data,
     167             546 :     NaClThreadIfStartFunction   thread_fn_ptr,
     168             546 :     void                        *thread_data,
     169             546 :     size_t                      thread_stack_size,
     170             546 :     struct NaClThreadInterface  **out_new_thread) {
     171             546 :   struct NaClThreadInterface  *new_thread;
     172                 : 
     173             546 :   NaClLog(3,
     174                 :           "NaClThreadInterfaceConstructAndStartThread: invoking factory"
     175                 :           " function 0x%"NACL_PRIxPTR", factory data 0x%"NACL_PRIxPTR"\n",
     176                 :           (uintptr_t) factory_fn, (uintptr_t) factory_data);
     177             546 :   if (!(*factory_fn)(factory_data,
     178                 :                      thread_fn_ptr,
     179                 :                      thread_data,
     180                 :                      thread_stack_size,
     181                 :                      &new_thread)) {
     182               0 :     NaClLog(3,
     183                 :             ("NaClThreadInterfaceConstructAndStartThread:"
     184                 :              " factory 0x%"NACL_PRIxPTR" failed to produce!\n"),
     185                 :             (uintptr_t) factory_fn);
     186               0 :     new_thread = NULL;
     187               0 :     goto abort;
     188                 :   }
     189             546 :   NaClLog(3,
     190                 :           "NaClThreadInterfaceConstructAndStartThread: StartThread vfn\n");
     191             546 :   if (!(*NACL_VTBL(NaClThreadInterface, new_thread)->StartThread)(
     192                 :           new_thread)) {
     193               0 :     NaClLog(3,
     194                 :             ("NaClThreadInterfaceConstructAndStartThread:"
     195                 :              " factory 0x%"NACL_PRIxPTR" produced a thread 0x%"NACL_PRIxPTR
     196                 :              " that won't start!\n"),
     197                 :             (uintptr_t) factory_fn,
     198                 :             (uintptr_t) new_thread);
     199               0 :     NaClRefCountUnref((struct NaClRefCount *) new_thread);
     200               0 :     new_thread = NULL;
     201               0 :     goto abort;
     202                 :   }
     203             546 :   NaClLog(4,
     204                 :           ("NaClThreadInterfaceConstructAndStartThread: thread 0x%"NACL_PRIxPTR
     205                 :            " started\n"),
     206                 :           (uintptr_t) new_thread);
     207                 : abort:
     208             546 :   *out_new_thread = new_thread;
     209             546 :   return new_thread != NULL;
     210                 : }

Generated by: LCOV version 1.7