1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-21 06:33:11 +00:00

FIX: panic: unaligned 64-bit atomic operation [32 bit machines] #1487 (#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
https://github.com/golang/go/issues/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
This commit is contained in:
RW 2021-08-22 10:28:34 +02:00 committed by GitHub
parent 4b62cfbb61
commit 3e8227d7eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 15 deletions

View File

@ -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)
@ -32,7 +33,7 @@ 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
@ -40,12 +41,12 @@ func (s *Storage) Get(key string) interface{} {
// 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()
}
@ -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) {
@ -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)
}
}

View File

@ -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
@ -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
}
@ -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
}
@ -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 {