LCOV - code coverage report
Current view: directory - src/shared/platform/win - nacl_fast_mutex.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 26 19 73.1 %
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/shared/platform/nacl_check.h"
       8                 : #include "native_client/src/shared/platform/win/nacl_fast_mutex.h"
       9                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      10                 : 
      11                 : /*
      12                 :  * Windows CRITICAL_SECTION objects are recursive locks.
      13                 :  * NaClFastMutex should be binary mutexes.  Thus, we keep a flag
      14                 :  * is_held to specify whether or not the lock is held.  Only the
      15                 :  * thread holding the CRITICAL_SECTION could take the lock again via
      16                 :  * EnterCriticalSection, so only that thread could observe a non-zero
      17                 :  * value of is_held.  When that occurs, it is because of a recursive
      18                 :  * lock acquisition; we crash the app when this occurs.
      19                 :  *
      20                 :  * If a CRITICAL_SECTION is abandoned, i.e., the thread holding it
      21                 :  * exits, MSDN says that the state of the CRITICAL_SECTION is
      22                 :  * undefined.  Ignoring standards/legalese interpretations that
      23                 :  * include melting the CPU, reasonable implementation-defined behavior
      24                 :  * include:
      25                 :  *
      26                 :  * - leaving the lock held, keeping all other threads from entering;
      27                 :  *
      28                 :  * - implicitly dropping the lock, letting another thread enter.
      29                 :  *
      30                 :  * In the first case, the application deadlocks.  This is fine (though
      31                 :  * crashing would be better).  In the second case, we will see is_held
      32                 :  * set and crash.  This is also reasonable.
      33                 :  */
      34                 : 
      35               9 : int NaClFastMutexCtor(struct NaClFastMutex *flp) {
      36               9 :   flp->is_held = 0;
      37               9 :   InitializeCriticalSection(&flp->mu);
      38               9 :   return 1;
      39               9 : }
      40                 : 
      41               8 : void NaClFastMutexDtor(struct NaClFastMutex *flp) {
      42               8 :   CHECK(0 == flp->is_held);
      43               8 :   DeleteCriticalSection(&flp->mu);
      44               8 : }
      45                 : 
      46               8 : void NaClFastMutexLock(struct NaClFastMutex *flp) {
      47               8 :   EnterCriticalSection(&flp->mu);
      48                 :   /*
      49                 :    * CRITICAL_SECTION locks are recursive lock, but we only want
      50                 :    * binary locks.  TODO(bsy): consider returning other error code,
      51                 :    * e.g., EDEADLK, here instead.
      52                 :    */
      53               8 :   CHECK(0 == flp->is_held);
      54               8 :   flp->is_held = 1;
      55               8 : }
      56                 : 
      57               0 : int NaClFastMutexTryLock(struct NaClFastMutex *flp) {
      58               0 :   if (TryEnterCriticalSection(&flp->mu)) {
      59                 :     /*
      60                 :      * Abandoned critical sections state is undefined.  TODO(bsy):
      61                 :      * consider returning other error code, e.g., EDEADLK here.
      62                 :      */
      63               0 :     CHECK(0 == flp->is_held);
      64               0 :     flp->is_held = 1;
      65               0 :     return 0;
      66                 :   }
      67                 :   /*
      68                 :    * Abandoned critical sections state is undefined; cannot check that
      69                 :    * is_held is true without holding the lock, so this might actually
      70                 :    * be a deadlock.
      71                 :    */
      72               0 :   return NACL_ABI_EBUSY;
      73               0 : }
      74                 : 
      75               8 : void NaClFastMutexUnlock(struct NaClFastMutex *flp) {
      76               8 :   CHECK(1 == flp->is_held);
      77               8 :   flp->is_held = 0;
      78               8 :   LeaveCriticalSection(&flp->mu);
      79               8 : }

Generated by: LCOV version 1.7