- tone down the assertion I asked Harrison to include in his fix for
<rdar://problem/
5511128>; it's OK to re-ref and deref the document
as long as you do so after the children are done being destroyed
No effect on release builds. Assertion change only.
Besides the changes listed below, renamed m_hasDeleted flag to
m_deletionHasBegun.
* dom/ContainerNode.cpp: (WebCore::ContainerNode::removeAllChildren):
Added code to set the m_deletionHasBegun flag and some assertions
that test its state.
* dom/Document.h: Removed m_hasDeleted -- we now use m_deletionHasBegun
in the base class TreeShared.
* dom/Document.cpp:
(WebCore::Document::Document): Removed initialization of m_hasDeleted.
(WebCore::Document::removedLastRef): Added code to clear
m_inRemovedLastRefFunction if we end up deciding not to delete this.
* platform/Shared.h:
(WebCore::TreeShared::TreeShared): Added m_deletionHasBegun in addition to
m_inRemovedLastRefFunction (formerly named m_hasRemovedLastRef).
(WebCore::TreeShared::~TreeShared): Assert that m_deletionHasBegun is true.
(WebCore::TreeShared::ref): Assert neither flag is true.
(WebCore::TreeShared::deref): Ditto.
(WebCore::TreeShared::hasOneRef): Ditto.
(WebCore::TreeShared::removedLastRef): Made private. Added code to
set m_hasDeleted to true. Also removed cast; since this class template
has a virtual destructor, we don't need to cast before calling delete.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@25813
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-09-30 Darin Adler <darin@apple.com>
+
+ Reviewed by Maciej.
+
+ - tone down the assertion I asked Harrison to include in his fix for
+ <rdar://problem/5511128>; it's OK to re-ref and deref the document
+ as long as you do so after the children are done being destroyed
+
+ No effect on release builds. Assertion change only.
+
+ Besides the changes listed below, renamed m_hasDeleted flag to
+ m_deletionHasBegun.
+
+ * dom/ContainerNode.cpp: (WebCore::ContainerNode::removeAllChildren):
+ Added code to set the m_deletionHasBegun flag and some assertions
+ that test its state.
+
+ * dom/Document.h: Removed m_hasDeleted -- we now use m_deletionHasBegun
+ in the base class TreeShared.
+ * dom/Document.cpp:
+ (WebCore::Document::Document): Removed initialization of m_hasDeleted.
+ (WebCore::Document::removedLastRef): Added code to clear
+ m_inRemovedLastRefFunction if we end up deciding not to delete this.
+
+ * platform/Shared.h:
+ (WebCore::TreeShared::TreeShared): Added m_deletionHasBegun in addition to
+ m_inRemovedLastRefFunction (formerly named m_hasRemovedLastRef).
+ (WebCore::TreeShared::~TreeShared): Assert that m_deletionHasBegun is true.
+ (WebCore::TreeShared::ref): Assert neither flag is true.
+ (WebCore::TreeShared::deref): Ditto.
+ (WebCore::TreeShared::hasOneRef): Ditto.
+ (WebCore::TreeShared::removedLastRef): Made private. Added code to
+ set m_hasDeleted to true. Also removed cast; since this class template
+ has a virtual destructor, we don't need to cast before calling delete.
+
2007-09-29 Holger Hans Peter Freyther <zecke@selfish.org>
Reviewed by Mark.
Reviewed by Darin.
- <rdar://5261371> Nothing downloaded when exporting bookmarks from iGoogle web history
- - Implemented IWebHTTPURLResponse::allHeaderFields so that if the content disposition is "attachment" we will download the file instead of display it. Also implemented some missing functionality.
+
+ Function for use by WebKit. Currently used only on Windows.
* platform/network/ResourceResponse.cpp:
(WebCore::ResourceResponse::isAttachment):
bool topLevel = !alreadyInsideDestructor;
if (topLevel)
alreadyInsideDestructor = true;
-
+
// List of nodes to be deleted.
- static Node *head;
- static Node *tail;
-
+ static Node* head;
+ static Node* tail;
+
// We have to tell all children that their parent has died.
- Node *n;
- Node *next;
+ Node* n;
+ Node* next;
+ for (n = m_firstChild; n != 0; n = next) {
+ ASSERT(!n->m_deletionHasBegun);
- for (n = m_firstChild; n != 0; n = next ) {
next = n->nextSibling();
n->setPreviousSibling(0);
n->setNextSibling(0);
n->setParent(0);
- if ( !n->refCount() ) {
+ if (!n->refCount()) {
+#ifndef NDEBUG
+ n->m_deletionHasBegun = true;
+#endif
// Add the node to the list of nodes to be deleted.
// Reuse the nextSibling pointer for this purpose.
if (tail)
} else if (n->inDocument())
n->removedFromDocument();
}
-
+
// Only for the top level call, do the actual deleting.
if (topLevel) {
while ((n = head) != 0) {
+ ASSERT(n->m_deletionHasBegun);
+
next = n->nextSibling();
n->setNextSibling(0);
head = next;
if (next == 0)
tail = 0;
-
+
delete n;
}
-
+
alreadyInsideDestructor = false;
m_firstChild = 0;
m_lastChild = 0;
, m_secureForms(0)
, m_designMode(inherit)
, m_selfOnlyRefCount(0)
-#ifndef NDEBUG
- , m_hasDeleted(false)
-#endif
#if ENABLE(SVG)
, m_svgExtensions(0)
#endif
void Document::removedLastRef()
{
- ASSERT(!m_hasDeleted);
+ ASSERT(!m_deletionHasBegun);
if (m_selfOnlyRefCount) {
- // if removing a child removes the last self-only ref, we don't
+ // If removing a child removes the last self-only ref, we don't
// want the document to be destructed until after
// removeAllChildren returns, so we guard ourselves with an
- // extra self-only ref
+ // extra self-only ref.
DocPtr<Document> guard(this);
- // we must make sure not to be retaining any of our children through
- // these extra pointers or we will create a reference cycle
+ // We must make sure not to be retaining any of our children through
+ // these extra pointers or we will create a reference cycle.
m_docType = 0;
m_focusedNode = 0;
m_hoverNode = 0;
delete m_tokenizer;
m_tokenizer = 0;
+
+#ifndef NDEBUG
+ m_inRemovedLastRefFunction = false;
+#endif
} else {
#ifndef NDEBUG
- m_hasDeleted = true;
+ m_deletionHasBegun = true;
#endif
delete this;
}
void selfOnlyRef()
{
- ASSERT(!m_hasDeleted);
+ ASSERT(!m_deletionHasBegun);
++m_selfOnlyRefCount;
}
void selfOnlyDeref()
{
- ASSERT(!m_hasDeleted);
+ ASSERT(!m_deletionHasBegun);
--m_selfOnlyRefCount;
if (!m_selfOnlyRefCount && !refCount()) {
#ifndef NDEBUG
- m_hasDeleted = true;
+ m_deletionHasBegun = true;
#endif
delete this;
}
InheritedBool m_designMode;
int m_selfOnlyRefCount;
-#ifndef NDEBUG
- bool m_hasDeleted;
-#endif
HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons;
/*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
Shared()
: m_refCount(0)
#ifndef NDEBUG
- , m_hasDeleted(false)
+ , m_deletionHasBegun(false)
#endif
{
}
void ref()
{
- ASSERT(!m_hasDeleted);
+ ASSERT(!m_deletionHasBegun);
++m_refCount;
}
void deref()
{
- ASSERT(!m_hasDeleted);
+ ASSERT(!m_deletionHasBegun);
if (--m_refCount <= 0) {
#ifndef NDEBUG
- m_hasDeleted = true;
+ m_deletionHasBegun = true;
#endif
delete static_cast<T*>(this);
}
bool hasOneRef()
{
- ASSERT(!m_hasDeleted);
+ ASSERT(!m_deletionHasBegun);
return m_refCount == 1;
}
private:
int m_refCount;
#ifndef NDEBUG
- bool m_hasDeleted;
+ bool m_deletionHasBegun;
#endif
};
TreeShared()
: m_refCount(0)
, m_parent(0)
+ {
#ifndef NDEBUG
- , m_hasRemovedLastRef(false)
+ m_deletionHasBegun = false;
+ m_inRemovedLastRefFunction = false;
#endif
- {
}
TreeShared(T* parent)
: m_refCount(0)
- , m_parent(parent)
+ , m_parent(0)
+ {
#ifndef NDEBUG
- , m_hasRemovedLastRef(false)
+ m_deletionHasBegun = false;
+ m_inRemovedLastRefFunction = false;
#endif
+ }
+ virtual ~TreeShared()
{
+ ASSERT(m_deletionHasBegun);
}
- virtual ~TreeShared() { }
-
- virtual void removedLastRef() { delete static_cast<T*>(this); }
void ref()
{
- ASSERT(!m_hasRemovedLastRef);
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_inRemovedLastRefFunction);
++m_refCount;
}
void deref()
{
- ASSERT(!m_hasRemovedLastRef);
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_inRemovedLastRefFunction);
if (--m_refCount <= 0 && !m_parent) {
#ifndef NDEBUG
- m_hasRemovedLastRef = true;
+ m_inRemovedLastRefFunction = true;
#endif
removedLastRef();
}
bool hasOneRef() const
{
- ASSERT(!m_hasRemovedLastRef);
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_inRemovedLastRefFunction);
return m_refCount == 1;
}
void setParent(T* parent) { m_parent = parent; }
T* parent() const { return m_parent; }
+#ifndef NDEBUG
+ bool m_deletionHasBegun;
+ bool m_inRemovedLastRefFunction;
+#endif
+
private:
- int m_refCount;
- T* m_parent;
+ virtual void removedLastRef()
+ {
#ifndef NDEBUG
- bool m_hasRemovedLastRef;
+ m_deletionHasBegun = true;
#endif
+ delete this;
+ }
+
+ int m_refCount;
+ T* m_parent;
};
}