split ptr retrieval and incrementation

This commit is contained in:
oliverpool 2017-02-20 16:38:27 +01:00
parent ebd6873cbb
commit 3da4095c08
1 changed files with 17 additions and 16 deletions

View File

@ -31,7 +31,8 @@ func (m *Metrics) incRequestsTotal(method string) {
// incErrorsTotal increases the counter for this error atomically by one. // incErrorsTotal increases the counter for this error atomically by one.
func (m *Metrics) incErrorsTotal(err HTTPError) { func (m *Metrics) incErrorsTotal(err HTTPError) {
m.ErrorsTotal.incError(err) ptr := m.ErrorsTotal.retrievePointerFor(err)
atomic.AddUint64(ptr, 1)
} }
// incBytesReceived increases the number of received bytes atomically be the // incBytesReceived increases the number of received bytes atomically be the
@ -86,25 +87,25 @@ func newErrorsTotalMap() ErrorsTotalMap {
} }
} }
// incErrorsTotal increases the counter for this error atomically by one. // retrievePointerFor returns (after creating it if necessary) the pointer to
func (e *ErrorsTotalMap) incError(err HTTPError) { // the counter for the error.
// The goal is to have a valid ptr to the counter for this err func (e *ErrorsTotalMap) retrievePointerFor(err HTTPError) *uint64 {
e.RLock() e.RLock()
ptr, ok := e.m[err] ptr, ok := e.m[err]
e.RUnlock() e.RUnlock()
if !ok { if ok {
// The ptr does not seem to exist for this err return ptr
// Hence we create it (using a write lock)
e.Lock()
// We ensure that the ptr wasn't created in the meantime
if ptr, ok = e.m[err]; !ok {
ptr = new(uint64)
e.m[err] = ptr
}
e.Unlock()
} }
// We can then increase the counter
atomic.AddUint64(ptr, 1) // For pointer creation, a WriteLock is required
e.Lock()
// We ensure that the ptr wasn't created in the meantime
if ptr, ok = e.m[err]; !ok {
ptr = new(uint64)
e.m[err] = ptr
}
e.Unlock()
return ptr
} }
// Load retrieves the map of the counter pointers atomically // Load retrieves the map of the counter pointers atomically