fix 64-bit aligment for 32-bit platforms
sync/atomic must be used with 64-bit aligned fields, and that alignment is difficult to ensure unless the field is the first one in the struct. https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
This commit is contained in:
parent
902bd80989
commit
e226733b26
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
agent: fix a panic on 32-bit platforms caused by misaligned struct fields used with sync/atomic.
|
||||||
|
```
|
|
@ -52,8 +52,11 @@ var defaultMetrics = metrics.Default
|
||||||
// statsHandler is a grpc/stats.StatsHandler which emits connection and
|
// statsHandler is a grpc/stats.StatsHandler which emits connection and
|
||||||
// request metrics to go-metrics.
|
// request metrics to go-metrics.
|
||||||
type statsHandler struct {
|
type statsHandler struct {
|
||||||
|
// activeConns is used with sync/atomic and MUST be 64-bit aligned. To ensure
|
||||||
|
// alignment on 32-bit platforms this field must remain the first field in
|
||||||
|
// the struct. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
activeConns uint64
|
||||||
metrics *metrics.Metrics
|
metrics *metrics.Metrics
|
||||||
activeConns uint64 // must be 8-byte aligned for atomic access
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStatsHandler(m *metrics.Metrics) *statsHandler {
|
func newStatsHandler(m *metrics.Metrics) *statsHandler {
|
||||||
|
@ -103,10 +106,11 @@ func (c *statsHandler) HandleConn(_ context.Context, s stats.ConnStats) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type activeStreamCounter struct {
|
type activeStreamCounter struct {
|
||||||
metrics *metrics.Metrics
|
// count is used with sync/atomic and MUST be 64-bit aligned. To ensure
|
||||||
// count of the number of open streaming RPCs on a server. It is accessed
|
// alignment on 32-bit platforms this field must remain the first field in
|
||||||
// atomically.
|
// the struct. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
count uint64
|
count uint64
|
||||||
|
metrics *metrics.Metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
// GRPCCountingStreamInterceptor is a grpc.ServerStreamInterceptor that emits a
|
// GRPCCountingStreamInterceptor is a grpc.ServerStreamInterceptor that emits a
|
||||||
|
|
|
@ -175,6 +175,11 @@ type manual struct {
|
||||||
// Configurator receives an initial TLS configuration from agent configuration,
|
// Configurator receives an initial TLS configuration from agent configuration,
|
||||||
// and receives updates from config reloads, auto-encrypt, and auto-config.
|
// and receives updates from config reloads, auto-encrypt, and auto-config.
|
||||||
type Configurator struct {
|
type Configurator struct {
|
||||||
|
// version is increased each time the Configurator is updated. Must be accessed
|
||||||
|
// using sync/atomic. Also MUST be the first field in this struct to ensure
|
||||||
|
// 64-bit alignment. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
version uint64
|
||||||
|
|
||||||
// lock synchronizes access to all fields on this struct except for logger and version.
|
// lock synchronizes access to all fields on this struct except for logger and version.
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
base *Config
|
base *Config
|
||||||
|
@ -188,9 +193,6 @@ type Configurator struct {
|
||||||
// logger is not protected by a lock. It must never be changed after
|
// logger is not protected by a lock. It must never be changed after
|
||||||
// Configurator is created.
|
// Configurator is created.
|
||||||
logger hclog.Logger
|
logger hclog.Logger
|
||||||
// version is increased each time the Configurator is updated. Must be accessed
|
|
||||||
// using sync/atomic.
|
|
||||||
version uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfigurator creates a new Configurator and sets the provided
|
// NewConfigurator creates a new Configurator and sets the provided
|
||||||
|
|
Loading…
Reference in New Issue