From: Michal H. <ms...@gm...> - 2008-04-15 13:52:29
|
Hi. This the second attempt for patchset which adds support for smart pointers also for CPdf. It is based on smart_ptr & weak_ptr pattern (thanks Jozo for coming with idea and implementation howto). CPdf unlike other cobject is not so simple to wrap by shared_ptr because of cyclic references (CPdf initializes IProperty objects which in turn refers back to the pdf). However changing IProperty::pdf from CPdf* to the weak_ptr<CPdf> does the trick. This change is rather intrusive to the rest of code, because it has to update all usage of CPdf usage as well as update low-level objects. Attached patches transform CPdf* to - weak_ptr<CPdf> for low-level - smart_ptr<CPdf> for high-level Patches coming in this patch-set are split to add features incrementally (see separate emails for detailed description and patch). All of them are compilable and higher one depends on the lower. I have tested it on couple of documents (including PDF specification) and no single problem occurred. I think that risk for future problems is only that we can force some nasty hidden bugs to be visible. I think it is better to have them visible even if it would mean that we will have kind of less stable next release. @Jozo could you comment changes, you would like to change (code style etc.). @Martin could you check whether this is mergeable with your current QT4 branch or it simple produce too many conflicts that it should wait for later inclusion. If it is OK with you (give me ACK), I would suggest to include ASAP. I don't want to create separate branch for this changes because I don't see any potential for future changes here (besides sync with current CVS). Let me know if I am missing something. Changelog v1 -> v2 ================== Mainly sync with current CVS state and one additional patch (06) for tests/bench code which has been added in the mean time. * Patch 01 ---------- Changes CPdf::getInstance from CPdf* to shared_ptr<CPdf> and updates all places where the result is used. * Patch 02 ---------- Preparatory patch for observers. Rationale is that sometimes it is impossible to unregister observers right in time and it is much easier to disable them (IObserver::setActive(false)) which guarantees that they are not called and noting bad can happen even if they are still registered. As an example, consider CPdf transformed to shared_ptr which is deallocated in the moment when the last reference is droped and shared_ptr itself is expired. This means that also all weak_ptr to this shared_ptr are not valid. As a result, ~CPdf is not allowed to dereference any objects or do anything where _this field (see Patch 03) is needed. Unfortunately this is the problem for page tree observers which can't be cleaned up sooner then in ~CPdf. Effectively, it is much simpler to deactivate them rather then store them in a complicated way and add more overhead for synchronization with changes in the page tree. Leaving observer registered and not active, of course, adds some memory overhead, but all properties are discarded in ~CPdf anyway. However, if there are some pending references to them (due to scripting e.g.) they could trigger observer with invalid data. IObserver::isActive is checked before this can actually happen. On the other hand, setActive can be particularly useful for situations where we would need temporarily disable notification. This patch can be added also separately without the rest. * Patch 03 ---------- Changes IProperty::pdf from CPdf* to weak_ptr<CPdf> and CPdf::_this field was added. The first one is used to reffer to the pdf and the second one is used to initialize all its properties. Both of them are initialized from shared_ptr returned by getInstance factory method and they are valid until shared_ptr is alive. * Patch 04 ---------- Updates pdf deleter to also close file handle so that it can be removed from CPdf. This is cleanup patch. * Patch 05 ---------- Updates design documentation for CPdf. I haven't found any mention about CPdf usage in cobjects.xml so I haven't updated that part (the one in cpdf.html should be enough anyway). * Patch 06 ---------- Simple update of tests/bench code to follow changes in CPdf::getInstance signature. -- Michal Hocko |