Clang 线程安全注释和共享功能

Clang thread safety annotation and shared capabilities

当我使用 clang thread annotations 时,以下代码会生成一个警告。我正在尝试包装 boost::shared_mutexboost::shared_lock。我如何使用线程注释来表示此锁是共享锁?

源代码:

#include <mutex>
#include "boost/thread/shared_mutex.hpp"

class __attribute__((shared_capability("mutex"))) BoostSharedMutex {
public:
  boost::shared_mutex &getNativeHandle() { return m_mutex; }
private:
  mutable boost::shared_mutex m_mutex;
};

class __attribute__((scoped_lockable)) MutexSharedLock {
public:
    explicit MutexSharedLock(BoostSharedMutex &mutex) __attribute__((acquire_shared_capability(mutex)))
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexSharedLock() __attribute__((release_shared_capability())) = default;

private:
    boost::shared_lock<boost::shared_mutex> m_lock;
};


int main() {
  BoostSharedMutex mutex;
  MutexSharedLock lock(mutex);
}

clang 输出:

clang++-3.6 --std=c++11 -Wall -Wthread-safety /tmp/foo.cpp -lboost_system
/tmp/foo.cpp:25:5: warning: releasing mutex 'lock' using shared access, expected exclusive access [-Wthread-safety-analysis]
    }
    ^
1 warning generated.

编辑:这可以编译但似乎是错误的。是我这边的问题吗?

#include <mutex>
#include "boost/thread/shared_mutex.hpp"

class __attribute__((shared_capability("mutex"))) BoostSharedMutex {
public:
  boost::shared_mutex &getNativeHandle() { return m_mutex; }
private:
  mutable boost::shared_mutex m_mutex;
};

class __attribute__((scoped_lockable)) MutexSharedLock {
public:
    explicit MutexSharedLock(BoostSharedMutex &mutex) __attribute__((acquire_capability(mutex))) // changed  from acquired_shared_capability
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexSharedLock() __attribute__((release_capability())) = default; // changed from release_shared_capability

private:
    boost::shared_lock<boost::shared_mutex> m_lock;
};

BoostSharedMutex mutex;
int locked_variable __attribute__((guarded_by(mutex)));

int main() {
  MutexSharedLock lock(mutex);
  std::cout << locked_variable << std::endl; // ok, guarded variable is only read
  locked_variable = 42; // no warning while writing in the guarded variable while only holding a non-exclusive lock?
}

尝试了几种组合后,这似乎有效:

#include <mutex>
#include "boost/thread/shared_mutex.hpp"

class __attribute__((capability("mutex"))) BoostSharedMutex {
public:
  boost::shared_mutex &getNativeHandle() { return m_mutex; }
private:
  mutable boost::shared_mutex m_mutex;
};

class __attribute__((scoped_lockable)) MutexSharedLock {
public:
    explicit MutexSharedLock(BoostSharedMutex &mutex) __attribute__((acquire_shared_capability(mutex)))
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexSharedLock() __attribute__((release_capability())) = default;

private:
    boost::shared_lock<boost::shared_mutex> m_lock;
};

class __attribute__((scoped_lockable)) MutexLock {
public:
    explicit MutexLock(BoostSharedMutex &mutex) __attribute__((acquire_capability(mutex)))
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexLock() __attribute__((release_capability())) = default;

private:
    std::unique_lock<boost::shared_mutex> m_lock;
};

BoostSharedMutex mutex;
int locked_variable __attribute__((guarded_by(mutex)));

int main() {
  {
    MutexSharedLock lock(mutex);
    std::cout << locked_variable << std::endl;
    // locked_variable = 42; -- triger a error as expected
  }
  {
    MutexLock lock(mutex);
    std::cout << locked_variable << std::endl;
    locked_variable = 42;
  }
}

我很想知道为什么 MutexSharedLock 应该使用 acquire_shared_capability 而发布时使用 release_capability ...

(如果有人现在可以确认代码正确,我会打开问题)

只需使用 unlock_function 而不是 release_shared_capability

同样适用于 try_acquire_capability/try_acquire_shared_capability - 它们只是不起作用,但以前的 exclusive_trylock_function/shared_trylock_function 效果很好。 M.b。这是 clang 中的错误。