github.com/haraldrudell/parl@v0.4.176/once-do-err.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package parl 7 8 // onceDoErr provides a wrapper function for sync.once.Do 9 // that executes a function returning an error that may panic 10 // - onceDoErr is a tuple value-type 11 // - — if used as local variable, function argument or return value, 12 // no allocation tajkes place 13 // - — taking its address causes allocation 14 type onceDoErr struct { 15 doErrFuncArgument func() (err error) 16 // DoErr return value pointers 17 didOnce *bool 18 isPanic *bool 19 errp *error 20 // pointer to observable parl.Once 21 // - has isDone and result fields 22 *Once 23 } 24 25 // invokeDoErrFuncArgument is behind o.once 26 func (d *onceDoErr) invokeDoErrFuncArgument() { 27 // indicate that the once did execute: last action 28 defer d.isDone.Store(true) 29 var result onceDoErrResult 30 defer d.saveResult(&result) 31 defer RecoverErr(func() DA { return A() }, &result.err, &result.isPanic) 32 33 result.err = d.doErrFuncArgument() 34 } 35 36 // saveResult stores the outcome of a DoErr invocation 37 func (d *onceDoErr) saveResult(result *onceDoErrResult) { 38 39 // store result in parl.Once 40 d.result.Store(result) 41 42 // update DoErr return values 43 *d.didOnce = true 44 *d.isPanic = result.isPanic 45 *d.errp = result.err 46 }