Fix PR8441, a race condition in the static attributes list. While the reference counting was itself threadsafe,

the implicit removal of each object from the global list was not.  Make this operation atomic.

llvm-svn: 118461
This commit is contained in:
Owen Anderson 2010-11-09 00:27:03 +00:00
parent 31f29e98bf
commit 9b14a25126
1 changed files with 12 additions and 5 deletions

View File

@ -106,7 +106,10 @@ Attributes Attribute::typeIncompatible(const Type *Ty) {
// AttributeListImpl Definition
//===----------------------------------------------------------------------===//
namespace llvm {
static ManagedStatic<sys::SmartMutex<true> > ALMutex;
class AttributeListImpl : public FoldingSetNode {
sys::cas_flag RefCount;
@ -122,10 +125,15 @@ public:
RefCount = 0;
}
void AddRef() { sys::AtomicIncrement(&RefCount); }
void AddRef() {
sys::SmartScopedLock<true> Lock(*ALMutex);
++RefCount;
}
void DropRef() {
sys::cas_flag old = sys::AtomicDecrement(&RefCount);
if (old == 0) delete this;
sys::SmartScopedLock<true> Lock(*ALMutex);
sys::cas_flag old = RefCount++;
if (old == 0)
delete this;
}
void Profile(FoldingSetNodeID &ID) const {
@ -139,11 +147,10 @@ public:
};
}
static ManagedStatic<sys::SmartMutex<true> > ALMutex;
static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists;
AttributeListImpl::~AttributeListImpl() {
sys::SmartScopedLock<true> Lock(*ALMutex);
// NOTE: Lock must be acquired by caller.
AttributesLists->RemoveNode(this);
}