LogClient.cc
LogEntry.cc
ostream_temp.cc
- Mutex.cc
OutputDataSocket.cc
PluginRegistry.cc
Readahead.cc
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include "common/Mutex.h"
-#include "common/config.h"
-#include "common/Clock.h"
-#include "common/valgrind.h"
-
-Mutex::Mutex(const std::string &n, bool r, bool ld,
- bool bt) :
- name(n), id(-1), recursive(r), lockdep(ld), backtrace(bt), nlock(0),
- locked_by(0)
-{
- ANNOTATE_BENIGN_RACE_SIZED(&id, sizeof(id), "Mutex lockdep id");
- ANNOTATE_BENIGN_RACE_SIZED(&nlock, sizeof(nlock), "Mutex nlock");
- ANNOTATE_BENIGN_RACE_SIZED(&locked_by, sizeof(locked_by), "Mutex locked_by");
- if (recursive) {
- // Mutexes of type PTHREAD_MUTEX_RECURSIVE do all the same checks as
- // mutexes of type PTHREAD_MUTEX_ERRORCHECK.
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&_m,&attr);
- pthread_mutexattr_destroy(&attr);
- if (lockdep && g_lockdep)
- _register();
- }
- else if (lockdep) {
- // If the mutex type is PTHREAD_MUTEX_ERRORCHECK, then error checking
- // shall be provided. If a thread attempts to relock a mutex that it
- // has already locked, an error shall be returned. If a thread
- // attempts to unlock a mutex that it has not locked or a mutex which
- // is unlocked, an error shall be returned.
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
- pthread_mutex_init(&_m, &attr);
- pthread_mutexattr_destroy(&attr);
- if (g_lockdep)
- _register();
- }
- else {
- // If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to recursively
- // lock the mutex results in undefined behavior. Attempting to unlock the
- // mutex if it was not locked by the calling thread results in undefined
- // behavior. Attempting to unlock the mutex if it is not locked results in
- // undefined behavior.
- pthread_mutex_init(&_m, NULL);
- }
-}
-
-Mutex::~Mutex() {
- ceph_assert(nlock == 0);
-
- // helgrind gets confused by condition wakeups leading to mutex destruction
- ANNOTATE_BENIGN_RACE_SIZED(&_m, sizeof(_m), "Mutex primitive");
- pthread_mutex_destroy(&_m);
-
- if (lockdep && g_lockdep) {
- lockdep_unregister(id);
- }
-}
-
-void Mutex::lock(bool no_lockdep)
-{
- if (lockdep && g_lockdep && !no_lockdep && !recursive) _will_lock();
- int r = pthread_mutex_lock(&_m);
- ceph_assert(r == 0);
- if (lockdep && g_lockdep) _locked();
- _post_lock();
-}
-
-void Mutex::unlock()
-{
- _pre_unlock();
- if (lockdep && g_lockdep) _will_unlock();
- int r = pthread_mutex_unlock(&_m);
- ceph_assert(r == 0);
-}
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_MUTEX_H
-#define CEPH_MUTEX_H
-
-#include "include/ceph_assert.h"
-#include "lockdep.h"
-
-#include <string>
-#include <pthread.h>
-#include <mutex>
-
-using namespace ceph;
-
-class Mutex {
-private:
- std::string name;
- int id;
- bool recursive;
- bool lockdep;
- bool backtrace; // gather backtrace on lock acquisition
-
- pthread_mutex_t _m;
- int nlock;
- pthread_t locked_by;
-
- // don't allow copying.
- void operator=(const Mutex &M);
- Mutex(const Mutex &M);
-
- void _register() {
- id = lockdep_register(name.c_str());
- }
- void _will_lock() { // about to lock
- id = lockdep_will_lock(name.c_str(), id, backtrace, recursive);
- }
- void _locked() { // just locked
- id = lockdep_locked(name.c_str(), id, backtrace);
- }
- void _will_unlock() { // about to unlock
- id = lockdep_will_unlock(name.c_str(), id);
- }
-
-public:
- Mutex(const std::string &n, bool r = false, bool ld=true, bool bt=false);
- ~Mutex();
- bool is_locked() const {
- return (nlock > 0);
- }
- bool is_locked_by_me() const {
- return nlock > 0 && locked_by == pthread_self();
- }
-
- bool TryLock() {
- return try_lock();
- }
- bool try_lock() {
- int r = pthread_mutex_trylock(&_m);
- if (r == 0) {
- if (lockdep && g_lockdep) _locked();
- _post_lock();
- }
- return r == 0;
- }
-
- void Lock(bool no_lockdep=false) {
- lock(no_lockdep);
- }
- void lock(bool no_lockdep=false);
-
- void _post_lock() {
- if (!recursive) {
- ceph_assert(nlock == 0);
- locked_by = pthread_self();
- };
- nlock++;
- }
-
- void _pre_unlock() {
- ceph_assert(nlock > 0);
- --nlock;
- if (!recursive) {
- ceph_assert(locked_by == pthread_self());
- locked_by = 0;
- ceph_assert(nlock == 0);
- }
- }
- void Unlock() {
- unlock();
- }
- void unlock();
-
- friend class Cond;
-
-
-public:
- typedef std::lock_guard<Mutex> Locker;
-};
-
-
-#endif
${PROJECT_SOURCE_DIR}/src/common/Graylog.cc
${PROJECT_SOURCE_DIR}/src/common/ostream_temp.cc
${PROJECT_SOURCE_DIR}/src/common/LogEntry.cc
- ${PROJECT_SOURCE_DIR}/src/common/Mutex.cc
${PROJECT_SOURCE_DIR}/src/common/SubProcess.cc
${PROJECT_SOURCE_DIR}/src/common/TextTable.cc
${PROJECT_SOURCE_DIR}/src/common/Thread.cc
add_ceph_unittest(unittest_mutex_debug)
target_link_libraries(unittest_mutex_debug ceph-common)
-# unittest_mutex
-add_executable(unittest_mutex
- test_mutex.cc
- )
-add_ceph_unittest(unittest_mutex)
-target_link_libraries(unittest_mutex ceph-common)
-
# unittest_shunique_lock
add_executable(unittest_shunique_lock
test_shunique_lock.cc
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- */
-
-#include <common/Mutex.h>
-#include "gtest/gtest.h"
-#include "common/ceph_context.h"
-#include "common/config.h"
-#include "include/coredumpctl.h"
-
-static CephContext* cct;
-
-static void do_init() {
- if (cct == nullptr) {
- cct = new CephContext(0);
- lockdep_register_ceph_context(cct);
- }
-}
-
-static void disable_lockdep() {
- if (cct) {
- lockdep_unregister_ceph_context(cct);
- cct->put();
- cct = nullptr;
- }
-}
-
-TEST(Mutex, NormalAsserts) {
- Mutex* m = new Mutex("Normal",false);
- m->Lock();
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- PrCtl unset_dumpable;
- EXPECT_DEATH(m->Lock(), ".*");
-}
-
-TEST(Mutex, RecursiveWithLockdep) {
- do_init();
- Mutex* m = new Mutex("Recursive1",true);
- m->Lock();
- m->Lock();
- m->Unlock();
- m->Unlock();
- delete m;
-}
-
-TEST(Mutex, RecursiveWithoutLockdep) {
- disable_lockdep();
- Mutex* m = new Mutex("Recursive2",true);
- m->Lock();
- m->Lock();
- m->Unlock();
- m->Unlock();
- delete m;
-}
-
-TEST(Mutex, DeleteLocked) {
- Mutex* m = new Mutex("Recursive3",false);
- m->Lock();
- PrCtl unset_dumpable;
- EXPECT_DEATH(delete m,".*");
-}