Bug 260712 - KTorrent crash after several minutes seeding many torrents
Summary: KTorrent crash after several minutes seeding many torrents
Status: RESOLVED FIXED
Alias: None
Product: ktorrent
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR crash (vote)
Target Milestone: ---
Assignee: Joris Guisson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-19 15:49 UTC by Alexey Shildyakov
Modified: 2011-01-10 19:09 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
valgrind log (275.31 KB, text/plain)
2011-01-10 00:40 UTC, Alexey Shildyakov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Shildyakov 2010-12-19 15:49:13 UTC
Application: ktorrent (4.1dev)
KDE Platform Version: 4.5.4 (KDE 4.5.4) (Compiled from sources)
Qt Version: 4.7.1
Operating System: Linux 2.6.36-gentoo-r1 x86_64
Distribution (Platform): Gentoo Packages

-- Information about the crash:
KTorrent crash after 2-5 minutes seeding over 150 torrents.

I know about _XIOError. But this crash happens really every time. I attach another crashes info. Thread 2 is similar for every these crashes.

libktorrent: at 38f23b7d678602b36fcdca20d2d8eb7012ea01dc commit
ktorrent: at b78b136c24da0df3e86ada1ee438de32ad99e531 commit

The crash can be reproduced every time.

-- Backtrace:
Application: KTorrent (ktorrent), signal: Segmentation fault
pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
	in ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
[Current thread is 1 (Thread 0x7f5be783a760 (LWP 9612))]

Thread 10 (Thread 0x7f5bd3c65710 (LWP 9614)):
[KCrash Handler]
#6  QCoreApplication::notifyInternal (this=0x7fff4a6e8920, receiver=0x7f5ba8093ca0, event=0x7f5bd3c64b90) at kernel/qcoreapplication.cpp:719
#7  0x00007f5be4f923fa in sendEvent (this=0x7f5bcc0056e0) at kernel/qcoreapplication.h:215
#8  QTimerInfoList::activateTimers (this=0x7f5bcc0056e0) at kernel/qeventdispatcher_unix.cpp:603
#9  0x00007f5be4f8f178 in timerSourceDispatch (source=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:184
#10 idleTimerSourceDispatch (source=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:231
#11 0x00007f5bdf48a399 in g_main_dispatch (context=0xe6d840) at gmain.c:2149
#12 g_main_context_dispatch (context=0xe6d840) at gmain.c:2702
#13 0x00007f5bdf48e220 in g_main_context_iterate (context=0xe6d840, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:2780
#14 0x00007f5bdf48e3c2 in g_main_context_iteration (context=0xe6d840, may_block=1) at gmain.c:2843
#15 0x00007f5be4f8ee3e in QEventDispatcherGlib::processEvents (this=0xf9dd20, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:415
#16 0x00007f5be4f5e192 in QEventLoop::processEvents (this=<value optimized out>, flags=) at kernel/qeventloop.cpp:149
#17 0x00007f5be4f5e55d in QEventLoop::exec (this=0x7f5bd3c64e20, flags=) at kernel/qeventloop.cpp:201
#18 0x00007f5be4e5d0f8 in QThread::exec (this=<value optimized out>) at thread/qthread.cpp:490
#19 0x00007f5be4e5fbc7 in QThreadPrivate::start (arg=0xf9e310) at thread/qthread_unix.cpp:285
#20 0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#21 0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 9 (Thread 0x7f5bd3464710 (LWP 9615)):
#0  0x00007f5be33f7d03 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=500) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007f5be7300d11 in net::Poll::poll (this=0x7f5bd3463d50, timeout=<value optimized out>) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/poll.cpp:99
#2  0x00007f5be7378517 in dht::RPCServer::Private::run (this=<value optimized out>) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/dht/rpcserver.cpp:95
#3  0x00007f5be4e5fbc7 in QThreadPrivate::start (arg=0xff8a80) at thread/qthread_unix.cpp:285
#4  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#5  0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 8 (Thread 0x7f5bd4466710 (LWP 9616)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f5bd04441e1 in metronom_sync_loop (this=0x3b66fd0) at metronom.c:870
#2  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#3  0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 7 (Thread 0x7f5bc4195710 (LWP 9617)):
#0  g_main_context_prepare (context=0x3af6f70, priority=<value optimized out>) at gmain.c:2453
#1  0x00007f5bdf48ddf2 in g_main_context_iterate (context=0x3af6f70, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:2760
#2  0x00007f5bdf48e3c2 in g_main_context_iteration (context=0x3af6f70, may_block=1) at gmain.c:2843
#3  0x00007f5be4f8ee8e in QEventDispatcherGlib::processEvents (this=0x3afa8d0, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:417
#4  0x00007f5be4f5e192 in QEventLoop::processEvents (this=<value optimized out>, flags=) at kernel/qeventloop.cpp:149
#5  0x00007f5be4f5e55d in QEventLoop::exec (this=0x7f5bc4194dc0, flags=) at kernel/qeventloop.cpp:201
#6  0x00007f5be4e5d0f8 in QThread::exec (this=<value optimized out>) at thread/qthread.cpp:490
#7  0x00007f5bd069e030 in Phonon::Xine::XineThread::run (this=0x3b00700) at /var/tmp/portage/media-sound/phonon-4.4.3/work/phonon-4.4.3/xine/xinethread.cpp:143
#8  0x00007f5be4e5fbc7 in QThreadPrivate::start (arg=0x3b00700) at thread/qthread_unix.cpp:285
#9  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#10 0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 6 (Thread 0x7f5bc378f710 (LWP 9618)):
#0  0x00007f5be33f7d03 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007f5bdd942853 in poll_func (ufds=0x3b6a090, nfds=<value optimized out>, timeout=<value optimized out>, userdata=0x3af9e40) at pulse/thread-mainloop.c:75
#2  0x00007f5bdd932816 in pa_mainloop_poll (m=0x3af9d40) at pulse/mainloop.c:879
#3  0x00007f5bdd933bee in pa_mainloop_iterate (m=0x3af9d40, block=<value optimized out>, retval=0x0) at pulse/mainloop.c:961
#4  0x00007f5bdd933cd0 in pa_mainloop_run (m=0x3af9d40, retval=0x0) at pulse/mainloop.c:979
#5  0x00007f5bdd942633 in thread (userdata=0x3af9ba0) at pulse/thread-mainloop.c:94
#6  0x00007f5bdc91c217 in internal_thread_func (userdata=0x3af9ef0) at pulsecore/thread-posix.c:83
#7  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#8  0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 5 (Thread 0x7f5bbef8d710 (LWP 9619)):
#0  pthread_cond_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:162
#1  0x00007f5bd0452323 in fifo_peek_int (fifo=0x3b8d220, blocking=1) at audio_out.c:348
#2  0x00007f5bd0453d3a in fifo_peek (this_gen=<value optimized out>) at audio_out.c:388
#3  ao_loop (this_gen=<value optimized out>) at audio_out.c:1015
#4  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#5  0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 4 (Thread 0x7f5bb8b6e710 (LWP 9644)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f5be4e5f21a in thread_sleep (ti=0x7f5bb8b6dda0) at thread/qthread_unix.cpp:435
#2  0x00007f5be4e5f370 in QThread::msleep (msecs=<value optimized out>) at thread/qthread_unix.cpp:461
#3  0x00007f5be72fbecd in net::DownloadThread::update (this=0xe3a460) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/downloadthread.cpp:91
#4  0x00007f5be72fc7c9 in net::NetworkThread::run (this=0xe3a460) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/networkthread.cpp:48
#5  0x00007f5be4e5fbc7 in QThreadPrivate::start (arg=0xe3a460) at thread/qthread_unix.cpp:285
#6  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#7  0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 3 (Thread 0x7f5bb836d710 (LWP 9645)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f5be4e5f21a in thread_sleep (ti=0x7f5bb836cda0) at thread/qthread_unix.cpp:435
#2  0x00007f5be4e5f370 in QThread::msleep (msecs=<value optimized out>) at thread/qthread_unix.cpp:461
#3  0x00007f5be72fadb5 in net::UploadThread::update (this=0xe3aad0) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/uploadthread.cpp:89
#4  0x00007f5be72fc7c9 in net::NetworkThread::run (this=0xe3aad0) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/networkthread.cpp:48
#5  0x00007f5be4e5fbc7 in QThreadPrivate::start (arg=0xe3aad0) at thread/qthread_unix.cpp:285
#6  0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#7  0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 2 (Thread 0x7f5bb7b6c710 (LWP 9646)):
#0  0x00007f5be33f7d03 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=5000) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007f5bdab17938 in send_dg (statp=0x7f5bb7b6cdc8, buf=<value optimized out>, buflen=<value optimized out>, buf2=0x0, buflen2=<value optimized out>, ans=0x7f5bb7b6abd0 "k\021\201\200", anssiz=1024, ansp=0x7f5bb7b6b450, ansp2=0x0, nansp2=0x0, resplen2=0x0) at res_send.c:1058
#2  __libc_res_nsend (statp=0x7f5bb7b6cdc8, buf=<value optimized out>, buflen=<value optimized out>, buf2=0x0, buflen2=<value optimized out>, ans=0x7f5bb7b6abd0 "k\021\201\200", anssiz=1024, ansp=0x7f5bb7b6b450, ansp2=0x0, nansp2=0x0, resplen2=0x0) at res_send.c:556
#3  0x00007f5bdab15ae5 in __libc_res_nquery (statp=0x7f5bb7b6cdc8, name=<value optimized out>, class=<value optimized out>, type=<value optimized out>, answer=0x7f5bb7b6abd0 "k\021\201\200", anslen=<value optimized out>, answerp=0x7f5bb7b6b450, answerp2=0x0, nanswerp2=0x0, resplen2=0x0) at res_query.c:225
#4  0x00007f5bba37443c in _nss_dns_gethostbyaddr2_r (addr=<value optimized out>, len=<value optimized out>, af=2, result=<value optimized out>, buffer=<value optimized out>, buflen=<value optimized out>, errnop=0x7f5bb7b6c698, h_errnop=0x7f5bb7b6bbbc, ttlp=0x0) at nss_dns/dns-host.c:471
#5  0x00007f5bba3745a5 in _nss_dns_gethostbyaddr_r (addr=0x7f5bb7b6a950, len=1, af=5000, result=0xffffffffffffffff, buffer=0x0, buflen=0, errnop=0x7f5bb7b6c698, h_errnop=0x7f5bb7b6bbbc) at nss_dns/dns-host.c:530
#6  0x00007f5be34173a8 in __gethostbyaddr_r (addr=0x7f5bcc8a8114, len=4, type=<value optimized out>, resbuf=0x7f5bb7b6bb80, buffer=<value optimized out>, buflen=<value optimized out>, result=0x7f5bb7b6bbb0, h_errnop=0x7f5bb7b6bbbc) at ../nss/getXXbyYY_r.c:253
#7  0x00007f5be341f4ed in getnameinfo (sa=0x7f5bcc8a8110, addrlen=<value optimized out>, host=0x7f5bb7b6bce0 "", hostlen=199, serv=0x7f5bb7b6bc10 "", servlen=199, flags=<value optimized out>) at getnameinfo.c:223
#8  0x00007f5be73001fb in net::ReverseResolver::resolve (this=<value optimized out>, addr=...) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/reverseresolver.cpp:64
#9  0x00007f5be7300258 in net::ReverseResolver::run (this=0x7f5bccd90f90) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/reverseresolver.cpp:73
#10 0x00007f5be7300303 in net::ReverseResolverThread::run (this=0x7f5bcc738680) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/reverseresolver.cpp:118
#11 0x00007f5be4e5fbc7 in QThreadPrivate::start (arg=0x7f5bcc738680) at thread/qthread_unix.cpp:285
#12 0x00007f5be4bcbc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#13 0x00007f5be3400a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 1 (Thread 0x7f5be783a760 (LWP 9612)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f5be4e5f21a in thread_sleep (ti=0x7fff4a6e8500) at thread/qthread_unix.cpp:435
#2  0x00007f5be4e5f370 in QThread::msleep (msecs=<value optimized out>) at thread/qthread_unix.cpp:461
#3  0x00007f5bd06bce0a in Phonon::Xine::Backend::~Backend (this=0x3af4c50, __in_chrg=<value optimized out>) at /var/tmp/portage/media-sound/phonon-4.4.3/work/phonon-4.4.3/xine/backend.cpp:111
#4  0x00007f5be1c62fa7 in Phonon::FactoryPrivate::~FactoryPrivate (this=0x7f5bcc2ecdf0, __in_chrg=<value optimized out>) at /var/tmp/portage/media-sound/phonon-4.4.3/work/phonon-4.4.3/phonon/factory.cpp:221
#5  0x00007f5be3364045 in __run_exit_handlers (status=1, listp=0x7f5be368f4a8, run_list_atexit=true) at exit.c:78
#6  0x00007f5be3364095 in exit (status=1248756868) at exit.c:100
#7  0x00007f5be408f548 in qt_xio_errhandler () at kernel/qapplication_x11.cpp:773
#8  0x00007f5be5f5fd40 in KApplication::xioErrhandler (this=0x7fff4a6e8920, dpy=0xe8c6e0) at /var/tmp/portage/kde-base/kdelibs-4.5.4/work/kdelibs-4.5.4/kdeui/kernel/kapplication.cpp:416
#9  0x00007f5be16b2c0e in _XIOError (dpy=0xe8c6e0) at XlibInt.c:1602
#10 0x00007f5be16b1add in _XEventsQueued (dpy=0xe8c6e0, mode=<value optimized out>) at xcb_io.c:307
#11 0x00007f5be16a1cef in XEventsQueued (dpy=0xe8c6e0, mode=2) at Pending.c:43
#12 0x00007f5be40cadc7 in x11EventSourcePrepare (s=0xe753f0, timeout=<value optimized out>) at kernel/qguieventdispatcher_glib.cpp:79
#13 0x00007f5bdf48d99d in g_main_context_prepare (context=0xe69f20, priority=<value optimized out>) at gmain.c:2469
#14 0x00007f5bdf48ddf2 in g_main_context_iterate (context=0xe69f20, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:2760
#15 0x00007f5bdf48e3c2 in g_main_context_iteration (context=0xe69f20, may_block=1) at gmain.c:2843
#16 0x00007f5be4f8ee3e in QEventDispatcherGlib::processEvents (this=0xe6f180, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:415
#17 0x00007f5be40caba6 in QGuiEventDispatcherGlib::processEvents (this=0x7fff4a6e8484, flags=<value optimized out>) at kernel/qguieventdispatcher_glib.cpp:204
#18 0x00007f5be4f5e192 in QEventLoop::processEvents (this=<value optimized out>, flags=) at kernel/qeventloop.cpp:149
#19 0x00007f5be4f5e55d in QEventLoop::exec (this=0x7fff4a6e8880, flags=) at kernel/qeventloop.cpp:201
#20 0x00007f5be4f60dfb in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1009
#21 0x000000000042d352 in main (argc=<value optimized out>, argv=<value optimized out>) at /var/tmp/portage/net-p2p/ktorrent-9999/work/ktorrent-9999/ktorrent/main.cpp:176

This bug may be a duplicate of or related to bug 259899, bug 251120.

Possible duplicates by query: bug 260359, bug 260347, bug 260253, bug 259975, bug 259814.

Reported using DrKonqi
Comment 1 Alexey Shildyakov 2010-12-19 15:53:28 UTC
Sorry. I submit attachments for another bug 259814
Attachment 55073 [details]
Attachment 55074 [details]
Attachment 55075 [details]
Comment 2 Joris Guisson 2010-12-19 19:23:22 UTC
I have seen that one a few times myself, thought I fixed it with a commit on the same day (cf258c805c536876b278b2e8e18c4d94440f23e8).
Comment 3 Joris Guisson 2010-12-19 20:15:23 UTC
Are you sure were running that version ?
Comment 4 Alexey Shildyakov 2010-12-19 20:50:54 UTC
Hmm... Cannot find that commit. The latest commited today I can see:
libktorrent: 01740395b688a01b777125be31607a426bbb1db4
ktorrent: 043144139b0560052fec0c6934143609c7c22c6b, 0dab80755cb920cd356cbf1651d10cc8dc6670e0

Yes. I'm sure to running that version. Now I recompiled (from that incident I compile ktorrent and libktorrent simultaneously) to commits:
libktorrent: 01740395b688a01b777125be31607a426bbb1db4
ktorrent: 043144139b0560052fec0c6934143609c7c22c6b

And the problem still exists.
Comment 5 Alexey Shildyakov 2010-12-20 19:35:32 UTC
Application: KTorrent (ktorrent), signal: Segmentation fault
pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
	in ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
[Current thread is 1 (Thread 0x7f007000c760 (LWP 28681))]

Thread 10 (Thread 0x7f0057fff710 (LWP 28683)):
[KCrash Handler]
#6  0x00000000055cae40 in ?? ()
#7  0x00007f006d7343eb in QCoreApplicationPrivate::checkReceiverThread (this=<value optimized out>, receiver=0x5b59130) at kernel/qcoreapplication.cpp:349
#8  0x00007f006c7e6e86 in QApplication::notify (this=0x7fffe51e4980, receiver=0x7f0057ffe4e0, e=0x7f0057ffeb90) at kernel/qapplication.cpp:3737
#9  0x000000000043de6c in kt::App::notify (this=0x7fffe51e4980, receiver=0x5b59130, event=0x7f0057ffeb90) at /var/tmp/portage/net-p2p/ktorrent-9999/work/ktorrent-9999/ktorrent/app.cpp:97
#10 0x00007f006d73158b in QCoreApplication::notifyInternal (this=0x7fffe51e4980, receiver=0x5b59130, event=0x7f0057ffeb90) at kernel/qcoreapplication.cpp:732
#11 0x00007f006d7643fa in sendEvent (this=0x2398c60) at kernel/qcoreapplication.h:215
#12 QTimerInfoList::activateTimers (this=0x2398c60) at kernel/qeventdispatcher_unix.cpp:603
#13 0x00007f006d761178 in timerSourceDispatch (source=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:184
#14 idleTimerSourceDispatch (source=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:231
#15 0x00007f0067c5c399 in g_main_dispatch (context=0x23989b0) at gmain.c:2149
#16 g_main_context_dispatch (context=0x23989b0) at gmain.c:2702
#17 0x00007f0067c60220 in g_main_context_iterate (context=0x23989b0, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:2780
#18 0x00007f0067c603c2 in g_main_context_iteration (context=0x23989b0, may_block=1) at gmain.c:2843
#19 0x00007f006d760e3e in QEventDispatcherGlib::processEvents (this=0x24bd410, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:415
#20 0x00007f006d730192 in QEventLoop::processEvents (this=<value optimized out>, flags=) at kernel/qeventloop.cpp:149
#21 0x00007f006d73055d in QEventLoop::exec (this=0x7f0057ffee20, flags=) at kernel/qeventloop.cpp:201
#22 0x00007f006d62f0f8 in QThread::exec (this=<value optimized out>) at thread/qthread.cpp:490
#23 0x00007f006d631bc7 in QThreadPrivate::start (arg=0x24bd850) at thread/qthread_unix.cpp:285
#24 0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#25 0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 9 (Thread 0x7f00577fe710 (LWP 28684)):
#0  0x00007f006bbc9d03 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=500) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007f006fad2d11 in net::Poll::poll (this=0x7f00577fdd50, timeout=<value optimized out>) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/poll.cpp:99
#2  0x00007f006fb4a517 in dht::RPCServer::Private::run (this=<value optimized out>) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/dht/rpcserver.cpp:95
#3  0x00007f006d631bc7 in QThreadPrivate::start (arg=0x7f0058016c40) at thread/qthread_unix.cpp:285
#4  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#5  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 8 (Thread 0x7f005cc38710 (LWP 28686)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f00549bd1e1 in metronom_sync_loop (this=0x50cb5e0) at metronom.c:870
#2  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#3  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 7 (Thread 0x7f004c72a710 (LWP 28687)):
#0  0x00007f006bbc9d03 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007f0067c5ff7d in g_main_context_poll (context=0x505beb0, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:3093
#2  g_main_context_iterate (context=0x505beb0, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:2775
#3  0x00007f0067c603c2 in g_main_context_iteration (context=0x505beb0, may_block=1) at gmain.c:2843
#4  0x00007f006d760e8e in QEventDispatcherGlib::processEvents (this=0x50588a0, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:417
#5  0x00007f006d730192 in QEventLoop::processEvents (this=<value optimized out>, flags=) at kernel/qeventloop.cpp:149
#6  0x00007f006d73055d in QEventLoop::exec (this=0x7f004c729dc0, flags=) at kernel/qeventloop.cpp:201
#7  0x00007f006d62f0f8 in QThread::exec (this=<value optimized out>) at thread/qthread.cpp:490
#8  0x00007f0054c17030 in Phonon::Xine::XineThread::run (this=0x505ee60) at /var/tmp/portage/media-sound/phonon-4.4.3/work/phonon-4.4.3/xine/xinethread.cpp:143
#9  0x00007f006d631bc7 in QThreadPrivate::start (arg=0x505ee60) at thread/qthread_unix.cpp:285
#10 0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#11 0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 6 (Thread 0x7f004bd24710 (LWP 28688)):
#0  0x00007f006bbc9d03 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007f0066114853 in poll_func (ufds=0x50ce810, nfds=<value optimized out>, timeout=<value optimized out>, userdata=0x505e910) at pulse/thread-mainloop.c:75
#2  0x00007f0066104816 in pa_mainloop_poll (m=0x505e810) at pulse/mainloop.c:879
#3  0x00007f0066105bee in pa_mainloop_iterate (m=0x505e810, block=<value optimized out>, retval=0x0) at pulse/mainloop.c:961
#4  0x00007f0066105cd0 in pa_mainloop_run (m=0x505e810, retval=0x0) at pulse/mainloop.c:979
#5  0x00007f0066114633 in thread (userdata=0x505e670) at pulse/thread-mainloop.c:94
#6  0x00007f00650ee217 in internal_thread_func (userdata=0x505ccf0) at pulsecore/thread-posix.c:83
#7  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#8  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 5 (Thread 0x7f0047522710 (LWP 28689)):
#0  pthread_cond_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:162
#1  0x00007f00549cb323 in fifo_peek_int (fifo=0x50f17f0, blocking=1) at audio_out.c:348
#2  0x00007f00549ccd3a in fifo_peek (this_gen=<value optimized out>) at audio_out.c:388
#3  ao_loop (this_gen=<value optimized out>) at audio_out.c:1015
#4  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#5  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 4 (Thread 0x7f0040bd7710 (LWP 28731)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f006d63121a in thread_sleep (ti=0x7f0040bd6da0) at thread/qthread_unix.cpp:435
#2  0x00007f006d631370 in QThread::msleep (msecs=<value optimized out>) at thread/qthread_unix.cpp:461
#3  0x00007f006facdecd in net::DownloadThread::update (this=0x2359460) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/downloadthread.cpp:91
#4  0x00007f006face7c9 in net::NetworkThread::run (this=0x2359460) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/networkthread.cpp:48
#5  0x00007f006d631bc7 in QThreadPrivate::start (arg=0x2359460) at thread/qthread_unix.cpp:285
#6  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#7  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 3 (Thread 0x7f003bfff710 (LWP 28732)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f006d63121a in thread_sleep (ti=0x7f003bffeda0) at thread/qthread_unix.cpp:435
#2  0x00007f006d631370 in QThread::msleep (msecs=<value optimized out>) at thread/qthread_unix.cpp:461
#3  0x00007f006faccdb5 in net::UploadThread::update (this=0x2359ad0) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/uploadthread.cpp:89
#4  0x00007f006face7c9 in net::NetworkThread::run (this=0x2359ad0) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/networkthread.cpp:48
#5  0x00007f006d631bc7 in QThreadPrivate::start (arg=0x2359ad0) at thread/qthread_unix.cpp:285
#6  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#7  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 2 (Thread 0x7f003b7fe710 (LWP 28733)):
#0  pthread_cond_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:162
#1  0x00007f006d6329d3 in wait (this=<value optimized out>, mutex=0x7f003c005410, time=18446744073709551615) at thread/qwaitcondition_unix.cpp:88
#2  QWaitCondition::wait (this=<value optimized out>, mutex=0x7f003c005410, time=18446744073709551615) at thread/qwaitcondition_unix.cpp:160
#3  0x00007f006fad23b2 in net::ReverseResolverThread::run (this=0x7f003c005400) at /var/tmp/portage/net-libs/libktorrent-9999/work/libktorrent-9999/src/net/reverseresolver.cpp:123
#4  0x00007f006d631bc7 in QThreadPrivate::start (arg=0x7f003c005400) at thread/qthread_unix.cpp:285
#5  0x00007f006d39dc3a in start_thread (arg=<value optimized out>) at pthread_create.c:301
#6  0x00007f006bbd2a9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 1 (Thread 0x7f007000c760 (LWP 28681)):
#0  pthread_cond_timedwait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:212
#1  0x00007f006d63121a in thread_sleep (ti=0x7fffe51e4570) at thread/qthread_unix.cpp:435
#2  0x00007f006d631370 in QThread::msleep (msecs=<value optimized out>) at thread/qthread_unix.cpp:461
#3  0x00007f0054c35e0a in Phonon::Xine::Backend::~Backend (this=0x505b900, __in_chrg=<value optimized out>) at /var/tmp/portage/media-sound/phonon-4.4.3/work/phonon-4.4.3/xine/backend.cpp:111
#4  0x00007f006a434fa7 in Phonon::FactoryPrivate::~FactoryPrivate (this=0x7f0058341390, __in_chrg=<value optimized out>) at /var/tmp/portage/media-sound/phonon-4.4.3/work/phonon-4.4.3/phonon/factory.cpp:221
#5  0x00007f006bb36045 in __run_exit_handlers (status=1, listp=0x7f006be614a8, run_list_atexit=true) at exit.c:78
#6  0x00007f006bb36095 in exit (status=-451001100) at exit.c:100
#7  0x00007f006c861548 in qt_xio_errhandler () at kernel/qapplication_x11.cpp:773
#8  0x00007f006e731d40 in KApplication::xioErrhandler (this=0x7fffe51e4980, dpy=0x23ab630) at /var/tmp/portage/kde-base/kdelibs-4.5.4/work/kdelibs-4.5.4/kdeui/kernel/kapplication.cpp:416
#9  0x00007f0069e84c0e in _XIOError (dpy=0x23ab630) at XlibInt.c:1602
#10 0x00007f0069e83add in _XEventsQueued (dpy=0x23ab630, mode=<value optimized out>) at xcb_io.c:307
#11 0x00007f0069e73cef in XEventsQueued (dpy=0x23ab630, mode=2) at Pending.c:43
#12 0x00007f006c89cd5c in x11EventSourceCheck (s=0x2393fd0) at kernel/qguieventdispatcher_glib.cpp:87
#13 0x00007f0067c5f603 in g_main_context_check (context=0x2389720, max_priority=0, fds=<value optimized out>, n_fds=-1) at gmain.c:2658
#14 0x00007f0067c5ff97 in g_main_context_iterate (context=0x2389720, block=<value optimized out>, dispatch=<value optimized out>, self=<value optimized out>) at gmain.c:2777
#15 0x00007f0067c603c2 in g_main_context_iteration (context=0x2389720, may_block=1) at gmain.c:2843
#16 0x00007f006d760e3e in QEventDispatcherGlib::processEvents (this=0x2385d30, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:415
#17 0x00007f006c89cba6 in QGuiEventDispatcherGlib::processEvents (this=0x7fffe51e44f4, flags=<value optimized out>) at kernel/qguieventdispatcher_glib.cpp:204
#18 0x00007f006d730192 in QEventLoop::processEvents (this=<value optimized out>, flags=) at kernel/qeventloop.cpp:149
#19 0x00007f006d73055d in QEventLoop::exec (this=0x7fffe51e48e0, flags=) at kernel/qeventloop.cpp:201
#20 0x00007f006d732dfb in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1009
#21 0x000000000042d352 in main (argc=<value optimized out>, argv=<value optimized out>) at /var/tmp/portage/net-p2p/ktorrent-9999/work/ktorrent-9999/ktorrent/main.cpp:176


Another backtrace. Now KTorrent crashed after several hours. Is it a problem with mediaplayer plugin?
Comment 6 Joris Guisson 2010-12-21 18:36:29 UTC
I haven't seen this XIO error crash since the fix I mentioned above. Could be that I'm lucky. 

My current hypothesis is that it is caused by doing X stuff in the wrong thread.
Comment 7 Alexey Shildyakov 2010-12-28 01:58:09 UTC
Hm... The problem doesn't exist with disabled utp protocol.
Comment 8 Joris Guisson 2011-01-05 20:19:24 UTC
Ran into this XIOError again yesterday

Could you run ktorrent under valgrind until you see it ? You seem to be able to reproduce this easier then me.

valgrind --log-file=vg.log --num-callers=50 /usr/bin/ktorrent --nofork
Comment 9 Alexey Shildyakov 2011-01-10 00:40:25 UTC
Created attachment 55793 [details]
valgrind log

libktorrent: d0deb0260781c69ec7a7eb23f39e0db133bc0757
ktorrent: 087f5be3f1db04868c00a3a8e691f0d0111aeda2

valgrind was crashed too
Comment 10 Joris Guisson 2011-01-10 19:09:48 UTC
commit dddb07872180ae70eb86fcdbdfe4e7270a7b6432
branch master
Author: Joris <joris.guisson@gmail.com>
Date:   Mon Jan 10 19:06:47 2011 +0100

    Move timers out of Connection object and into UTPServer. This fixes a crash due to cleaning up timer in the wrong thread.
    
    BUG: 260712

diff --git a/ChangeLog b/ChangeLog
index f1b82d8..c85fc6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@ Changes in 1.1rc1:
 - Fix bug in UPnP so that it works properly with D-Link DIR 635 routers
 - Fix crash due to manipulating timers in the wrong thread (261903)
 - Fix compiler warning in TimeEstimator (262618)
+- Fix crash due to cleaning up timer in the wrong thread (260712)
 
 Changes in 1.1beta1:
 - Use UTF-8 as default codec in bt::Value::toString
diff --git a/src/download/packet.cpp b/src/download/packet.cpp
index adfe4c0..c8ab706 100644
--- a/src/download/packet.cpp
+++ b/src/download/packet.cpp
@@ -108,7 +108,7 @@ namespace bt
 			if (ReadUint32(data,9) != req.getOffset())
 				return false; 
 			
-			if (ReadUint32(data,13) != req.getLength())
+			if (size - 13 != req.getLength())
 				return false;
 			
 			return true;
diff --git a/src/utp/connection.cpp b/src/utp/connection.cpp
index d6ccd5b..e439326 100644
--- a/src/utp/connection.cpp
+++ b/src/utp/connection.cpp
@@ -44,7 +44,7 @@ namespace utp
 	}
 	
 	Connection::Connection(bt::Uint16 recv_connection_id, Type type, const net::Address& remote, Transmitter* transmitter) 
-		: transmitter(transmitter)
+		: transmitter(transmitter),timer_id(-1)
 	{
 		stats.type = type;
 		stats.remote = remote;
@@ -668,19 +668,14 @@ namespace utp
 		if (QThread::currentThread() != thread())
 			emit doDelayedStartTimer();
 		else
-			timer.start(stats.timeout,this);
+			delayedStartTimer();
 	}
 	
 	void Connection::delayedStartTimer()
 	{
-		timer.start(stats.timeout,this);
+		if (timer_id != -1)
+			transmitter->cancelTimer(timer_id);
+		timer_id = transmitter->scheduleTimer(self.toStrongRef(),stats.timeout);
 	}
-
-	void Connection::timerEvent(QTimerEvent* event)
-	{
-		Q_UNUSED(event);
-		handleTimeout();
-	}
-
 }
 
diff --git a/src/utp/connection.h b/src/utp/connection.h
index 693df92..d6064cf 100644
--- a/src/utp/connection.h
+++ b/src/utp/connection.h
@@ -161,6 +161,9 @@ namespace utp
 		/// Set a weak pointer to self
 		void setWeakPointer(WPtr ptr) {self = ptr;}
 		
+		/// Handle a timeout
+		void handleTimeout();
+		
 	private:
 		void sendSYN();
 		void sendState();
@@ -173,8 +176,6 @@ namespace utp
 		void checkIfClosed();
 		void sendDataPacket(const QByteArray & packet);
 		void sendDataPacket(const QByteArray & packet, bt::Uint16 seq_nr, const TimeValue & now);
-		virtual void timerEvent(QTimerEvent* event);
-		void handleTimeout();
 		void startTimer();
 		void checkState();
 		
@@ -197,8 +198,8 @@ namespace utp
 		bool fin_sent;
 		TimeValue last_packet_sent;
 		DelayWindow* delay_window;
-		QBasicTimer timer;
 		Connection::WPtr self;
+		int timer_id;
 		
 		friend class UTPServer;
 	};
@@ -219,6 +220,12 @@ namespace utp
 		
 		/// Called when the connection is closed
 		virtual void closed(Connection::Ptr conn) = 0;
+		
+		/// Schedule a timer for a connection
+		virtual int scheduleTimer(Connection::Ptr conn,bt::Uint32 timeout) = 0;
+		
+		/// Kill a previously started timer
+		virtual void cancelTimer(int timer_id) = 0;
 	};
 	
 }
diff --git a/src/utp/tests/connectiontest.cpp b/src/utp/tests/connectiontest.cpp
index d44644c..661ae62 100644
--- a/src/utp/tests/connectiontest.cpp
+++ b/src/utp/tests/connectiontest.cpp
@@ -54,6 +54,37 @@ public:
 		Q_UNUSED(conn);
 	}
 	
+	QMap<int,Connection::WPtr> timers;
+	
+    virtual int scheduleTimer(Connection::Ptr conn, Uint32 timeout)
+	{
+		int timer_id = startTimer(timeout);
+		timers.insert(timer_id,conn.toWeakRef());
+		return timer_id;
+	}
+	
+	virtual void cancelTimer(int timer_id)
+	{
+		killTimer(timer_id);
+		timers.remove(timer_id);
+	}
+	
+	virtual void timerEvent(QTimerEvent* ev)
+	{
+		int tid = ev->timerId();
+		killTimer(tid);
+		QMap<int,Connection::WPtr>::iterator i = timers.find(tid);
+		if (i != timers.end())
+		{
+			Connection::Ptr ptr = i.value().toStrongRef();
+			if (ptr)
+				ptr->handleTimeout();
+			timers.erase(i);
+		}
+		
+		ev->accept();
+	}
+	
 	QByteArray buildPacket(bt::Uint32 type,bt::Uint32 recv_conn_id,bt::Uint32 send_conn_id,bt::Uint16 seq_nr,bt::Uint16 ack_nr)
 	{
 		TimeValue tv;
diff --git a/src/utp/utpserver.cpp b/src/utp/utpserver.cpp
index e0abb63..5714894 100644
--- a/src/utp/utpserver.cpp
+++ b/src/utp/utpserver.cpp
@@ -544,5 +544,37 @@ namespace utp
 				i++;
 		}
 	}
+	
+	int UTPServer::scheduleTimer(Connection::Ptr conn, Uint32 timeout)
+	{
+		int timer_id = startTimer(timeout);
+		d->active_timers.insert(timer_id, Connection::WPtr(conn));
+		return timer_id;
+	}
+	
+	void UTPServer::cancelTimer(int timer_id)
+	{
+		killTimer(timer_id);
+		d->active_timers.remove(timer_id);
+	}
+
+
+	void UTPServer::timerEvent(QTimerEvent* ev)
+	{
+		int timer_id = ev->timerId();
+		killTimer(timer_id);
+		
+		QMap<int,Connection::WPtr>::iterator i = d->active_timers.find(timer_id);
+		if (i != d->active_timers.end())
+		{
+			Connection::Ptr conn = i.value().toStrongRef();
+			if (conn)
+				conn->handleTimeout();
+			
+			d->active_timers.erase(i);
+		}
+		
+		ev->accept();
+	}
 
 }
\ No newline at end of file
diff --git a/src/utp/utpserver.h b/src/utp/utpserver.h
index dcf4a33..f90fb07 100644
--- a/src/utp/utpserver.h
+++ b/src/utp/utpserver.h
@@ -82,6 +82,9 @@ namespace utp
 		virtual void stateChanged(Connection::Ptr conn, bool readable, bool writeable);
 		virtual void closed(Connection::Ptr conn);
 		virtual void customEvent(QEvent* ev);
+		virtual void timerEvent(QTimerEvent* ev);
+		virtual int scheduleTimer(Connection::Ptr conn, Uint32 timeout);
+		virtual void cancelTimer(int timer_id);
 		
 	signals:
 		void handlePendingConnectionsDelayed();
diff --git a/src/utp/utpserver_p.h b/src/utp/utpserver_p.h
index 24b863c..ee9ec8d 100644
--- a/src/utp/utpserver_p.h
+++ b/src/utp/utpserver_p.h
@@ -102,6 +102,7 @@ namespace utp
 		QList<net::ServerSocket::Ptr> sockets;
 		bool running;
 		QMap<quint16,Connection::Ptr> connections;
+		QMap<int,Connection::WPtr> active_timers;
 		UTPServerThread* utp_thread;
 		QMutex mutex;
 		bt::PtrMap<net::Poll*,PollPipePair> poll_pipes;
Comment 11 Joris Guisson 2011-01-10 19:09:48 UTC
commit 9a5d70fed69866624b7bba87df50947679b73561
branch 1.1
Author: Joris <joris.guisson@gmail.com>
Date:   Mon Jan 10 19:06:47 2011 +0100

    Backport to 1.1: Move timers out of Connection object and into UTPServer. This fixes a crash due to cleaning up timer in the wrong thread.
    
    CCBUG: 260712

diff --git a/ChangeLog b/ChangeLog
index 33dde23..cebc1cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@ Changes in 1.1rc1:
 - Fix bug in UPnP so that it works properly with D-Link DIR 635 routers
 - Fix crash due to manipulating timers in the wrong thread (261903)
 - Fix compiler warning in TimeEstimator (262618)
+- Fix crash due to cleaning up timer in the wrong thread (260712)
 
 Changes in 1.1beta1:
 - Use UTF-8 as default codec in bt::Value::toString
diff --git a/src/download/packet.cpp b/src/download/packet.cpp
index adfe4c0..c8ab706 100644
--- a/src/download/packet.cpp
+++ b/src/download/packet.cpp
@@ -108,7 +108,7 @@ namespace bt
 			if (ReadUint32(data,9) != req.getOffset())
 				return false; 
 			
-			if (ReadUint32(data,13) != req.getLength())
+			if (size - 13 != req.getLength())
 				return false;
 			
 			return true;
diff --git a/src/utp/connection.cpp b/src/utp/connection.cpp
index d6ccd5b..e439326 100644
--- a/src/utp/connection.cpp
+++ b/src/utp/connection.cpp
@@ -44,7 +44,7 @@ namespace utp
 	}
 	
 	Connection::Connection(bt::Uint16 recv_connection_id, Type type, const net::Address& remote, Transmitter* transmitter) 
-		: transmitter(transmitter)
+		: transmitter(transmitter),timer_id(-1)
 	{
 		stats.type = type;
 		stats.remote = remote;
@@ -668,19 +668,14 @@ namespace utp
 		if (QThread::currentThread() != thread())
 			emit doDelayedStartTimer();
 		else
-			timer.start(stats.timeout,this);
+			delayedStartTimer();
 	}
 	
 	void Connection::delayedStartTimer()
 	{
-		timer.start(stats.timeout,this);
+		if (timer_id != -1)
+			transmitter->cancelTimer(timer_id);
+		timer_id = transmitter->scheduleTimer(self.toStrongRef(),stats.timeout);
 	}
-
-	void Connection::timerEvent(QTimerEvent* event)
-	{
-		Q_UNUSED(event);
-		handleTimeout();
-	}
-
 }
 
diff --git a/src/utp/connection.h b/src/utp/connection.h
index 693df92..d6064cf 100644
--- a/src/utp/connection.h
+++ b/src/utp/connection.h
@@ -161,6 +161,9 @@ namespace utp
 		/// Set a weak pointer to self
 		void setWeakPointer(WPtr ptr) {self = ptr;}
 		
+		/// Handle a timeout
+		void handleTimeout();
+		
 	private:
 		void sendSYN();
 		void sendState();
@@ -173,8 +176,6 @@ namespace utp
 		void checkIfClosed();
 		void sendDataPacket(const QByteArray & packet);
 		void sendDataPacket(const QByteArray & packet, bt::Uint16 seq_nr, const TimeValue & now);
-		virtual void timerEvent(QTimerEvent* event);
-		void handleTimeout();
 		void startTimer();
 		void checkState();
 		
@@ -197,8 +198,8 @@ namespace utp
 		bool fin_sent;
 		TimeValue last_packet_sent;
 		DelayWindow* delay_window;
-		QBasicTimer timer;
 		Connection::WPtr self;
+		int timer_id;
 		
 		friend class UTPServer;
 	};
@@ -219,6 +220,12 @@ namespace utp
 		
 		/// Called when the connection is closed
 		virtual void closed(Connection::Ptr conn) = 0;
+		
+		/// Schedule a timer for a connection
+		virtual int scheduleTimer(Connection::Ptr conn,bt::Uint32 timeout) = 0;
+		
+		/// Kill a previously started timer
+		virtual void cancelTimer(int timer_id) = 0;
 	};
 	
 }
diff --git a/src/utp/tests/connectiontest.cpp b/src/utp/tests/connectiontest.cpp
index d44644c..661ae62 100644
--- a/src/utp/tests/connectiontest.cpp
+++ b/src/utp/tests/connectiontest.cpp
@@ -54,6 +54,37 @@ public:
 		Q_UNUSED(conn);
 	}
 	
+	QMap<int,Connection::WPtr> timers;
+	
+    virtual int scheduleTimer(Connection::Ptr conn, Uint32 timeout)
+	{
+		int timer_id = startTimer(timeout);
+		timers.insert(timer_id,conn.toWeakRef());
+		return timer_id;
+	}
+	
+	virtual void cancelTimer(int timer_id)
+	{
+		killTimer(timer_id);
+		timers.remove(timer_id);
+	}
+	
+	virtual void timerEvent(QTimerEvent* ev)
+	{
+		int tid = ev->timerId();
+		killTimer(tid);
+		QMap<int,Connection::WPtr>::iterator i = timers.find(tid);
+		if (i != timers.end())
+		{
+			Connection::Ptr ptr = i.value().toStrongRef();
+			if (ptr)
+				ptr->handleTimeout();
+			timers.erase(i);
+		}
+		
+		ev->accept();
+	}
+	
 	QByteArray buildPacket(bt::Uint32 type,bt::Uint32 recv_conn_id,bt::Uint32 send_conn_id,bt::Uint16 seq_nr,bt::Uint16 ack_nr)
 	{
 		TimeValue tv;
diff --git a/src/utp/utpserver.cpp b/src/utp/utpserver.cpp
index e0abb63..5714894 100644
--- a/src/utp/utpserver.cpp
+++ b/src/utp/utpserver.cpp
@@ -544,5 +544,37 @@ namespace utp
 				i++;
 		}
 	}
+	
+	int UTPServer::scheduleTimer(Connection::Ptr conn, Uint32 timeout)
+	{
+		int timer_id = startTimer(timeout);
+		d->active_timers.insert(timer_id, Connection::WPtr(conn));
+		return timer_id;
+	}
+	
+	void UTPServer::cancelTimer(int timer_id)
+	{
+		killTimer(timer_id);
+		d->active_timers.remove(timer_id);
+	}
+
+
+	void UTPServer::timerEvent(QTimerEvent* ev)
+	{
+		int timer_id = ev->timerId();
+		killTimer(timer_id);
+		
+		QMap<int,Connection::WPtr>::iterator i = d->active_timers.find(timer_id);
+		if (i != d->active_timers.end())
+		{
+			Connection::Ptr conn = i.value().toStrongRef();
+			if (conn)
+				conn->handleTimeout();
+			
+			d->active_timers.erase(i);
+		}
+		
+		ev->accept();
+	}
 
 }
\ No newline at end of file
diff --git a/src/utp/utpserver.h b/src/utp/utpserver.h
index dcf4a33..f90fb07 100644
--- a/src/utp/utpserver.h
+++ b/src/utp/utpserver.h
@@ -82,6 +82,9 @@ namespace utp
 		virtual void stateChanged(Connection::Ptr conn, bool readable, bool writeable);
 		virtual void closed(Connection::Ptr conn);
 		virtual void customEvent(QEvent* ev);
+		virtual void timerEvent(QTimerEvent* ev);
+		virtual int scheduleTimer(Connection::Ptr conn, Uint32 timeout);
+		virtual void cancelTimer(int timer_id);
 		
 	signals:
 		void handlePendingConnectionsDelayed();
diff --git a/src/utp/utpserver_p.h b/src/utp/utpserver_p.h
index 24b863c..ee9ec8d 100644
--- a/src/utp/utpserver_p.h
+++ b/src/utp/utpserver_p.h
@@ -102,6 +102,7 @@ namespace utp
 		QList<net::ServerSocket::Ptr> sockets;
 		bool running;
 		QMap<quint16,Connection::Ptr> connections;
+		QMap<int,Connection::WPtr> active_timers;
 		UTPServerThread* utp_thread;
 		QMutex mutex;
 		bt::PtrMap<net::Poll*,PollPipePair> poll_pipes;