On Monday, April 27, 2020 at 4:22:41 PM UTC-7, Ian Lance Taylor wrote: > > On Sun, Apr 26, 2020 at 4:55 PM Liam <networ...@gmail.com <javascript:>> > wrote: > > > > During an io.Copy() where the Writer is a TCPConn and the Reader is a > 200K disk file, my code may concurrently Write() on the same TCPConn. > > > > I see the result of the Write() inserted into the result of the > io.Copy(). I had the impression that was impossible, but I must be > mistaken, as the sendfile(2) docs read: > > > > Note that a successful call to sendfile() may write fewer bytes than > requested; the caller should be prepared to retry the call if there were > unsent bytes. > > > > Could someone confirm that one must indeed synchronize concurrent use of > tcpConn.Write() and io.Copy(tcpConn, file)? > > Synchronization should not be required. internal/poll.Sendfile > acquires a write lock on dstFD, which is the TCP socket. That should > ensure that the contents of an ordinary Write (which also acquires a > write lock) should not interleave with the sendfile data. > > That said, if the sendfile system call cannot be used for whatever > reason, the net package will fall back on doing ordinary Read and > Write calls. And those Write calls can be interleaved with other > Write calls done by a different goroutine. I think that is probably > permitted, in that io.Copy doesn't promise to not interleave with > simultaneous Write calls on the destination. > > So in the general case you should indeed use your own locking to avoid > interleaving between io.Copy and a concurrent Write. >
Thanks for the details. Where could I add a Println() to reveal why it doesn't call poll.Sendfile()? I expect this system to use sendfile(2). The file is a normal file on a local partition (running on a Digital Ocean Droplet). /etc/fstab has: UUID=[omitted] / ext4 defaults 1 1 $ df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 981M 0 981M 0% /dev tmpfs 996M 0 996M 0% /dev/shm tmpfs 996M 436K 995M 1% /run tmpfs 996M 0 996M 0% /sys/fs/cgroup /dev/vda1 59G 5.7G 51G 11% / tmpfs 200M 0 200M 0% /run/user/0 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/34f33339-058e-446f-8848-910133980498%40googlegroups.com.