Skip to content

Commit

Permalink
FIX: panic: unaligned 64-bit atomic operation [32 bit machines] #1487 (
Browse files Browse the repository at this point in the history
…#1502)

* 🐛 panic: unaligned 64-bit atomic operation [32 bit machines] #1487
https://pkg.go.dev/sync/atomic#pkg-notes
https://go101.org/article/memory-layout.html
golang/go#36606

* 🐛 panic: unaligned 64-bit atomic operation [32 bit machines] #1487
change from uin64 to uint32 for the timestamp -> max value is 4294967295 -> Sun Feb 07 2106 06:28:15 GMT+0000
  • Loading branch information
ReneWerner87 committed Aug 22, 2021
1 parent 4b62cfb commit 3e8227d
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
19 changes: 10 additions & 9 deletions internal/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import (
type Storage struct {
sync.RWMutex
data map[string]item // data
ts uint64 // timestamp
ts uint32 // timestamp
}

type item struct {
// max value is 4294967295 -> Sun Feb 07 2106 06:28:15 GMT+0000
e uint32 // exp
v interface{} // val
e uint64 // exp
}

func New() *Storage {
store := &Storage{
data: make(map[string]item),
ts: uint64(time.Now().Unix()),
ts: uint32(time.Now().Unix()),
}
go store.gc(10 * time.Millisecond)
go store.updater(1 * time.Second)
Expand All @@ -32,20 +33,20 @@ func (s *Storage) Get(key string) interface{} {
s.RLock()
v, ok := s.data[key]
s.RUnlock()
if !ok || v.e != 0 && v.e <= atomic.LoadUint64(&s.ts) {
if !ok || v.e != 0 && v.e <= atomic.LoadUint32(&s.ts) {
return nil
}
return v.v
}

// Set key with value
func (s *Storage) Set(key string, val interface{}, ttl time.Duration) {
var exp uint64
var exp uint32
if ttl > 0 {
exp = uint64(ttl.Seconds()) + atomic.LoadUint64(&s.ts)
exp = uint32(ttl.Seconds()) + atomic.LoadUint32(&s.ts)
}
s.Lock()
s.data[key] = item{val, exp}
s.data[key] = item{exp, val}
s.Unlock()
}

Expand All @@ -66,7 +67,7 @@ func (s *Storage) Reset() {
func (s *Storage) updater(sleep time.Duration) {
for {
time.Sleep(sleep)
atomic.StoreUint64(&s.ts, uint64(time.Now().Unix()))
atomic.StoreUint32(&s.ts, uint32(time.Now().Unix()))
}
}
func (s *Storage) gc(sleep time.Duration) {
Expand All @@ -76,7 +77,7 @@ func (s *Storage) gc(sleep time.Duration) {
expired = expired[:0]
s.RLock()
for key, v := range s.data {
if v.e != 0 && v.e <= atomic.LoadUint64(&s.ts) {
if v.e != 0 && v.e <= atomic.LoadUint32(&s.ts) {
expired = append(expired, key)
}
}
Expand Down
13 changes: 7 additions & 6 deletions internal/storage/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ type Storage struct {
}

type entry struct {
// max value is 4294967295 -> Sun Feb 07 2106 06:28:15 GMT+0000
expiry uint32
data []byte
expiry int64
}

// New creates a new memory storage
Expand All @@ -41,7 +42,7 @@ func (s *Storage) Get(key string) ([]byte, error) {
s.mux.RLock()
v, ok := s.db[key]
s.mux.RUnlock()
if !ok || v.expiry != 0 && v.expiry <= time.Now().Unix() {
if !ok || v.expiry != 0 && v.expiry <= uint32(time.Now().Unix()) {
return nil, nil
}

Expand All @@ -55,13 +56,13 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
return nil
}

var expire int64
var expire uint32
if exp != 0 {
expire = time.Now().Add(exp).Unix()
expire = uint32(time.Now().Add(exp).Unix())
}

s.mux.Lock()
s.db[key] = entry{val, expire}
s.db[key] = entry{expire, val}
s.mux.Unlock()
return nil
}
Expand Down Expand Up @@ -101,7 +102,7 @@ func (s *Storage) gc() {
case <-s.done:
return
case t := <-ticker.C:
now := t.Unix()
now := uint32(t.Unix())
s.mux.Lock()
for id, v := range s.db {
if v.expiry != 0 && v.expiry < now {
Expand Down

0 comments on commit 3e8227d

Please sign in to comment.