LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build darwin freebsd linux netbsd openbsd | 5 // +build darwin freebsd linux netbsd openbsd |
6 | 6 |
7 package net | 7 package net |
8 | 8 |
9 import ( | 9 import ( |
10 "io" | 10 "io" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 if fd.laddr != nil { | 68 if fd.laddr != nil { |
69 ls = fd.laddr.String() | 69 ls = fd.laddr.String() |
70 } | 70 } |
71 if fd.raddr != nil { | 71 if fd.raddr != nil { |
72 rs = fd.raddr.String() | 72 rs = fd.raddr.String() |
73 } | 73 } |
74 return fd.net + ":" + ls + "->" + rs | 74 return fd.net + ":" + ls + "->" + rs |
75 } | 75 } |
76 | 76 |
77 func (fd *netFD) connect(la, ra syscall.Sockaddr) error { | 77 func (fd *netFD) connect(la, ra syscall.Sockaddr) error { |
| 78 // Do not need to call fd.writeLock here, |
| 79 // because fd is not yet accessible to user, |
| 80 // so no concurrent operations are possible. |
78 if err := fd.pd.PrepareWrite(); err != nil { | 81 if err := fd.pd.PrepareWrite(); err != nil { |
79 return err | 82 return err |
80 } | 83 } |
81 for { | 84 for { |
82 err := syscall.Connect(fd.sysfd, ra) | 85 err := syscall.Connect(fd.sysfd, ra) |
83 if err == nil || err == syscall.EISCONN { | 86 if err == nil || err == syscall.EISCONN { |
84 break | 87 break |
85 } | 88 } |
86 if err != syscall.EINPROGRESS && err != syscall.EALREADY && err
!= syscall.EINTR { | 89 if err != syscall.EINPROGRESS && err != syscall.EALREADY && err
!= syscall.EINTR { |
87 return err | 90 return err |
(...skipping 10 matching lines...) Expand all Loading... |
98 // so this must be executed before closesocket. | 101 // so this must be executed before closesocket. |
99 fd.pd.Close() | 102 fd.pd.Close() |
100 closesocket(fd.sysfd) | 103 closesocket(fd.sysfd) |
101 fd.sysfd = -1 | 104 fd.sysfd = -1 |
102 runtime.SetFinalizer(fd, nil) | 105 runtime.SetFinalizer(fd, nil) |
103 } | 106 } |
104 | 107 |
105 // Add a reference to this fd. | 108 // Add a reference to this fd. |
106 // Returns an error if the fd cannot be used. | 109 // Returns an error if the fd cannot be used. |
107 func (fd *netFD) incref() error { | 110 func (fd *netFD) incref() error { |
108 » if fd == nil || !fd.fdmu.Incref() { | 111 » if !fd.fdmu.Incref() { |
109 return errClosing | 112 return errClosing |
110 } | 113 } |
111 return nil | 114 return nil |
112 } | 115 } |
113 | 116 |
114 // Remove a reference to this FD and close if we've been asked to do so | 117 // Remove a reference to this FD and close if we've been asked to do so |
115 // (and there are no references left). | 118 // (and there are no references left). |
116 func (fd *netFD) decref() { | 119 func (fd *netFD) decref() { |
117 » if fd != nil && fd.fdmu.Decref() { | 120 » if fd.fdmu.Decref() { |
118 fd.destroy() | 121 fd.destroy() |
119 } | 122 } |
120 } | 123 } |
121 | 124 |
122 // Add a reference to this fd and lock for reading. | 125 // Add a reference to this fd and lock for reading. |
123 // Returns an error if the fd cannot be used. | 126 // Returns an error if the fd cannot be used. |
124 func (fd *netFD) readLock() error { | 127 func (fd *netFD) readLock() error { |
125 » if fd == nil || !fd.fdmu.RWLock(true) { | 128 » if !fd.fdmu.RWLock(true) { |
126 return errClosing | 129 return errClosing |
127 } | 130 } |
128 return nil | 131 return nil |
129 } | 132 } |
130 | 133 |
131 // Unlock for reading and remove a reference to this FD. | 134 // Unlock for reading and remove a reference to this FD. |
132 func (fd *netFD) readUnlock() { | 135 func (fd *netFD) readUnlock() { |
133 » if fd != nil && fd.fdmu.RWUnlock(true) { | 136 » if fd.fdmu.RWUnlock(true) { |
134 fd.destroy() | 137 fd.destroy() |
135 } | 138 } |
136 } | 139 } |
137 | 140 |
138 // Add a reference to this fd and lock for writing. | 141 // Add a reference to this fd and lock for writing. |
139 // Returns an error if the fd cannot be used. | 142 // Returns an error if the fd cannot be used. |
140 func (fd *netFD) writeLock() error { | 143 func (fd *netFD) writeLock() error { |
141 » if fd == nil || !fd.fdmu.RWLock(false) { | 144 » if !fd.fdmu.RWLock(false) { |
142 return errClosing | 145 return errClosing |
143 } | 146 } |
144 return nil | 147 return nil |
145 } | 148 } |
146 | 149 |
147 // Unlock for writing and remove a reference to this FD. | 150 // Unlock for writing and remove a reference to this FD. |
148 func (fd *netFD) writeUnlock() { | 151 func (fd *netFD) writeUnlock() { |
149 » if fd != nil && fd.fdmu.RWUnlock(false) { | 152 » if fd.fdmu.RWUnlock(false) { |
150 fd.destroy() | 153 fd.destroy() |
151 } | 154 } |
152 } | 155 } |
153 | 156 |
154 func (fd *netFD) Close() error { | 157 func (fd *netFD) Close() error { |
155 fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict | 158 fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict |
156 if !fd.fdmu.IncrefAndClose() { | 159 if !fd.fdmu.IncrefAndClose() { |
157 fd.pd.Unlock() | 160 fd.pd.Unlock() |
158 return errClosing | 161 return errClosing |
159 } | 162 } |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 if err = syscall.SetNonblock(ns, false); err != nil { | 472 if err = syscall.SetNonblock(ns, false); err != nil { |
470 return nil, &OpError{"setnonblock", fd.net, fd.laddr, err} | 473 return nil, &OpError{"setnonblock", fd.net, fd.laddr, err} |
471 } | 474 } |
472 | 475 |
473 return os.NewFile(uintptr(ns), fd.name()), nil | 476 return os.NewFile(uintptr(ns), fd.name()), nil |
474 } | 477 } |
475 | 478 |
476 func closesocket(s int) error { | 479 func closesocket(s int) error { |
477 return syscall.Close(s) | 480 return syscall.Close(s) |
478 } | 481 } |
LEFT | RIGHT |