LCOV - code coverage report
Current view: directory - src/trusted/nacl_base - nacl_refcount.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 54 45 83.3 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 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/nacl_base/nacl_refcount.h"
       8                 : 
       9                 : #include "native_client/src/shared/platform/nacl_log.h"
      10                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      11                 : 
      12            4821 : int NaClRefCountCtor(struct NaClRefCount *self) {
      13            4821 :   NaClLog(4, "NaClRefCountCtor(0x%08"NACL_PRIxPTR").\n", (uintptr_t) self);
      14            4821 :   self->ref_count = 1;
      15            4821 :   self->vtbl = (struct NaClRefCountVtbl *) NULL;
      16            4821 :   if (NaClFastMutexCtor(&self->mu)) {
      17            4821 :     self->vtbl = &kNaClRefCountVtbl;
      18            4821 :     return 1;
      19                 :   }
      20               0 :   return 0;
      21            4821 : }
      22                 : 
      23            1183 : static void NaClRefCountDtor(struct NaClRefCount  *self) {
      24            1183 :   NaClLog(4, "NaClRefCountDtor(0x%08"NACL_PRIxPTR"), refcount %"NACL_PRIuS
      25                 :           ", destroying.\n",
      26                 :           (uintptr_t) self,
      27                 :           self->ref_count);
      28                 :   /*
      29                 :    * NB: refcount could be non-zero.  Here's why: if a subclass's Ctor
      30                 :    * fails, it will have already run NaClRefCountCtor and have
      31                 :    * initialized the mutex and set the ref_count to 1.  Because Unref
      32                 :    * would free memory and Ctors aren't factories, the subclass Ctor
      33                 :    * cannot just invoke NaClRefCountUnref; instead, it must directly
      34                 :    * invoke the base class Dtor.
      35                 :    *
      36                 :    * We do, however, expect the ref_count to be either 0 or 1.
      37                 :    */
      38            1183 :   switch (self->ref_count) {
      39                 :     case 0:
      40            1183 :       break;
      41                 :     case 1:
      42               0 :       NaClLog(LOG_WARNING,
      43                 :               ("NaClRefCountDtor invoked on a generic refcounted"
      44                 :                " object at 0x%08"NACL_PRIxPTR" with refcount 1."
      45                 :                "  This legitimately occurs only during subclass"
      46                 :                " ctor failures.\n"),
      47                 :               (uintptr_t) self);
      48               0 :       break;
      49                 :     default:
      50               0 :       NaClLog(LOG_FATAL,
      51                 :               ("NaClRefCountDtor invoked on a generic refcounted"
      52                 :                " object at 0x%08"NACL_PRIxPTR" with non-zero"
      53                 :                " reference count (%"NACL_PRIuS")\n"),
      54                 :               (uintptr_t) self,
      55                 :               self->ref_count);
      56               0 :   }
      57                 : 
      58            1183 :   NaClFastMutexDtor(&self->mu);
      59            1183 :   self->vtbl = (struct NaClRefCountVtbl const *) NULL;
      60            1183 : }
      61                 : 
      62                 : struct NaClRefCountVtbl const kNaClRefCountVtbl = {
      63                 :   NaClRefCountDtor,
      64                 : };
      65                 : 
      66           86155 : struct NaClRefCount *NaClRefCountRef(struct NaClRefCount *nrcp) {
      67           86155 :   NaClLog(4, "NaClRefCountRef(0x%08"NACL_PRIxPTR").\n",
      68                 :           (uintptr_t) nrcp);
      69           86155 :   NaClFastMutexLock(&nrcp->mu);
      70           86155 :   if (0 == ++nrcp->ref_count) {
      71               0 :     NaClLog(LOG_FATAL, "NaClRefCountRef integer overflow\n");
      72               0 :   }
      73           86155 :   NaClFastMutexUnlock(&nrcp->mu);
      74           86155 :   return nrcp;
      75                 : }
      76                 : 
      77           84570 : void NaClRefCountUnref(struct NaClRefCount *nrcp) {
      78           84570 :   int destroy;
      79                 : 
      80           84570 :   NaClLog(4, "NaClRefCountUnref(0x%08"NACL_PRIxPTR").\n",
      81                 :           (uintptr_t) nrcp);
      82           84570 :   NaClFastMutexLock(&nrcp->mu);
      83           84570 :   if (0 == nrcp->ref_count) {
      84               0 :     NaClLog(LOG_FATAL,
      85                 :             ("NaClRefCountUnref on 0x%08"NACL_PRIxPTR
      86                 :              ", refcount already zero!\n"),
      87                 :             (uintptr_t) nrcp);
      88               0 :   }
      89           84570 :   destroy = (0 == --nrcp->ref_count);
      90           84570 :   NaClFastMutexUnlock(&nrcp->mu);
      91           84570 :   if (destroy) {
      92            1183 :     (*nrcp->vtbl->Dtor)(nrcp);
      93            1183 :     free(nrcp);
      94            1183 :   }
      95           84570 : }
      96                 : 
      97             284 : void NaClRefCountSafeUnref(struct NaClRefCount *nrcp) {
      98             284 :   NaClLog(4, "NaClRefCountSafeUnref(0x%08"NACL_PRIxPTR").\n",
      99                 :           (uintptr_t) nrcp);
     100             284 :   if (NULL == nrcp) {
     101             258 :     return;
     102                 :   }
     103              26 :   NaClRefCountUnref(nrcp);
     104             310 : }
     105                 : 
     106            3390 : void NaClRefCountLock(struct NaClRefCount *nrcp) {
     107            3390 :   NaClFastMutexLock(&nrcp->mu);
     108            3390 : }
     109                 : 
     110            3389 : void NaClRefCountUnlock(struct NaClRefCount *nrcp) {
     111            3389 :   NaClFastMutexUnlock(&nrcp->mu);
     112            3389 : }

Generated by: LCOV version 1.7