Commit Graph

17 Commits

Author SHA1 Message Date
James Tucker
498f7ec663 syncs: add Map.LoadOrInit for lazily initialized values
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-10-06 17:06:11 -07:00
Brad Fitzpatrick
e8551d6b40 all: use Go 1.21 slices, maps instead of x/exp/{slices,maps}
Updates #8419

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-17 08:42:35 -07:00
Denton Gentry
7e15c78a5a syncs: add map.Clear() method
Updates https://github.com/tailscale/corp/issues/13979

Signed-off-by: Denton Gentry <dgentry@tailscale.com>
2023-08-17 08:02:56 -07:00
James Tucker
b3c3a9f174 syncs: add Map.Len to get the length of the Map
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-27 19:10:28 -07:00
James Tucker
d35ce1add9 syncs: add documentation to Map.Range
Updates #cleanup

Signed-off-by: James Tucker <james@tailscale.com>
2023-04-27 17:07:07 -07:00
Joe Tsai
dad78f31f3
syncs: add WaitGroup wrapper (#7481)
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-03-09 12:04:38 -08:00
Will Norris
71029cea2d all: update copyright and license headers
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>
2023-01-27 15:36:29 -08:00
Joe Tsai
9a05cdd2b5
syncs: add Map (#6260)
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-11-10 10:55:26 -08:00
Maisem Ali
b75f81ec00 syncs: add generic AtomicValue
Signed-off-by: Maisem Ali <maisem@tailscale.com>
2022-08-04 11:52:16 -07:00
Brad Fitzpatrick
4950fe60bd syncs, all: move to using Go's new atomic types instead of ours
Fixes #5185

Change-Id: I850dd532559af78c3895e2924f8237ccc328449d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-08-04 07:47:59 -07:00
Brad Fitzpatrick
e4fecfe31d wgengine/{monitor,router}: restore Linux ip rules when systemd deletes them
Thanks.

Fixes #1591

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-07-20 15:52:22 -07:00
David Crawshaw
676e32ad72 syncs: add AtomicUint32
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2021-06-23 08:51:37 -07:00
Brad Fitzpatrick
77ec80538a syncs: add Semaphore
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-03-23 12:39:28 -07:00
Dmytro Tananayskiy
c431382720 Fix receiver in order to be consistent: syncs.WaitGroupChan
Signed-off-by: Dmytro Tananayskiy <dmitriyminer@gmail.com>
2020-11-24 17:20:34 -08:00
Josh Bleecher Snyder
bf24d54143 syncs: add AssertLocked
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-09-09 12:27:52 -07:00
Brad Fitzpatrick
d3134ad0c8 syncs: add AtomicBool 2020-05-29 12:41:30 -07:00
Brad Fitzpatrick
b4d02a251a syncs: add new package for extra sync types 2020-03-12 11:13:33 -07:00