Create a mechanism for allowing a |Destroy| method to be called on buffer handles whose refcount hits 0 instead of |delete|. Use that mechanism to fix threadsafety problems with shared empty buffer handles, restoring sharable strings to their previous state of threadsafety. b=117153 sr=jag r=alecf

git-svn-id: svn://10.0.0.236/trunk@112277 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dbaron%fas.harvard.edu
2002-01-16 03:08:22 +00:00
parent f0e007cdfc
commit 865e4ed64a
6 changed files with 212 additions and 76 deletions

View File

@@ -100,15 +100,10 @@ nsSharableString::SetCapacity( size_type aNewCapacity )
void
nsSharableString::SetLength( size_type aNewLength )
{
if ( !mBuffer->IsMutable() || aNewLength > mBuffer->DataLength() )
{
SetCapacity(aNewLength);
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
}
else
{
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
}
if ( !mBuffer->IsMutable() || aNewLength >= mBuffer->StorageLength() )
SetCapacity(aNewLength);
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
// This is needed for |Truncate| callers and also for some callers
// (such as nsAString::do_AppendFromReadable) that are manipulating
// the internals of the string. It also makes sense to do this
@@ -166,11 +161,15 @@ nsSharableString::shared_buffer_handle_type*
nsSharableString::GetSharedEmptyBufferHandle()
{
static shared_buffer_handle_type* sBufferHandle = nsnull;
static char_type null_char = char_type(0);
if (!sBufferHandle) {
sBufferHandle = NS_AllocateContiguousHandleWithData(sBufferHandle,
PRUint32(1), (self_type*)nsnull);
sBufferHandle->AcquireReference();
sBufferHandle = new nsNonDestructingSharedBufferHandle<char_type>(&null_char, &null_char, 1);
sBufferHandle->AcquireReference(); // To avoid the |Destroy|
// mechanism unless threads
// race to set the refcount, in
// which case we'll pull the
// same trick in |Destroy|.
}
return sBufferHandle;
}
@@ -265,15 +264,10 @@ nsSharableCString::SetCapacity( size_type aNewCapacity )
void
nsSharableCString::SetLength( size_type aNewLength )
{
if ( !mBuffer->IsMutable() || aNewLength > mBuffer->DataLength() )
{
SetCapacity(aNewLength);
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
}
else
{
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
}
if ( !mBuffer->IsMutable() || aNewLength >= mBuffer->StorageLength() )
SetCapacity(aNewLength);
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
// This is needed for |Truncate| callers and also for some callers
// (such as nsACString::do_AppendFromReadable) that are manipulating
// the internals of the string. It also makes sense to do this
@@ -331,11 +325,15 @@ nsSharableCString::shared_buffer_handle_type*
nsSharableCString::GetSharedEmptyBufferHandle()
{
static shared_buffer_handle_type* sBufferHandle = nsnull;
static char_type null_char = char_type(0);
if (!sBufferHandle) {
sBufferHandle = NS_AllocateContiguousHandleWithData(sBufferHandle,
PRUint32(1), (self_type*)nsnull);
sBufferHandle->AcquireReference();
sBufferHandle = new nsNonDestructingSharedBufferHandle<char_type>(&null_char, &null_char, 1);
sBufferHandle->AcquireReference(); // To avoid the |Destroy|
// mechanism unless threads
// race to set the refcount, in
// which case we'll pull the
// same trick in |Destroy|.
}
return sBufferHandle;
}