eMule's CUploadQueue class uses a 100ms cyclic timer that latches TimerProc() function, which then proceeds to call many functions.

When a computer running eMule is under heavy load, or those functions take very long to execute (eg. with high upload speeds when many clients are uploaded to concurrently) the timer's execution delay becomes very long. It's no longer 100ms timer - I've seen ten timer ticks taking even over ten seconds.

Also, sometimes eMule freezes. I think it may be due to getting a file chunk close to file end, where eMule extends the file by even hundreds of megabytes, or when completing a file. Eg. my incoming -folder is on a different physical disk than my temp -folder, so the files actually are moved. These operations take quite a long time, and apparently freeze parts of eMule.

When upload timer doesn't run often enough, clients start dropping from upload list. Perhaps because the clients want to get some bytes very often, or perhaps because Windows sockets time out. Whatever the reason, I've seen my upload list drop from over a hundred clients to nearly no clients, which again causes more problems - upload list has to be filled from queue, which takes a short while, and data rates drop dramatically.

To counter these problems I'd propose moving the timer function to another thread - one that isn't hopefully so dependant on main application thread freezing sometimes. That would counter the problem with occasional freezes with eMule, but might also help in problems that haven't been found yet..

While I'm no expert in Windows programming, it looks to me that the timer restarts when the callback function returns. So, it's essential that the callback function returns very fast if the timer is exepected to latch exactly at the periods it's run at. If the callback function execution time is very long, the timer goes off pitch. Eg. assume the callback function runs 30ms, and the timer period is 100ms. Now you get (1000/(100+30) = 7.7) ticks per second instead of (1000/100 = 10). Any function that assumes ten ticks per second will now be far from the target. Also, I don't know what restrictions Windows puts on the timer execution context, but as timers are typically interrupt-based, the execution context might have restrictions on it.

Of course the problem could partially be solved by changing the timer tick assumption. Instead of assuming 10 ticks per second, the TimerProc() would keep count on how long it's been since last execution time, and where execution time is needed (eg. counting how many bytes should be uploaded in this timer cycle) the time difference would be used instead of 100ms assumption. This doesn't, however, solve any problems that might arise from running in execution context given by the timer interrupt instead of in the application's normal execution context.

Another issue completely is optimizing heavily the functions that are driven by the timer. For that, some profiling data would be needed, and I haven't even checked what those functions do, or which parts of the codebase they touch.

So, I wrote a simple patch that creates a thread where the timer was created before, and then within that thread it creates a timer, and starts running. Does pretty much the same things the old TimerProc() did, but I've added some debuggin output to see how it runs. Downside is, that while the patch compiles, the resulting application doesn't work. Help in solving the problem would be appreciated. And you either know how to contact me, or you don't need to know, so I don't need to put contact information here.

Note: this doesn't work. eMule isn't threadsafe, so lots of work has to be done..