Tuesday, July 31, 2007

Tis that time of the month again! MonoTorrent 0.13 has been tagged in SVN, so tis time to update again. As per usual, there's a long list of changes. The biggest of which has been the commit of the latest version of the piece picker. It's a big step up efficiency-wise as compared to the older piece picking algorithm. While the core algorithms are essentially the same, they've been refined and honed into a sleek beast of a class ;) Here's a partial list of changes, but the piece picker change is the biggest reason to update sooner rather than later.

[Improvements]
If a peer sends data too slowly, its piece requests are reassigned to another peer
Smarter piece picker - Allows multiple peers to download the blocks from the same piece.
- Has significantly less overhead than with the old piece picker code
- Significantly faster endgame mode with the new code
Optimised Socket.BeginRead to need approximately 15% less calls to BeginRead.
Optimised the loading of fast resume data.
It is possible to safely call .Stop() on a torrent while it is hashing.


[Bugfixes]
Peers sending a HaveAll are correctly marked as seeders
Fixed bug which resulted in crashes under MS.NET with encryption code
Fixed potential issues with ConnectionListener race conditions
Stale fast-resume data is deleted so it isn't reloaded by accident


[Features]
Added a 'Complete' bool to TorrentManager
Exposed the PeerEncryption stuff so it is possible to tell what encryption method a connection is using
Marked EngineSettings and TorrentSettings as Serializable
It is now possible to create .torrents in a non-blocking way using the async BeginCreate method. The operation is also cancellable.
All eventargs now contain a reference to the TorrentManager that fired the event.

Monday, July 16, 2007

Work has been progressing steadily on Lunar Eclipse, although not quite as fast as i'd hoped for. At the moment, my big challenge is coping with resizing while shapes are rotated. Unfortunately, it doesn't seem that easy to deal with. I've attached a video which demonstrates the issue. Check it out here: http://primates.ximian.com/~amcgovern/sample.avi

When a shape is in it's normal rotation (i.e. angle is zero), the change in Y coordinate in the mouse can be directly related to a change in height of the shape, and a change in X coordinate in the mouse can be directly related to a change in width, so everything resizes nicely.

However, when the shape is rotated by 90 degrees, a change in the X coordinate now relates to the height, and a change in Y is the width. At other angles, a change in 'height' is contributed to by both the X coordinate and Y coordinate change in the mouse.

The problem is that i don't know how best to handle this. The main issues are the following:
1) The amount of resizing to do should be based on the how far the mouse moves in the 'right' direction. i.e. if you move the mouse perpendicular to the side of the shape, the side should expand to follow the mouse
2) When resizing, the shapes shouldn't float around. As you can see towards the end, when i resize the rotated shape, it physically moves around the canvas.

So, if anyone has any advice on how to tackle these issues without tonnes of helper code, that'd be amazing. Currently, things are looking like they could get fairly messy trying to get this to work.

If anyone wants to check out the code, it's available at: http://anonsvn.mono-project.com/source/trunk/lunareclips

Wednesday, July 11, 2007

While i knew that creationism had found a home in america, i did't realise they had dedicated museums for it. Still, it's nice to know that the traditional values of common sense, reason and logic are being held up, like a bright torch, to lead us on into the future. I'd hate to think stupid things like scientific evidence could get in the way of a proper education as to how things happened way back when.
Since my last blogpost several things have been happening in MonoTorrent. Firstly, i finally managed to track down what was probably the most elusive bug to date.

Here's an abridged version of the events.

I had been getting reports on and off of strange crashes in the BigInteger class. These crashes appeared to be memory corruption problems of some sort. Needless to say, i immediately suspected that the reporter either had faulty ram or a highly overclocked system or even a corrupt .NET framework install. However, after getting him to run Memtest and a few other tests, i had to rule that out as a cause. However, as i couldn't reproduce, and he couldn't reproduce, there wasn't much i could do.

Time passed, several weeks i think and i was getting him to log every access to the class for me. Two other people had reported the same bug, so i knew something was definitely up. The only thing is, i couldn't reproduce it, no matter what i tried! I was hammering the code with dozens of new connections a second and getting no crash.

I had been in touch with Sebastien Pouliot who was doing his best to help me with tracking down the bug. Eventually i got fairly pissed off about the whole thing and decided it was time to solve this once and for all. I had already wasted hours trying to reproduce this at this stage, so if i didn't get it fixed this time, i was just going to completely disable the encryption code and thus "fix" the issue.

I logged into the windows machine i had in work, coded up a quick testcase which hammered the BigInteger class with random calculations. This didn't break after a fairly lengthy time running. Then i added 10 threads performing the calculation, as this was a 4 processor machine, so this way i could check more numbers at a time and so (hopefully) get a crash sooner.

BANG! I had reproduced.

I then spent the next hour or so (wasting some of both miguels and sebastians time) in finally tracking it down to a compiler bug in gmcs. The conditions for reproducing the bug were fairly strict, which is why i never managed to reproduce it myself.

1) You must be running under MS.NET 2.0 (meaning you have to be on windows)
2) You must be running a multi-processor machine
3) There must be more than 1 thread running a BigInteger.ModPow calculation simultaneously.
4) It has to be Wednesday ;)

The quick fix was to just compile the big integer code using the microsoft compiler. The only thing i'll say is i pity the person who has to track down the bug in the compiler, it's unlikely to be easy.

Hit Counter