зеркало из https://github.com/mozilla/pjs.git
First stab at making this threadsafe. Still need to refcount the Assertion struct.
This commit is contained in:
Родитель
42a21dec68
Коммит
cdbcd66802
|
@ -29,6 +29,10 @@
|
|||
a special case for them to improve access time to individual
|
||||
elements.
|
||||
|
||||
3) Complete implementation of thread-safety; specifically, make
|
||||
assertions be reference counted objects (so that a cursor can
|
||||
still refer to an assertion that gets removed from the graph).
|
||||
|
||||
*/
|
||||
|
||||
#include "nscore.h"
|
||||
|
@ -45,6 +49,15 @@
|
|||
#include "plhash.h"
|
||||
#include "plstr.h"
|
||||
|
||||
|
||||
#if 1 // defined(MOZ_THREADSAFE_RDF)
|
||||
#include "nsAutoLock.h"
|
||||
#define NS_AUTOLOCK(__monitor) nsAutoLock __lock(__monitor)
|
||||
#else
|
||||
#define NS_AUTOLOCK(__monitor)
|
||||
#endif
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kIRDFAssertionCursorIID, NS_IRDFASSERTIONCURSOR_IID);
|
||||
static NS_DEFINE_IID(kIRDFArcsInCursorIID, NS_IRDFARCSINCURSOR_IID);
|
||||
static NS_DEFINE_IID(kIRDFArcsOutCursorIID, NS_IRDFARCSOUTCURSOR_IID);
|
||||
|
@ -121,6 +134,19 @@ protected:
|
|||
|
||||
friend class InMemoryResourceCursor; // b/c it needs to enumerate mForwardArcs
|
||||
|
||||
// Thread-safe writer implementation methods.
|
||||
nsresult
|
||||
SafeAssert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv);
|
||||
|
||||
nsresult
|
||||
SafeUnassert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target);
|
||||
|
||||
|
||||
public:
|
||||
InMemoryDataSource(void);
|
||||
virtual ~InMemoryDataSource(void);
|
||||
|
@ -194,6 +220,10 @@ public:
|
|||
Assertion* GetReverseArcs(nsIRDFNode* v);
|
||||
void SetForwardArcs(nsIRDFResource* u, Assertion* as);
|
||||
void SetReverseArcs(nsIRDFNode* v, Assertion* as);
|
||||
|
||||
|
||||
// This datasource's monitor object.
|
||||
PRLock* mLock;
|
||||
};
|
||||
|
||||
const PRInt32 InMemoryDataSource::kInitialTableSize = 500;
|
||||
|
@ -248,10 +278,10 @@ public:
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InMemoryAssertionCursor::InMemoryAssertionCursor(InMemoryDataSource* ds,
|
||||
nsIRDFNode* u,
|
||||
nsIRDFResource* label,
|
||||
PRBool tv,
|
||||
Direction direction)
|
||||
nsIRDFNode* u,
|
||||
nsIRDFResource* label,
|
||||
PRBool tv,
|
||||
Direction direction)
|
||||
: mDataSource(ds),
|
||||
mSource(nsnull),
|
||||
mLabel(label),
|
||||
|
@ -297,6 +327,8 @@ InMemoryAssertionCursor::Advance(void)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_AUTOLOCK(mDataSource->mLock);
|
||||
|
||||
NS_IF_RELEASE(mValue);
|
||||
|
||||
while (mNextAssertion) {
|
||||
|
@ -333,6 +365,8 @@ InMemoryAssertionCursor::GetValue(nsIRDFNode** aValue)
|
|||
if (! aValue)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mDataSource->mLock);
|
||||
|
||||
NS_ADDREF(mValue);
|
||||
*aValue = mValue;
|
||||
return NS_OK;
|
||||
|
@ -358,6 +392,8 @@ InMemoryAssertionCursor::GetSubject(nsIRDFResource** aSubject)
|
|||
if (! aSubject)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mDataSource->mLock);
|
||||
|
||||
if (mDirection == eDirectionForwards) {
|
||||
NS_ADDREF(mSource);
|
||||
*aSubject = mSource;
|
||||
|
@ -393,6 +429,8 @@ InMemoryAssertionCursor::GetObject(nsIRDFNode** aObject)
|
|||
if (! aObject)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mDataSource->mLock);
|
||||
|
||||
if (mDirection == eDirectionForwards) {
|
||||
if (! mValue)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -415,6 +453,8 @@ InMemoryAssertionCursor::GetTruthValue(PRBool* aTruthValue)
|
|||
if (! aTruthValue)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mDataSource->mLock);
|
||||
|
||||
*aTruthValue = mTruthValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -797,7 +837,8 @@ InMemoryDataSource::InMemoryDataSource(void)
|
|||
: mURL(nsnull),
|
||||
mForwardArcs(nsnull),
|
||||
mReverseArcs(nsnull),
|
||||
mObservers(nsnull)
|
||||
mObservers(nsnull),
|
||||
mLock(nsnull)
|
||||
{
|
||||
mForwardArcs = PL_NewHashTable(kInitialTableSize,
|
||||
rdf_HashPointer,
|
||||
|
@ -812,6 +853,9 @@ InMemoryDataSource::InMemoryDataSource(void)
|
|||
PL_CompareValues,
|
||||
nsnull,
|
||||
nsnull);
|
||||
|
||||
mLock = PR_NewLock();
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
|
@ -838,6 +882,8 @@ InMemoryDataSource::~InMemoryDataSource(void)
|
|||
}
|
||||
delete mObservers;
|
||||
}
|
||||
|
||||
PR_DestroyLock(mLock);
|
||||
}
|
||||
|
||||
PRIntn
|
||||
|
@ -909,6 +955,20 @@ InMemoryDataSource::GetSource(nsIRDFResource* property,
|
|||
PRBool tv,
|
||||
nsIRDFResource** source)
|
||||
{
|
||||
NS_PRECONDITION(source != nsnull, "null ptr");
|
||||
if (! source)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(property != nsnull, "null ptr");
|
||||
if (! property)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(target != nsnull, "null ptr");
|
||||
if (! target)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
nsresult rv;
|
||||
for (Assertion* as = GetReverseArcs(target); as != nsnull; as = as->mNext) {
|
||||
PRBool eq;
|
||||
|
@ -935,6 +995,20 @@ InMemoryDataSource::GetTarget(nsIRDFResource* source,
|
|||
PRBool tv,
|
||||
nsIRDFNode** target)
|
||||
{
|
||||
NS_PRECONDITION(source != nsnull, "null ptr");
|
||||
if (! source)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(property != nsnull, "null ptr");
|
||||
if (! property)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(target != nsnull, "null ptr");
|
||||
if (! target)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
nsresult rv;
|
||||
for (Assertion* as = GetForwardArcs(source); as != nsnull; as = as->mNext) {
|
||||
PRBool eq;
|
||||
|
@ -965,6 +1039,20 @@ InMemoryDataSource::HasAssertion(nsIRDFResource* source,
|
|||
PRBool tv,
|
||||
PRBool* hasAssertion)
|
||||
{
|
||||
NS_PRECONDITION(source != nsnull, "null ptr");
|
||||
if (! source)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(property != nsnull, "null ptr");
|
||||
if (! property)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(target != nsnull, "null ptr");
|
||||
if (! target)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
nsresult rv;
|
||||
for (Assertion* as = GetForwardArcs(source); as != nsnull; as = as->mNext) {
|
||||
PRBool eq;
|
||||
|
@ -1003,6 +1091,8 @@ InMemoryDataSource::GetSources(nsIRDFResource* property,
|
|||
if (! sources)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryAssertionCursor* result
|
||||
= new InMemoryAssertionCursor(this, target, property, tv, eDirectionReverse);
|
||||
|
||||
|
@ -1024,6 +1114,8 @@ InMemoryDataSource::GetTargets(nsIRDFResource* source,
|
|||
if (! targets)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryAssertionCursor* result
|
||||
= new InMemoryAssertionCursor(this, source, property, tv, eDirectionForwards);
|
||||
|
||||
|
@ -1035,14 +1127,16 @@ InMemoryDataSource::GetTargets(nsIRDFResource* source,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::Assert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsresult
|
||||
InMemoryDataSource::SafeAssert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv)
|
||||
{
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
nsresult rv;
|
||||
Assertion* next = GetForwardArcs(source);
|
||||
Assertion* prev = next;
|
||||
Assertion* as = nsnull;
|
||||
|
@ -1107,6 +1201,20 @@ InMemoryDataSource::Assert(nsIRDFResource* source,
|
|||
prev->mInvNext = as;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::Assert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = SafeAssert(source, property, target, tv)))
|
||||
return rv;
|
||||
|
||||
// notify observers
|
||||
if (mObservers) {
|
||||
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
|
||||
|
@ -1119,11 +1227,14 @@ InMemoryDataSource::Assert(nsIRDFResource* source,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::Unassert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target)
|
||||
|
||||
nsresult
|
||||
InMemoryDataSource::SafeUnassert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target)
|
||||
{
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
nsresult rv;
|
||||
Assertion* next = GetForwardArcs(source);
|
||||
Assertion* prev = next;
|
||||
|
@ -1178,6 +1289,19 @@ InMemoryDataSource::Unassert(nsIRDFResource* source,
|
|||
NS_RELEASE(as->mTarget);
|
||||
delete as;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::Unassert(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = SafeUnassert(source, property, target)))
|
||||
return rv;
|
||||
|
||||
// Notify the world
|
||||
if (mObservers) {
|
||||
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
|
||||
|
@ -1198,6 +1322,8 @@ InMemoryDataSource::AddObserver(nsIRDFObserver* observer)
|
|||
if (! observer)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
if (! mObservers) {
|
||||
if ((mObservers = new nsVoidArray()) == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -1214,6 +1340,8 @@ InMemoryDataSource::RemoveObserver(nsIRDFObserver* observer)
|
|||
if (! observer)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
if (! mObservers)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -1246,6 +1374,8 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFResource* source, nsIRDFArcsOutCursor** l
|
|||
if (! labels)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryArcsCursor* result =
|
||||
new InMemoryArcsCursor(this, source, eDirectionForwards);
|
||||
|
||||
|
@ -1264,6 +1394,8 @@ InMemoryDataSource::GetAllResources(nsIRDFResourceCursor** aCursor)
|
|||
if (! aCursor)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryResourceCursor* result =
|
||||
new InMemoryResourceCursor(this);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче