summaryrefslogtreecommitdiffhomepage
path: root/syncs/syncs.go
AgeCommit message (Collapse)AuthorFilesLines
2025-08-29syncs: add Semaphore.Len (#16981)Joe Tsai1-0/+7
The Len reports the number of acquired tokens for metrics. Updates tailscale/corp#31252 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-08-28syncs: delete WaitGroup and use sync.WaitGroup.Go in Go 1.25Joe Tsai1-16/+0
Our own WaitGroup wrapper type was a prototype implementation for the Go method on the standard sync.WaitGroup type. Now that there is first-class support for Go, we should migrate over to using it and delete syncs.WaitGroup. Updates #cleanup Updates tailscale/tailscale#16330 Change-Id: Ib52b10f9847341ce29b4ca0da927dc9321691235 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-05-30syncs: fix AtomicValue.CompareAndSwap (#16137)Joe Tsai1-2/+8
Fix CompareAndSwap in the edge-case where the underlying sync.AtomicValue is uninitialized (i.e., Store was never called) and the oldV is the zero value, then perform CompareAndSwap with any(nil). Also, document that T must be comparable. This is a pre-existing restriction. Fixes #16135 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-12-18syncs: add MutexValue (#14422)Joe Tsai1-0/+62
MutexValue is simply a value guarded by a mutex. For any type that is not pointer-sized, MutexValue will perform much better than AtomicValue since it will not incur an allocation boxing the value into an interface value (which is how Go's atomic.Value is implemented under-the-hood). Updates #cleanup Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-10-09syncs: allocate map with Map.WithLock (#13755)Joe Tsai1-0/+3
One primary purpose of WithLock is to mutate the underlying map. However, this can lead to a panic if it happens to be nil. Thus, always allocate a map before passing it to f. Updates tailscale/corp#11038 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-10-09syncs: delete Map.Range, update callers to iteratorsBrad Fitzpatrick1-16/+0
Updates #11038 Change-Id: I2819fed896cc4035aba5e4e141b52c12637373b1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-10-09syncs: add iterators to Map (#13739)Joe Tsai1-0/+48
Add Keys, Values, and All to iterate over all keys, values, and entries, respectively. Updates #11038 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-07-11syncs: add Map.WithLock to allow mutations to the underlying map (#8101)Joe Tsai1-1/+12
Some operations cannot be implemented with the prior API: * Iterating over the map and deleting keys * Iterating over the map and replacing items * Calling APIs that expect a native Go map Add a Map.WithLock method that acquires a write-lock on the map and then calls a user-provided closure with the underlying Go map. This allows users to interact with the Map as a regular Go map, but with the gaurantees that it is concurrent safe. Updates tailscale/corp#9115 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-04-30syncs: fix AtomicValue for interface kinds (#11943)Joe Tsai1-6/+13
If AtomicValue[T] is used with a T that is an interface kind, then Store may panic if different concret types are ever stored. Fix this by always wrapping in a concrete type. Technically, this is only needed if T is an interface kind, but there is no harm in doing it also for non-interface kinds. Updates #cleanup Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-03-19syncs: add Swap methodAndrew Dunham1-0/+11
To mimic sync.Map.Swap, sync/atomic.Value.Swap, etc. Updates tailscale/corp#1297 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: If7627da1bce8b552873b21d7e5ebb98904e9a650
2023-10-18syncs: add Map.LoadFunc (#9869)Joe Tsai1-3/+20
The LoadFunc loads a value and calls a user-provided function. The utility of this method is to ensure that the map lock is held while executing user-provided logic. This allows us to solve TOCTOU bugs that would be nearly imposible to the solve without this API. Updates tailscale/corp#14772 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2023-10-06syncs: add Map.LoadOrInit for lazily initialized valuesJames Tucker1-0/+20
I was reviewing some code that was performing this by hand, and wanted to suggest using syncs.Map, however as the code in question was allocating a non-trivial structure this would be necessary to meet the target. Updates #cleanup Signed-off-by: James Tucker <james@tailscale.com>
2023-08-17all: use Go 1.21 slices, maps instead of x/exp/{slices,maps}Brad Fitzpatrick1-2/+1
Updates #8419 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-17syncs: add map.Clear() methodDenton Gentry1-0/+8
Updates https://github.com/tailscale/corp/issues/13979 Signed-off-by: Denton Gentry <dgentry@tailscale.com>
2023-04-27syncs: add Map.Len to get the length of the MapJames Tucker1-0/+7
I need this for a corp change where I have a set as a queue, and make a different decisison if the set is empty. Updates tailscale/corp#10344 Signed-off-by: James Tucker <james@tailscale.com>
2023-04-27syncs: add documentation to Map.RangeJames Tucker1-0/+2
Updates #cleanup Signed-off-by: James Tucker <james@tailscale.com>
2023-03-09syncs: add WaitGroup wrapper (#7481)Joe Tsai1-0/+16
The addition of WaitGroup.Go in the standard library has been repeatedly proposed and rejected. See golang/go#18022, golang/go#23538, and golang/go#39863 In summary, the argument for WaitGroup.Go is that it avoids bugs like: go func() { wg.Add(1) defer wg.Done() ... }() where the increment happens after execution (not before) and also (to a lesser degree) because: wg.Go(func() { ... }) is shorter and more readble. The argument against WaitGroup.Go is that the provided function takes no arguments and so inputs and outputs must closed over by the provided function. The most common race bug for goroutines is that the caller forgot to capture the loop iteration variable, so this pattern may make it easier to be accidentally racy. However, that is changing with golang/go#57969. In my experience the probability of race bugs due to the former still outwighs the latter, but I have no concrete evidence to prove it. The existence of errgroup.Group.Go and frequent utility of the method at least proves that this is a workable pattern and the possibility of accidental races do not appear to manifest as frequently as feared. A reason *not* to use errgroup.Group everywhere is that there are many situations where it doesn't make sense for the goroutine to return an error since the error is handled in a different mechanism (e.g., logged and ignored, formatted and printed to the frontend, etc.). While you can use errgroup.Group by always returning nil, the fact that you *can* return nil makes it easy to accidentally return an error when nothing is checking the return of group.Wait. This is not a hypothetical problem, but something that has bitten us in usages that was only using errgroup.Group without intending to use the error reporting part of it. Thus, add a (yet another) variant of WaitGroup here that is identical to sync.WaitGroup, but with an extra method. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2023-01-27all: update copyright and license headersWill Norris1-3/+2
This updates all source files to use a new standard header for copyright and license declaration. Notably, copyright no longer includes a date, and we now use the standard SPDX-License-Identifier header. This commit was done almost entirely mechanically with perl, and then some minimal manual fixes. Updates #6865 Signed-off-by: Will Norris <will@tailscale.com>
2022-11-10syncs: add Map (#6260)Joe Tsai1-0/+66
Map is a concurrent safe map that is a trivial wrapper over a Go map and a sync.RWMutex. It is optimized for use-cases where the entries change often, which is the opposite use-case of what sync.Map is optimized for. The API is patterned off of sync.Map, but made generic. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-04syncs: add generic AtomicValueMaisem Ali1-0/+43
Signed-off-by: Maisem Ali <maisem@tailscale.com>
2022-08-04syncs, all: move to using Go's new atomic types instead of oursBrad Fitzpatrick1-36/+0
Fixes #5185 Change-Id: I850dd532559af78c3895e2924f8237ccc328449d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-07-20wgengine/{monitor,router}: restore Linux ip rules when systemd deletes themBrad Fitzpatrick1-0/+10
Thanks. Fixes #1591 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-06-23syncs: add AtomicUint32David Crawshaw1-0/+11
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2021-03-23syncs: add SemaphoreBrad Fitzpatrick1-1/+46
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-11-24Fix receiver in order to be consistent: syncs.WaitGroupChanDmytro Tananayskiy1-4/+4
Signed-off-by: Dmytro Tananayskiy <dmitriyminer@gmail.com>
2020-09-09syncs: add AssertLockedJosh Bleecher Snyder1-1/+1
This allows us to check lock invariants. It was proposed upstream and rejected in: https://github.com/golang/go/issues/1366 Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2020-05-29syncs: add AtomicBoolBrad Fitzpatrick1-0/+15
2020-03-12syncs: add new package for extra sync typesBrad Fitzpatrick1-0/+66