github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/patches/stats-race-fix.diff (about)

     1  diff --git a/stats.go b/stats.go
     2  index 59723e6..1c72091 100644
     3  --- a/gopkg.in/mgo.v2/stats.go
     4  +++ b/gopkg.in/mgo.v2/stats.go
     5  @@ -30,43 +30,29 @@ import (
     6   	"sync"
     7   )
     8   
     9  -var stats *Stats
    10  -var statsMutex sync.Mutex
    11  +var stats Stats
    12   
    13   func SetStats(enabled bool) {
    14  -	statsMutex.Lock()
    15  -	if enabled {
    16  -		if stats == nil {
    17  -			stats = &Stats{}
    18  -		}
    19  -	} else {
    20  -		stats = nil
    21  -	}
    22  -	statsMutex.Unlock()
    23  +	stats.reset(enabled)
    24   }
    25   
    26  -func GetStats() (snapshot Stats) {
    27  -	statsMutex.Lock()
    28  -	snapshot = *stats
    29  -	statsMutex.Unlock()
    30  -	return
    31  +func GetStats() Stats {
    32  +	stats.mu.RLock()
    33  +	defer stats.mu.RUnlock()
    34  +	return stats
    35   }
    36   
    37   func ResetStats() {
    38  -	statsMutex.Lock()
    39  +	// If we call ResetStats we assume you want to use stats, so we enable
    40  +	// them.
    41   	debug("Resetting stats")
    42  -	old := stats
    43  -	stats = &Stats{}
    44  -	// These are absolute values:
    45  -	stats.Clusters = old.Clusters
    46  -	stats.SocketsInUse = old.SocketsInUse
    47  -	stats.SocketsAlive = old.SocketsAlive
    48  -	stats.SocketRefs = old.SocketRefs
    49  -	statsMutex.Unlock()
    50  -	return
    51  +	stats.reset(true)
    52   }
    53   
    54   type Stats struct {
    55  +	mu      sync.RWMutex
    56  +	enabled bool
    57  +
    58   	Clusters     int
    59   	MasterConns  int
    60   	SlaveConns   int
    61  @@ -78,70 +64,74 @@ type Stats struct {
    62   	SocketRefs   int
    63   }
    64   
    65  -func (stats *Stats) cluster(delta int) {
    66  -	if stats != nil {
    67  -		statsMutex.Lock()
    68  -		stats.Clusters += delta
    69  -		statsMutex.Unlock()
    70  +func (stats *Stats) reset(enabled bool) {
    71  +	stats.mu.Lock()
    72  +	defer stats.mu.Unlock()
    73  +
    74  +	stats.MasterConns = 0
    75  +	stats.SlaveConns = 0
    76  +	stats.SentOps = 0
    77  +	stats.ReceivedOps = 0
    78  +	stats.ReceivedDocs = 0
    79  +
    80  +	if !enabled {
    81  +		// These are absolute values so we don't reset them unless we are
    82  +		// disabling stats altogether.
    83  +		stats.Clusters = 0
    84  +		stats.SocketsInUse = 0
    85  +		stats.SocketsAlive = 0
    86  +		stats.SocketRefs = 0
    87   	}
    88   }
    89   
    90  +func (stats *Stats) cluster(delta int) {
    91  +	stats.mu.Lock()
    92  +	stats.Clusters += delta
    93  +	stats.mu.Unlock()
    94  +}
    95  +
    96   func (stats *Stats) conn(delta int, master bool) {
    97  -	if stats != nil {
    98  -		statsMutex.Lock()
    99  -		if master {
   100  -			stats.MasterConns += delta
   101  -		} else {
   102  -			stats.SlaveConns += delta
   103  -		}
   104  -		statsMutex.Unlock()
   105  +	stats.mu.Lock()
   106  +	if master {
   107  +		stats.MasterConns += delta
   108  +	} else {
   109  +		stats.SlaveConns += delta
   110   	}
   111  +	stats.mu.Unlock()
   112   }
   113   
   114   func (stats *Stats) sentOps(delta int) {
   115  -	if stats != nil {
   116  -		statsMutex.Lock()
   117  -		stats.SentOps += delta
   118  -		statsMutex.Unlock()
   119  -	}
   120  +	stats.mu.Lock()
   121  +	stats.SentOps += delta
   122  +	stats.mu.Unlock()
   123   }
   124   
   125   func (stats *Stats) receivedOps(delta int) {
   126  -	if stats != nil {
   127  -		statsMutex.Lock()
   128  -		stats.ReceivedOps += delta
   129  -		statsMutex.Unlock()
   130  -	}
   131  +	stats.mu.Lock()
   132  +	stats.ReceivedOps += delta
   133  +	stats.mu.Unlock()
   134   }
   135   
   136   func (stats *Stats) receivedDocs(delta int) {
   137  -	if stats != nil {
   138  -		statsMutex.Lock()
   139  -		stats.ReceivedDocs += delta
   140  -		statsMutex.Unlock()
   141  -	}
   142  +	stats.mu.Lock()
   143  +	stats.ReceivedDocs += delta
   144  +	stats.mu.Unlock()
   145   }
   146   
   147   func (stats *Stats) socketsInUse(delta int) {
   148  -	if stats != nil {
   149  -		statsMutex.Lock()
   150  -		stats.SocketsInUse += delta
   151  -		statsMutex.Unlock()
   152  -	}
   153  +	stats.mu.Lock()
   154  +	stats.SocketsInUse += delta
   155  +	stats.mu.Unlock()
   156   }
   157   
   158   func (stats *Stats) socketsAlive(delta int) {
   159  -	if stats != nil {
   160  -		statsMutex.Lock()
   161  -		stats.SocketsAlive += delta
   162  -		statsMutex.Unlock()
   163  -	}
   164  +	stats.mu.Lock()
   165  +	stats.SocketsAlive += delta
   166  +	stats.mu.Unlock()
   167   }
   168   
   169   func (stats *Stats) socketRefs(delta int) {
   170  -	if stats != nil {
   171  -		statsMutex.Lock()
   172  -		stats.SocketRefs += delta
   173  -		statsMutex.Unlock()
   174  -	}
   175  +	stats.mu.Lock()
   176  +	stats.SocketRefs += delta
   177  +	stats.mu.Unlock()
   178   }