Coverage for /Syzygy/common/recursive_lock.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%40400.C++source

Line-by-line coverage:

   1    :  // Copyright 2014 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/common/recursive_lock.h"
  16    :  
  17    :  #include "base/logging.h"
  18    :  
  19    :  namespace common {
  20    :  
  21    :  RecursiveLock::RecursiveLock()
  22  E :      : lock_is_free_(&lock_), thread_id_(0), recursion_(0) {
  23  E :  }
  24    :  
  25  E :  void RecursiveLock::AssertAcquired() {
  26  E :    DWORD thread_id = ::GetCurrentThreadId();
  27  E :    base::AutoLock lock(lock_);
  28    :  
  29  E :    DCHECK_EQ(thread_id, thread_id_);
  30  E :    DCHECK_LE(0u, recursion_);
  31  E :  }
  32    :  
  33  E :  void RecursiveLock::Acquire() {
  34  E :    TryImpl(true);
  35  E :  }
  36    :  
  37  E :  void RecursiveLock::Release() {
  38  E :    DWORD thread_id = ::GetCurrentThreadId();
  39  E :    base::AutoLock lock(lock_);
  40    :  
  41  E :    DCHECK_EQ(thread_id, thread_id_);
  42  E :    DCHECK_LT(0u, recursion_);
  43    :  
  44    :    // Decrement the recursion count. If the lock is now free then clear the
  45    :    // thread ID and notify a waiting thread.
  46  E :    --recursion_;
  47  E :    if (recursion_ == 0) {
  48  E :      thread_id_ = 0;
  49  E :      lock_is_free_.Signal();
  50    :    }
  51  E :  }
  52    :  
  53  E :  bool RecursiveLock::Try() {
  54  E :    return TryImpl(false);
  55  E :  }
  56    :  
  57  E :  bool RecursiveLock::TryImpl(bool wait) {
  58  E :    DWORD thread_id = ::GetCurrentThreadId();
  59  E :    base::AutoLock lock(lock_);
  60    :  
  61    :    // Reentrancy on the same thread.
  62  E :    if (thread_id_ == thread_id) {
  63  E :      ++recursion_;
  64  E :      return true;
  65    :    }
  66    :  
  67    :    // If we're not willing to wait and the lock is not free to acquire then
  68    :    // bail out.
  69  E :    if (!wait && thread_id_ != 0)
  70  E :      return false;
  71    :  
  72    :    // Somebody else has the lock so let's wait for them to release it.
  73  E :    while (thread_id_ != 0)
  74    :      // This releases lock_ and waits for a signal, thus 'Acquire' does not busy
  75    :      // loop.
  76  E :      lock_is_free_.Wait();
  77    :  
  78    :    // Acquire the lock.
  79  E :    DCHECK_EQ(0u, thread_id_);
  80  E :    DCHECK_EQ(0u, recursion_);
  81  E :    thread_id_ = thread_id;
  82  E :    recursion_ = 1;
  83    :  
  84  E :    return true;
  85  E :  }
  86    :  
  87    :  }  // namespace common

Coverage information generated Thu Jan 14 17:40:38 2016.