LCOV - code coverage report
Current view: directory - src/trusted/nacl_base - nacl_refcount.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 50 43 86.0 %
Date: 2014-09-25 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               6 : int NaClRefCountCtor(struct NaClRefCount *self) {
      13               6 :   NaClLog(4, "NaClRefCountCtor(0x%08"NACL_PRIxPTR").\n", (uintptr_t) self);
      14               6 :   self->ref_count = 1;
      15               6 :   self->vtbl = (struct NaClRefCountVtbl *) NULL;
      16               6 :   if (NaClFastMutexCtor(&self->mu)) {
      17               6 :     self->vtbl = &kNaClRefCountVtbl;
      18               6 :     return 1;
      19                 :   }
      20               0 :   return 0;
      21               6 : }
      22                 : 
      23               5 : static void NaClRefCountDtor(struct NaClRefCount  *self) {
      24                 :   NaClLog(4, "NaClRefCountDtor(0x%08"NACL_PRIxPTR"), refcount %"NACL_PRIuS
      25                 :           ", destroying.\n",
      26                 :           (uintptr_t) self,
      27               5 :           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               5 :   switch (self->ref_count) {
      39                 :     case 0:
      40               5 :       break;
      41                 :     case 1:
      42                 :       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               0 :               (uintptr_t) self);
      48               0 :       break;
      49                 :     default:
      50                 :       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               0 :               self->ref_count);
      56                 :   }
      57                 : 
      58               5 :   NaClFastMutexDtor(&self->mu);
      59               5 :   self->vtbl = (struct NaClRefCountVtbl const *) NULL;
      60               5 : }
      61                 : 
      62                 : struct NaClRefCountVtbl const kNaClRefCountVtbl = {
      63                 :   NaClRefCountDtor,
      64                 : };
      65                 : 
      66               4 : struct NaClRefCount *NaClRefCountRef(struct NaClRefCount *nrcp) {
      67                 :   NaClLog(4, "NaClRefCountRef(0x%08"NACL_PRIxPTR").\n",
      68               4 :           (uintptr_t) nrcp);
      69               4 :   NaClFastMutexLock(&nrcp->mu);
      70               4 :   if (0 == ++nrcp->ref_count) {
      71               0 :     NaClLog(LOG_FATAL, "NaClRefCountRef integer overflow\n");
      72                 :   }
      73               4 :   NaClFastMutexUnlock(&nrcp->mu);
      74               4 :   return nrcp;
      75               4 : }
      76                 : 
      77               6 : void NaClRefCountUnref(struct NaClRefCount *nrcp) {
      78                 :   int destroy;
      79                 : 
      80                 :   NaClLog(4, "NaClRefCountUnref(0x%08"NACL_PRIxPTR").\n",
      81               6 :           (uintptr_t) nrcp);
      82               6 :   NaClFastMutexLock(&nrcp->mu);
      83               6 :   if (0 == nrcp->ref_count) {
      84                 :     NaClLog(LOG_FATAL,
      85                 :             ("NaClRefCountUnref on 0x%08"NACL_PRIxPTR
      86                 :              ", refcount already zero!\n"),
      87               0 :             (uintptr_t) nrcp);
      88                 :   }
      89               6 :   destroy = (0 == --nrcp->ref_count);
      90               6 :   NaClFastMutexUnlock(&nrcp->mu);
      91               6 :   if (destroy) {
      92               5 :     (*nrcp->vtbl->Dtor)(nrcp);
      93               5 :     free(nrcp);
      94                 :   }
      95               6 : }
      96                 : 
      97               1 : void NaClRefCountSafeUnref(struct NaClRefCount *nrcp) {
      98                 :   NaClLog(4, "NaClRefCountSafeUnref(0x%08"NACL_PRIxPTR").\n",
      99               1 :           (uintptr_t) nrcp);
     100               1 :   if (NULL == nrcp) {
     101               0 :     return;
     102                 :   }
     103               1 :   NaClRefCountUnref(nrcp);
     104               1 : }
     105                 : 
     106               3 : void NaClRefCountLock(struct NaClRefCount *nrcp) {
     107               3 :   NaClFastMutexLock(&nrcp->mu);
     108               3 : }
     109                 : 
     110               3 : void NaClRefCountUnlock(struct NaClRefCount *nrcp) {
     111               3 :   NaClFastMutexUnlock(&nrcp->mu);
     112               3 : }

Generated by: LCOV version 1.7