1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 func selfConnectedTCPSocket() (pr
, pw
*os
.File
, err os
.Error
) {
13 // See ../syscall/exec.go for description of ForkLock.
14 syscall
.ForkLock
.RLock()
15 sockfd
, e
:= syscall
.Socket(syscall
.AF_INET
, syscall
.SOCK_STREAM
, 0)
17 syscall
.ForkLock
.RUnlock()
18 return nil, nil, os
.Errno(e
)
20 syscall
.CloseOnExec(sockfd
)
21 syscall
.ForkLock
.RUnlock()
23 // Allow reuse of recently-used addresses.
24 syscall
.SetsockoptInt(sockfd
, syscall
.SOL_SOCKET
, syscall
.SO_REUSEADDR
, 1)
27 var la syscall
.Sockaddr
28 if laTCP
, err
= ResolveTCPAddr("127.0.0.1:0"); err
!= nil {
32 if la
, err
= laTCP
.sockaddr(syscall
.AF_INET
); err
!= nil {
35 e
= syscall
.Bind(sockfd
, la
)
39 return nil, nil, os
.Errno(e
)
42 laddr
, _
:= syscall
.Getsockname(sockfd
)
43 e
= syscall
.Connect(sockfd
, laddr
)
48 fd
:= os
.NewFile(sockfd
, "wakeupSocket")
52 func newPollServer() (s
*pollServer
, err os
.Error
) {
54 s
.cr
= make(chan *netFD
, 1)
55 s
.cw
= make(chan *netFD
, 1)
56 // s.pr and s.pw are indistinguishable.
57 if s
.pr
, s
.pw
, err
= selfConnectedTCPSocket(); err
!= nil {
61 if e
= syscall
.SetNonblock(s
.pr
.Fd(), true); e
!= 0 {
63 err
= &os
.PathError
{"setnonblock", s
.pr
.Name(), os
.Errno(e
)}
68 if s
.poll
, err
= newpollster(); err
!= nil {
71 if err
= s
.poll
.AddFD(s
.pr
.Fd(), 'r', true); err
!= nil {
75 s
.pending
= make(map[int]*netFD
)