YouROK / TorrServer

Torrent stream server
GNU General Public License v3.0
1.34k stars 178 forks source link

[BUG] fatal error: sync: Unlock of unlocked RWMutex #364

Open Packuh opened 4 months ago

Packuh commented 4 months ago

Windows 11 Pro MatriX.129 TorrServer-windows-amd64.exe постоянно крашится, иногда можно пол часа смотреть фильм, а потом TorrServer-windows-amd64.exe начинает крашится каждую минуту

2024/02/25 00:57:43 Close cache for: e52b35cfef5923156c33004654b0e93204edf0bb
2024/02/25 00:57:44 disconect
2024/02/25 00:57:44 connect
2024/02/25 00:57:44 Set listen port to random autoselect (0)
2024/02/25 00:57:44 Client config: {"CacheSize":268435456,"ReaderReadAHead":95,"PreloadCache":61,"UseDisk":true,"TorrentsSavePath":"D:\\torserver\\cache","RemoveCacheOnDrop":false,"ForceEncrypt":false,"RetrackersMode":1,"TorrentDisconnectTimeout":30,"EnableDebug":false,"EnableDLNA":false,"FriendlyName":"","EnableRutorSearch":false,"EnableIPv6":false,"DisableTCP":false,"DisableUTP":false,"DisableUPNP":false,"DisableDHT":false,"DisablePEX":false,"DisableUpload":false,"DownloadRateLimit":0,"UploadRateLimit":0,"ConnectionsLimit":25,"PeersListenPort":0,"SslPort":0,"SslCert":"","SslKey":""}
2024/02/25 00:57:44 PublicIp4: 151.252.94.140
2024/02/25 00:57:45 New torrent e52b35cfef5923156c33004654b0e93204edf0bb
2024/02/25 00:57:45 end set settings
2024/02/25 00:57:52 Create cache for: Wonka.2023.D.BDRip.1.46Gb.MegaPeer e52b35cfef5923156c33004654b0e93204edf0bb
[2024-02-25 00:58:01 +0500 NIL] dht server on 0.0.0.0:20576 (node id 0de41546283096183cb115a74161224af5b9ea4d) completed bootstrap ({47 25}) [github.com/anacrolix/torrent client.go:320]
2024/02/25 00:58:07 error reading Socket PacketConn: read udp4 0.0.0.0:20576: wsarecvfrom: The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.
fatal error: sync: Unlock of unlocked RWMutex

goroutine 371663 [running]:
sync.fatal({0xf1770a?, 0xc002ccb9c8?})
        /usr/local/go/src/runtime/panic.go:1061 +0x18
sync.(*RWMutex).Unlock(0xc0000e6c10)
        /usr/local/go/src/sync/rwmutex.go:209 +0x45
github.com/anacrolix/sync.(*RWMutex).Unlock(0xc0015a00a8?)
        /Users/yourok/go/pkg/mod/github.com/anacrolix/sync@v0.5.1/rwmutex.go:26 +0x2f
github.com/anacrolix/torrent.(*Client).unlock(0x2f262a0?)
        /Users/yourok/go/pkg/mod/github.com/tsynik/torrent@v1.2.13/client.go:1366 +0x19
panic({0xdc11c0?, 0x1058460?})
        /usr/local/go/src/runtime/panic.go:914 +0x21f
github.com/anacrolix/torrent/storage.Piece.ReadAt({{0x10624a0?, 0xc0018461e0?}, {0xc0010b5580?, 0xc001230620?}}, {0xc0014e4000, 0x6fe3cd?, 0x8000}, 0x28000)
        /Users/yourok/go/pkg/mod/github.com/tsynik/torrent@v1.2.13/storage/wrappers.go:88 +0x346
io.(*SectionReader).Read(0xc00239b2c0, {0xc0014e4000?, 0x8000?, 0x20ae5b6c138?})
        /usr/local/go/src/io/io.go:516 +0x4f
io.copyBuffer({0x20ae5b17c90, 0xc001230620}, {0x105aa60, 0xc00239b2c0}, {0x0, 0x0, 0x0})
        /usr/local/go/src/io/io.go:430 +0x1a6
io.Copy(...)
        /usr/local/go/src/io/io.go:389
github.com/anacrolix/torrent.(*Torrent).hashPiece(0xc001601c00, 0x22f)
        /Users/yourok/go/pkg/mod/github.com/tsynik/torrent@v1.2.13/torrent.go:743 +0x229
github.com/anacrolix/torrent.(*Torrent).verifyPiece(0xc001601c00, 0x22f)
        /Users/yourok/go/pkg/mod/github.com/tsynik/torrent@v1.2.13/torrent.go:1651 +0x25a
created by github.com/anacrolix/torrent.(*Torrent).queuePieceCheck in goroutine 356922
        /Users/yourok/go/pkg/mod/github.com/tsynik/torrent@v1.2.13/torrent.go:1687 +0x10a

goroutine 1 [chan receive, 76 minutes]:
server/web.Wait(...)
        /Users/yourok/Projects/GO/TorrServer/server/web/server.go:123
server.WaitServer(...)
        /Users/yourok/Projects/GO/TorrServer/server/server.go:122
main.main()
        /Users/yourok/Projects/GO/TorrServer/server/cmd/main.go:108 +0x5a5
*****
leporel commented 4 months ago

@tsynik https://github.com/tsynik/torrent/blob/f374a737b82f28e0ceaaef43a26a0a979e97d945/torrent.go#L1650

t.hashPiece(piece) выдает ошибку и отрабатывает дефер на уже разлоченый мютекс.

как то не идеоматично внутри гоурутины verifyPiece() использовать мьютекс чтобы другая verifyPiece() горутина могла перехватить управление и тоже потом застопориться на пол пути, не разбирался в смысле кода, но что если один и тот же pieceIndex обрабатывают две горутины и одна взяла и запустила другую, которая успела залочить первую, может тут подойдет использовать мьютекс по индексу pieceIndex ?