-
Notifications
You must be signed in to change notification settings - Fork 124
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
bugfix:save file.Fd() to avoid block again #15
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: detailyang <detailyang@gmail.com>
See the code as below: 1. setNonblock(file.Fd()) 2. file.Fd() The second file.Fd() above will set the fd to block again. Signed-off-by: detailyang <detailyang@gmail.com>
Signed-off-by: detailyang <detailyang@gmail.com>
Signed-off-by: detailyang <detailyang@gmail.com>
Would you have a look at this? Many thanks:) |
netpoll/handle.go
Outdated
return &Desc{file: os.NewFile(fd, ""), event: ev, fd: int(fd)} | ||
} | ||
|
||
// NewDescFile creates descriptor from os.File |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! Could you please follow this rules for comments? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
func (h *Desc) fd() int { | ||
return int(h.file.Fd()) | ||
// Fd returns the underlying file descriptor | ||
func (h *Desc) Fd() int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this now must be exported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since I need the underlying fd in my scene so I have to export the fd:(.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my scene, I need the fd and join the fd to another epoll fd which is super strange but it works. I use easygo to solve golang/go#15735
} | ||
|
||
// NewDescFile creates descriptor from os.File | ||
func NewDescFile(file *os.File, ev Event) *Desc { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really necessary to provide additional Desc
constructor here? Why just don't setup fd
field of the struct right in place where it is created and remove whole Fd()
getter method?
Might be useful to take a look at the syscall.RawConn (https://golang.org/pkg/syscall/#RawConn). Since go 1.9 it may allow to avoid FD duplication at all. |
Signed-off-by: detailyang <detailyang@gmail.com>
@gobwas sorry, I'm busy:) can you look at this. @ligser RawConn says the following:
The fd is invalid after f returns although we know the fd should never be changed? |
@detailyang Yes, I think about that notice too, but in the stdlib code it does not looks like the FD changed anywhere. So I think this notice about the FD state not the FD value. But anyway if you create a new method like: func (h *Desc) Control(f func(fd uintptr) error) (err error) {
// Here we rely that func will be executed in the same goroutine and we can
// receive new err value at the end (err captured to the func).
cntErr := h.rawConn.Control(func(fd uintptr) {
err = f(fd)
})
runtime.KeepAlive(h)
if cntErr != nil {
return cntErr
}
return err
} and store a |
Signed-off-by: detailyang <detailyang@gmail.com>
But that approach does not widely tested. I use it in my own implementation and do not know about caveats. Maybe repo owners see something that I missed about that approach. |
@ligser many thanks. I do not understand the way you use I check the code in https://github.com/golang/go/blob/master/src/internal/poll/fd_unix.go#L512 which I think it says the fd must be associated with the opened file but after the callback return the fd maybe is associated with the closed file or another file which the new fd is the value.. |
@detailyang https://groups.google.com/forum/#!topic/Golang-nuts/LIWj6Gl--es there is some doubts about method arguments and GC. Anyway KeepAlive here just for ensure and just because I see same pattern somewhere in stdlib it may be not required. |
Oh, looks like I seen that in net/rawconn, and looks like the |
See the code below:
The second desc.fd() will set the kernel file description block again.
#11 is likely related.