mirror of
https://github.com/ceph/ceph
synced 2025-02-23 11:07:35 +00:00
common/Mutex: remove Mutex
as it's replaced by `ceph::mutex` Signed-off-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
parent
57a3254f3d
commit
dc21fd028d
@ -21,7 +21,6 @@ set(common_srcs
|
||||
LogClient.cc
|
||||
LogEntry.cc
|
||||
ostream_temp.cc
|
||||
Mutex.cc
|
||||
OutputDataSocket.cc
|
||||
PluginRegistry.cc
|
||||
Readahead.cc
|
||||
|
@ -1,90 +0,0 @@
|
||||
// -*- 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);
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
// -*- 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
|
@ -67,7 +67,6 @@ add_library(crimson-common STATIC
|
||||
${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
|
||||
|
@ -242,13 +242,6 @@ add_executable(unittest_mutex_debug
|
||||
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
|
||||
|
@ -1,64 +0,0 @@
|
||||
// -*- 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,".*");
|
||||
}
|
Loading…
Reference in New Issue
Block a user