GitRoot

craft your forge, build your project, grow your community freely
 1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
 2//
 3// SPDX-License-Identifier: EUPL-1.2
 4
 5package repository
 6
 7import "sync"
 8
 9type repoLocks struct {
10	locks map[string]*repoLock
11	lock  sync.Mutex
12}
13
14type repoLock struct {
15	willWrite sync.Mutex
16	write     sync.RWMutex
17}
18
19func newRepoLocks() *repoLocks {
20	return &repoLocks{
21		locks: make(map[string]*repoLock),
22		lock:  sync.Mutex{},
23	}
24}
25
26func (rl *repoLocks) get(repoName string) *repoLock {
27	rl.lock.Lock()
28	defer rl.lock.Unlock()
29	_, ok := rl.locks[repoName]
30	if !ok {
31		rl.locks[repoName] = &repoLock{
32			willWrite: sync.Mutex{},
33			write:     sync.RWMutex{},
34		}
35	}
36	return rl.locks[repoName]
37}
38
39func (rl *repoLocks) Read(repoName string) func() {
40	l := rl.get(repoName)
41	l.write.RLock()
42	return func() {
43		l.write.RUnlock()
44	}
45}
46
47func (rl *repoLocks) WillWrite(repoName string) *repoLock {
48	l := rl.get(repoName)
49	l.willWrite.Lock()
50	return l
51}
52
53func (l *repoLock) Close() {
54	l.willWrite.Unlock()
55}
56
57func (l *repoLock) Write() func() {
58	l.write.Lock()
59	return func() {
60		l.write.Unlock()
61	}
62}