MCPcopy
hub / github.com/minio/minio-go / doCall

Method doCall

pkg/singleflight/singleflight.go:147–208  ·  view source on GitHub ↗

doCall handles the single call for a key.

(c *call[V], key K, fn func() (V, error))

Source from the content-addressed store, hash-verified

145
146// doCall handles the single call for a key.
147func (g *Group[K, V]) doCall(c *call[V], key K, fn func() (V, error)) {
148 normalReturn := false
149 recovered := false
150
151 // use double-defer to distinguish panic from runtime.Goexit,
152 // more details see https://golang.org/cl/134395
153 defer func() {
154 // the given function invoked runtime.Goexit
155 if !normalReturn && !recovered {
156 c.err = errGoexit
157 }
158
159 g.mu.Lock()
160 defer g.mu.Unlock()
161 c.wg.Done()
162 if g.m[key] == c {
163 delete(g.m, key)
164 }
165
166 if e, ok := c.err.(*panicError); ok {
167 // In order to prevent the waiting channels from being blocked forever,
168 // needs to ensure that this panic cannot be recovered.
169 if len(c.chans) > 0 {
170 go panic(e)
171 select {} // Keep this goroutine around so that it will appear in the crash dump.
172 } else {
173 panic(e)
174 }
175 } else if c.err == errGoexit {
176 // Already in the process of goexit, no need to call again
177 } else {
178 // Normal return
179 for _, ch := range c.chans {
180 ch <- Result[V]{c.val, c.err, c.dups > 0}
181 }
182 }
183 }()
184
185 func() {
186 defer func() {
187 if !normalReturn {
188 // Ideally, we would wait to take a stack trace until we've determined
189 // whether this is a panic or a runtime.Goexit.
190 //
191 // Unfortunately, the only way we can distinguish the two is to see
192 // whether the recover stopped the goroutine from terminating, and by
193 // the time we know that, the part of the stack trace relevant to the
194 // panic has been discarded.
195 if r := recover(); r != nil {
196 c.err = newPanicError(r)
197 }
198 }
199 }()
200
201 c.val, c.err = fn()
202 normalReturn = true
203 }()
204

Callers 2

DoMethod · 0.95
DoChanMethod · 0.95

Calls 1

newPanicErrorFunction · 0.85

Tested by

no test coverage detected