9

I have multiple Goroutines sharing a net.Conn object. Can they issue a Write calls simultaneously?

My main concern is that of Write calls which are partially done. Say I intend to wrote 100 bytes, but only 30 were sent, so I need to send 70 more. For this I will typically write a loop:

count := 0
for count < len(buf) {
    byteSent, err := conn.Write(buf[count:])
    //check error 

    count += byteSent
}

But I see that Go implements this loop in net.Conn.Write line number 318 and it does so by taking a lock.

However, on Windows implementation there is no such loop except that there is a call to WSASend. I do not know how WSASend behaves and could not get much from the MSDN docs

Hence the questions are:

[edit] Added 4th question

  1. Do I need to acquire a lock everytime I write to socket?
  2. If yes, then the purpose of acquiring the lock in Write implementation is defeated.
  3. In unix implementation, does it mean that I cannot get byteSent < len(buf) unless err != nil? (I mean am I reading the code correct?)
  4. Does the WSASend on Windows implements the equivalent loop in Unix implementation
4
  • The documentation states: "Multiple goroutines may invoke methods on a Conn simultaneously.". If that doesn't hold true for all platforms then it's a bug that needs to be fixed. Commented Jul 25, 2016 at 10:57
  • You right. The only thing stopping me to file the bug is that I do not know whether WSASend implements the loop equivalent to unix impl or not. Hence the question on SO Commented Jul 25, 2016 at 11:02
  • Normally you file a bug when you have proof that it doesn't work correctly. Otherwise you assume the code works as advertised. Commented Jul 25, 2016 at 11:09
  • I just found out that there is no looping required for WSASend here. This answers my questions. I will check some more, else I will answer this myself Commented Jul 25, 2016 at 11:30

2 Answers 2

9

Yes, you can make many calls to a net.Conn's write method in parallel.

Part of net.Conn's contract is that it can be used from multiple Goroutines concurrently. This is explicitly called out in its documentation:

Conn is a generic stream-oriented network connection.

Multiple goroutines may invoke methods on a Conn simultaneously.

Though I can't speak to the Windows implementation in particular, this statement holds true for all platforms. Since there is no loop in the Windows implementation then WSASend calls must make guarantees that the Unix API does not.

Sign up to request clarification or add additional context in comments.

Comments

1
  1. The io.Write says that in case of partial write, err will be != nil

  2. Found here on StackOverflow that WSASend need not have a loop around it.

  3. From #1 & #2, it implies that I need not acquire lock before calling net.Conn.Write.

So my question stands answered.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.