FWIW a compromise is to have

type Locked[T any] struct {
    mu sync.Mutex
    val T
}

func (l *Locked[T]) Do(f func(T) T) {
    l.mu.Lock()
    defer l.mu.Unlock()
    l.val = f(l.val)
}

This forces modifications to be under the protection of a mutex while also
allowing those modifications to do arbitrary things.

The downside is that this might do more locking than is strictly needed.
So, under contention, it might perform significantly worse than "manually"
managing the critical section.

On Mon, May 23, 2022 at 9:11 AM Brian Candler <b.cand...@pobox.com> wrote:

> > It's best to be intentional about it and explicitly acquire and release
> a mutex around the critical sections of your code - because ultimately,
> only your code knows which sections are critical.
>
> That's really essential.  For example, using your library, the following
> code is most definitely *not* race-free:
>
> tmp := v.Load()
> tmp = tmp + 1
> v.Save(tmp)
>
> The mutex has to protect the entire sequence, not the individual load and
> save operations.
>
> On Monday, 23 May 2022 at 07:57:02 UTC+1 axel.wa...@googlemail.com wrote:
>
>> Just to be clear, are you aware of the sync/atomic package?
>> https://pkg.go.dev/sync/atomic
>> There are also some changes in there for Go 1.18, specifically the
>> addition of some types, so that only atomic operations can be done:
>> https://pkg.go.dev/sync/atomic@master
>> I mention this because atomic.Value and atomic.Pointer[T] are essentially
>> what you are suggesting here.
>>
>> On Mon, May 23, 2022 at 8:04 AM Zhaoxun Yan <yan.z...@gmail.com> wrote:
>>
>>> However, as I want to narrow the scope of this type down to generate
>>> integer types (as in the commented code), it encountered two obstacles:
>>>
>>> 1) It is not legal to embed a generic inside a struct, nor can it make
>>> generalized computation  =+1
>>>
>>> 2) Inheritance is not available in golang, so type "Counter" cannot
>>> inherit type "Global" and get its methods automatically. I need to repeat
>>> Save and Load methods to "Counter".
>>>
>>> Am I correct? Or can you improve it?
>>>
>>
>> You are correct that there is no way in Go to write a type which gets all
>> methods from an embedded field using generics. However, that is a good
>> thing. For example, say you could write
>>
>> type Locked[T any] struct {
>>     sync.Mutex
>>     T
>> }
>>
>> And this would get the methods of T and the methods of sync.Mutex. Then a
>> user could do
>>
>> type Counter int64
>> func (c *Counter) Increment() { *c += 1 }
>>
>> func main() {
>>     var c Locked[Counter]
>>     go c.Increment()
>>     go c.Increment()
>> }
>>
>> And get a data race. That is, a method can modify a value in a way that
>> is incompatible with what your wrapper type is trying to do.
>>
>> That's really the crux of both of the obstacles you mention. You can't
>> run arbitrary computations and you can't promote methods, because *not all
>> computation and not all methods can be made concurrency safe this way*.
>>
>> It's best to be intentional about it and explicitly acquire and release a
>> mutex around the critical sections of your code - because ultimately, only
>> your code knows which sections are critical.
>>
>>
>>>
>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/baa74bff-6688-4d39-843b-c99a4fea2d1an%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/baa74bff-6688-4d39-843b-c99a4fea2d1an%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/50d6ab3d-46d0-4357-b5fa-d99b73ef2adan%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/50d6ab3d-46d0-4357-b5fa-d99b73ef2adan%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfG63G2%2BCk5VVmAhT1UMxpVsxy88C4gOPH%3DxV%3DZnXXUjmA%40mail.gmail.com.

Reply via email to