11 hours of coding session, but the list of improvements is bit shorter today. Thing is, I lost like 3 hours trying to introduce an EventTable template specialization for shared_ptr-ptrs, but couldn't get it working properly. The original problem was that I realized that shared_ptr-contained objects that used event tables (such as hash-work objects) were never actually deleted, since EventTable engine stores a copy of the pointer internally (which is OK for raw pointers, but not OK for smart pointers). So this means we leaked roughly 32kb memory for each hash job (32kb io buffers which were supposed to be cleaned when the object was destroyed). It didn't show up too much in ed2k, altough enough to raise some eyebrows (if you downloaded a lot and fast, you noticed the leak). However, in BT, where there are thousands of chunks, this became a problem very fast.
Anyway, the idea was to use a rather clever construct - EventTable template class specialization, which is itself derived from the main EventTable class template, and overrides handleEvents virtual function. Great in theory, but practice turned out to be more complicated, since we still need some way for lookups in there, and Boost smart pointers are REALLY annoying for that thing - their
operator<, which makes these smart pointers a nightmare when you need to do lookups on objects based on their pointer value (which is the case there). I tried to work around it by overriding the containers comparison predicate, but ran into further problems - namely, we need to store the pointers in there as weak_ptr, since only weak_ptr can implicitly be constructed from shared_ptr (raw pointers can't, which would mean I'd have to duplicate most of the code in the specialization - something I set out to avoid in the first place with the inheritance). However, weak_ptr can only be casted back to shared_ptr via explicit shared_ptr constructor call (which, can throw as well), and even IF all goes right, we still have the problem - if we have two weak_ptrs (in which case the comparison-value would be 0), we break std::map unique-key rule. *duh*.
Other than that, today's changelog is as follows:
- [2259] Fixed .dat file (for temp files) saving and loading - namely I had forgotten one 'break' statement in a switch clause during loading, and wrote wrong tagcount when writing. For the most part, this hopefully didn't cause anyone to lose their temp files (there is one condition where this could theoretically break things). Ofcourse, if you didn't use revisions between 2255 and 2259, you aren't affected.
- [2262] Various additional self-checks related to chunk-verification code; should now properly syncronize/rehash formerly completed, but currently not yet marked as "verified" chunks. (ticket 136)
- [2262] verifyRange() method now also allows disabling the file saving before posting the hash job, to speed up cases where we need to rehash thousands of chunks in same file (no point saving it thousands of times in row).
- [2263] Handles duplicate data (e.g. near the end of download) more gracefully now.
- [2264] Decoupling ChunkCacher init from standard PartialTorrent init (in preparation for possible further decoupling of those two into separate classes).
- [2264] Fixed a number of bugs related to cache files; if you have partial downloads, expect to see a lot of cache verification failures on first start - the cache engine behaviour before this patch was very broken.
- [2264] Properly updates child m_verified ranges when parent verifies ranges, and properly updates parent's m_verified ranges when child verifies ranges.
- [2266] AutoStartTorrents config setting now takes effect immediately on runtime.
- [2268] Fixed Content-Disposition header parsing (in http module), which incorrectly added one " symbol to the end of filename.
Those that have forgotten, AutoStartTorrents configuration setting tells BT plugin to automatically start downloading torrents that were downloaded by other modules. So with this setting turned on, if you download a .torrent from ed2k, or via http, or any other means, BT plugin will start downloading it. It doesn't affect normal shared .torrent files - it only triggers when a download is completed, and filename ends with ".torrent". Hence, it's possible to type "do http://some.url/blah.torrent", and it first downloads the blah.torrent file using HTTP module, and then starts the torrent download using BT module.
Madcat, ZzZz