alaingilbert / mtx

Generic mutex helpers

Home Page:https://pkg.go.dev/github.com/alaingilbert/mtx

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Go Reference

Golang generic mutex helpers

package main

import (
    "fmt"
    "github.com/alaingilbert/mtx"
)

func main() {
    // go run -race main.go
    type Something struct {
        Field1    string
        SharedMap mtx.Map[string, int]
    }

    something := Something{
        Field1:    "this memory is not being shared, no mutex needed on Field1",
        SharedMap: mtx.NewRWMap[string, int](nil),
    }

    for i := 0; i < 100; i++ {
        go something.SharedMap.Insert("a", i)
    }

    fmt.Println(something.SharedMap.Get("a"))
}
package main

import (
    "fmt"
    "github.com/alaingilbert/mtx"
)

func main() {
    type Something struct {
        Field1           string
        SharedInt        mtx.Mtx[int]
        SharedFloat64    mtx.Mtx[float64]
        SharedMap1       mtx.Map[string, int]
        SharedMap2       mtx.Map[string, int]
        SharedSlice1     mtx.Slice[int]
        SharedSlice2     mtx.Slice[int]
        SharedSlicePtr1  *mtx.Slice[int]
        SharedSlicePtr2  *mtx.Slice[int]
    }
    something := Something{
        Field1:           "",
        SharedInt:        mtx.NewMtx(0),                        // uses sync.Mutex
        SharedFloat64:    mtx.NewRWMtx(0.0),                    // uses sync.RWMutex
        SharedMap1:       mtx.NewMap(map[string]int{"a": 1}),   // uses sync.Mutex
        SharedMap2:       mtx.NewRWMap(map[string]int{"b": 2}), // uses sync.RWMutex
        SharedSlice1:     mtx.NewSlice([]int{1, 2, 3}),         // uses sync.Mutex
        SharedSlice2:     mtx.NewRWSlice([]int{4, 5, 6}),       // uses sync.RWMutex
        SharedSlicePtr1:  mtx.NewSlicePtr([]int{7, 8, 9}),      // uses sync.Mutex
        SharedSlicePtr2:  mtx.NewRWSlicePtr([]int{10, 11, 12}), // uses sync.RWMutex
    }
    fmt.Println(something)
}

Goal

It is not unusual in Go to see code like this,
where the user has to not forget to use the mutex, and has to not make a mistake with the unlocking mechanism.

// NOTE: This code block is NOT an example on how to use the library!

type Something struct {
    SharedMapMtx sync.RWMutex
    SharedMap    map[string]int
}

func someFn(s Something) {
    s.SharedMapMtx.Lock()
    defer s.SharedMapMtx.Unlock()
    s.SharedMap["foo"] = 1
}

This library ensure that a field which is protected by a mutex will be used properly without compromising on flexibility.

type Something struct {
    SharedMap    mtx.Map[string, int]
}

// This is the recommended way of setting a key
func someFn(s *Something) {
    s.SharedMap.Insert("foo", 1)
}

// This is also good
func someOtherFn(s *Something) {
    s.SharedMap.With(func(sharedMapPtr *map[string]int) {
        (*sharedMapPtr)["foo"] = 1
    })
}

// But it can be as flexible as needed
func anotherOneFn(s *Something) {
    s.SharedMap.Lock()
    defer s.SharedMap.Unlock()
    sharedMapPtr := s.SharedMap.GetPointer()
    (*sharedMapPtr)["foo"] = 1
}

About

Generic mutex helpers

https://pkg.go.dev/github.com/alaingilbert/mtx

License:MIT License


Languages

Language:Go 100.0%