Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1133)

Delta Between Two Patch Sets: src/pkg/net/fd_mutex.go

Issue 12418043: code review 12418043: net: add special netFD mutex (Closed)
Left Patch Set: diff -r 97ea81ad7455 https://dvyukov%40google.com@code.google.com/p/go/ Created 11 years, 7 months ago
Right Patch Set: diff -r 5a51d54e34bb https://dvyukov%40google.com@code.google.com/p/go/ Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/net/fd_mutex_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2013 The Go Authors. All rights reserved. 1 // Copyright 2013 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 package net 5 package net
6 6
7 import "sync/atomic" 7 import "sync/atomic"
8 8
9 // fdMutex is a specialized synchronization primitive 9 // fdMutex is a specialized synchronization primitive
10 // that manages lifetime of fd and serializes access 10 // that manages lifetime of an fd and serializes access
11 // to Read and Write methods on netFD. 11 // to Read and Write methods on netFD.
12 type fdMutex struct { 12 type fdMutex struct {
13 state uint64 13 state uint64
14 rsema uint32 14 rsema uint32
15 wsema uint32 15 wsema uint32
16 } 16 }
17 17
18 // fdMutex.state is organized as follows: 18 // fdMutex.state is organized as follows:
19 // 1 bit - whether netFD is closed, if set all subsequent lock operations will f ail. 19 // 1 bit - whether netFD is closed, if set all subsequent lock operations will f ail.
20 // 1 bit - lock for read operations. 20 // 1 bit - lock for read operations.
(...skipping 14 matching lines...) Expand all
35 ) 35 )
36 36
37 // Read operations must do RWLock(true)/RWUnlock(true). 37 // Read operations must do RWLock(true)/RWUnlock(true).
38 // Write operations must do RWLock(false)/RWUnlock(false). 38 // Write operations must do RWLock(false)/RWUnlock(false).
39 // Misc operations must do Incref/Decref. Misc operations include functions like 39 // Misc operations must do Incref/Decref. Misc operations include functions like
40 // setsockopt and setDeadline. They need to use Incref/Decref to ensure that 40 // setsockopt and setDeadline. They need to use Incref/Decref to ensure that
41 // they operate on the correct fd in presence of a concurrent Close call 41 // they operate on the correct fd in presence of a concurrent Close call
42 // (otherwise fd can be closed under their feet). 42 // (otherwise fd can be closed under their feet).
43 // Close operation must do IncrefAndClose/Decref. 43 // Close operation must do IncrefAndClose/Decref.
44 44
45 // All lock operations return false if fd is closed.
46 // All unlock operations return true if fd is closed and it has dropped the last reference.
47
48 // RWLock/Incref return whether fd is open. 45 // RWLock/Incref return whether fd is open.
49 // RWUnlock/Decref return whether fd is closed and there are no remaining refere nces. 46 // RWUnlock/Decref return whether fd is closed and there are no remaining refere nces.
50 47
51 func (mu *fdMutex) Incref() bool { 48 func (mu *fdMutex) Incref() bool {
52 for { 49 for {
53 old := atomic.LoadUint64(&mu.state) 50 old := atomic.LoadUint64(&mu.state)
54 if old&mutexClosed != 0 { 51 if old&mutexClosed != 0 {
55 return false 52 return false
56 } 53 }
57 new := old + mutexRef 54 new := old + mutexRef
(...skipping 11 matching lines...) Expand all
69 old := atomic.LoadUint64(&mu.state) 66 old := atomic.LoadUint64(&mu.state)
70 if old&mutexClosed != 0 { 67 if old&mutexClosed != 0 {
71 return false 68 return false
72 } 69 }
73 // Mark as closed and acquire a reference. 70 // Mark as closed and acquire a reference.
74 new := (old | mutexClosed) + mutexRef 71 new := (old | mutexClosed) + mutexRef
75 if new&mutexRefMask == 0 { 72 if new&mutexRefMask == 0 {
76 panic("net: inconsistent fdMutex") 73 panic("net: inconsistent fdMutex")
77 } 74 }
78 // Remove all read and write waiters. 75 // Remove all read and write waiters.
79 » » new &= ^uint64(mutexRMask | mutexWMask) 76 » » new &^= mutexRMask | mutexWMask
80 if atomic.CompareAndSwapUint64(&mu.state, old, new) { 77 if atomic.CompareAndSwapUint64(&mu.state, old, new) {
81 // Wake all read and write waiters, 78 // Wake all read and write waiters,
82 // they will observe closed flag after wakeup. 79 // they will observe closed flag after wakeup.
83 for old&mutexRMask != 0 { 80 for old&mutexRMask != 0 {
84 old -= mutexRWait 81 old -= mutexRWait
85 runtime_Semrelease(&mu.rsema) 82 runtime_Semrelease(&mu.rsema)
86 } 83 }
87 for old&mutexWMask != 0 { 84 for old&mutexWMask != 0 {
88 old -= mutexWWait 85 old -= mutexWWait
89 runtime_Semrelease(&mu.wsema) 86 runtime_Semrelease(&mu.wsema)
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 runtime_Semrelease(mutexSema) 175 runtime_Semrelease(mutexSema)
179 } 176 }
180 return new&(mutexClosed|mutexRef) == mutexClosed 177 return new&(mutexClosed|mutexRef) == mutexClosed
181 } 178 }
182 } 179 }
183 } 180 }
184 181
185 // Implemented in runtime package. 182 // Implemented in runtime package.
186 func runtime_Semacquire(sema *uint32) 183 func runtime_Semacquire(sema *uint32)
187 func runtime_Semrelease(sema *uint32) 184 func runtime_Semrelease(sema *uint32)
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b