Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why we need mutex lock and unlock when reading conn #12

Open
euclid1990 opened this issue Jul 15, 2019 · 1 comment
Open

Why we need mutex lock and unlock when reading conn #12

euclid1990 opened this issue Jul 15, 2019 · 1 comment

Comments

@euclid1990
Copy link

euclid1990 commented Jul 15, 2019

Hi @gobwas, thank you for creating awesome example !
I have a question about your sample code.

https://github.com/gobwas/ws-examples/blob/master/src/chat/chat.go#L79-L80

func (u *User) readRequest() (*Request, error) {
	u.io.Lock()
	defer u.io.Unlock()
	...
}

Why we need lock when read ? if I put the Receive (contain readRequest) method in for-loop. (I am not using poller.Start(desc, func(ev netpoll.Event))

func (s *Socket) Start(conn net.Conn, name string) {
	// Register incoming user in chat.
	user := s.chat.Register(conn)

	go func() {
		retry := 0
		defer conn.Close()
		defer func() {
			if r := recover(); r != nil {
				log.Println(r)
			}
		}()

		for {
			err := user.Receive()
			if err != nil {
				// When receive failed, we can only disconnect broken
				// connection and stop to receive events about it.
				log.Printf("Read user [%s] - client [%s] text failed: %v\n", user.Name, name, err)
				goto disconnect
			}
			log.Println("User receive successful")
		disconnect:
			if retry = retry + 1; retry > 3 {
				log.Printf("Remove user [%s] - client [%s]\n", user.Name, name)
				s.chat.Remove(user)
				break
			}
			delay := time.Millisecond
			log.Printf("Start receive error: %v; retrying in %s", err, delay)
			time.Sleep(delay)
		}
	}()
}

===> its seem block write method such as

https://github.com/gobwas/ws-examples/blob/master/src/chat/chat.go#L135-L136

func (u *User) writeRaw(p []byte) error {
	u.io.Lock()
	defer u.io.Unlock()
	...
}

because readRequest have made u.io locked, and writeRaw can not aquire this lock.

If I remove u.io.Lock() in readRequest method, Have it any problem?

Thank you !

@euclid1990
Copy link
Author

https://golang.org/pkg/net/#Conn mention

Conn is a generic stream-oriented network connection.

Multiple goroutines may invoke methods on a Conn simultaneously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant