New attempt to fix Pavel's crash, this modifies r40206.

The global list of cloned buffers was a bad idea. We don't have multiple
export threads, but we can have multiple autosave threads. So now we keep
more than one of these lists at the same time, and each cloned buffer has
a pointer to the relevant list. Note that this would make multiple export
possible, if we wanted to do that at some time.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_2_0_X@40229 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2011-11-20 18:56:36 +00:00
parent b9eb3af385
commit bd826dae67
2 changed files with 21 additions and 19 deletions

View File

@ -140,13 +140,13 @@ void showPrintError(string const & name)
Alert::error(_("Print document failed"), str); Alert::error(_("Print document failed"), str);
} }
/// a list of Buffers we cloned
set<Buffer *> cloned_buffer_list;
} // namespace anon } // namespace anon
// A storehouse for the cloned buffers.
list<CloneList> cloned_buffers;
class Buffer::Impl class Buffer::Impl
{ {
public: public:
@ -298,6 +298,8 @@ public:
/// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_ /// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_
/// This one is useful for preview detached in a thread. /// This one is useful for preview detached in a thread.
Buffer const * cloned_buffer_; Buffer const * cloned_buffer_;
///
CloneList * clone_list_;
/// are we in the process of exporting this buffer? /// are we in the process of exporting this buffer?
mutable bool doing_export; mutable bool doing_export;
@ -334,7 +336,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_,
toc_backend(owner), macro_lock(false), timestamp_(0), toc_backend(owner), macro_lock(false), timestamp_(0),
checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false), checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false),
bibfile_cache_valid_(false), cloned_buffer_(cloned_buffer), bibfile_cache_valid_(false), cloned_buffer_(cloned_buffer),
doing_export(false), parent_buffer(0) clone_list_(0), doing_export(false), parent_buffer(0)
{ {
if (!cloned_buffer_) { if (!cloned_buffer_) {
temppath = createBufferTmpDir(); temppath = createBufferTmpDir();
@ -393,13 +395,13 @@ Buffer::~Buffer()
if (isClone()) { if (isClone()) {
// this is in case of recursive includes: we won't try to delete // this is in case of recursive includes: we won't try to delete
// ourselves as a child. // ourselves as a child.
cloned_buffer_list.erase(this); d->clone_list_->erase(this);
// loop over children // loop over children
Impl::BufferPositionMap::iterator it = d->children_positions.begin(); Impl::BufferPositionMap::iterator it = d->children_positions.begin();
Impl::BufferPositionMap::iterator end = d->children_positions.end(); Impl::BufferPositionMap::iterator end = d->children_positions.end();
for (; it != end; ++it) { for (; it != end; ++it) {
Buffer * child = const_cast<Buffer *>(it->first); Buffer * child = const_cast<Buffer *>(it->first);
if (cloned_buffer_list.erase(child)) if (d->clone_list_->erase(child))
delete child; delete child;
} }
// FIXME Do we really need to do this right before we delete d? // FIXME Do we really need to do this right before we delete d?
@ -442,25 +444,21 @@ Buffer::~Buffer()
Buffer * Buffer::clone() const Buffer * Buffer::clone() const
{ {
BufferMap bufmap; BufferMap bufmap;
masterBuffer()->clone(bufmap); cloned_buffers.push_back(CloneList());
CloneList * clones = &cloned_buffers.back();
masterBuffer()->clone(bufmap, clones);
// make sure we got cloned // make sure we got cloned
BufferMap::const_iterator bit = bufmap.find(this); BufferMap::const_iterator bit = bufmap.find(this);
LASSERT(bit != bufmap.end(), return 0); LASSERT(bit != bufmap.end(), return 0);
Buffer * cloned_buffer = bit->second; Buffer * cloned_buffer = bit->second;
// record the list of cloned buffers
cloned_buffer_list.clear();
BufferMap::iterator it = bufmap.begin();
BufferMap::iterator en = bufmap.end();
for (; it != en; ++it)
cloned_buffer_list.insert(it->second);
return cloned_buffer; return cloned_buffer;
} }
void Buffer::clone(BufferMap & bufmap) const void Buffer::clone(BufferMap & bufmap, CloneList * clones) const
{ {
// have we already been cloned? // have we already been cloned?
if (bufmap.find(this) != bufmap.end()) if (bufmap.find(this) != bufmap.end())
@ -468,6 +466,8 @@ void Buffer::clone(BufferMap & bufmap) const
Buffer * buffer_clone = new Buffer(fileName().absFileName(), false, this); Buffer * buffer_clone = new Buffer(fileName().absFileName(), false, this);
bufmap[this] = buffer_clone; bufmap[this] = buffer_clone;
clones->insert(buffer_clone);
buffer_clone->d->clone_list_ = clones;
buffer_clone->d->macro_lock = true; buffer_clone->d->macro_lock = true;
buffer_clone->d->children_positions.clear(); buffer_clone->d->children_positions.clear();
// FIXME (Abdel 09/01/2010): this is too complicated. The whole children_positions and // FIXME (Abdel 09/01/2010): this is too complicated. The whole children_positions and
@ -481,7 +481,7 @@ void Buffer::clone(BufferMap & bufmap) const
dit.setBuffer(buffer_clone); dit.setBuffer(buffer_clone);
Buffer * child = const_cast<Buffer *>(it->second.second); Buffer * child = const_cast<Buffer *>(it->second.second);
child->clone(bufmap); child->clone(bufmap, clones);
BufferMap::iterator it = bufmap.find(child); BufferMap::iterator it = bufmap.find(child);
LASSERT(it != bufmap.end(), continue); LASSERT(it != bufmap.end(), continue);
Buffer * child_clone = it->second; Buffer * child_clone = it->second;

View File

@ -75,6 +75,8 @@ class FileNameList;
class Buffer; class Buffer;
typedef std::list<Buffer *> ListOfBuffers; typedef std::list<Buffer *> ListOfBuffers;
/// a list of Buffers we cloned
typedef std::set<Buffer *> CloneList;
/** The buffer object. /** The buffer object.
@ -214,7 +216,7 @@ private:
/// ///
typedef std::map<Buffer const *, Buffer *> BufferMap; typedef std::map<Buffer const *, Buffer *> BufferMap;
/// ///
void clone(BufferMap &) const; void clone(BufferMap &, CloneList *) const;
/// save timestamp and checksum of the given file. /// save timestamp and checksum of the given file.
void saveCheckSum() const; void saveCheckSum() const;
/// read a new file /// read a new file