package once

import (
	"sync"
	"sync/atomic"
)

type Oncev2 struct {
	m    sync.Mutex
	done uint32
}

func (o *Oncev2) Do(f func() error) error {
	if atomic.LoadUint32(&o.done) == 1 {
		return nil
	}
	return o.slowDo(f)
}

func (o *Oncev2) slowDo(f func() error) error {
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		err := f()
		if err == nil {
			atomic.StoreUint32(&o.done, 1)
		}
		return err
	}
	return nil
}
