* Regenerate code to update copyright end year to 2023
* Test behaviour of default values initialized in different ways
This adds repro tests for #126 and #129
* Fix Swap and CompareAndSwap for Value wrappers
Fixes#126, #129
All atomic types can be used without initialization, e.g., `var v
<AtomicType>`. This works fine for integer types as the initialized
value of 0 matches the default value for the user-facing type. However,
for Value wrappers, they are initialized to `nil`, which is a value that
can't be set (triggers a panic) so the default value for the user-facing
type is forced to be stored as a different value. This leads to multiple
possible values representing the default user-facing type.
E.g., an `atomic.String` with value `""` may be represented by the
underlying atomic as either `nil`, or `""`. This causes issues when we
don't handle the `nil` value correctly, causing to panics in `Swap` and
incorrectly not swapping values in `CompareAndSwap`.
This change fixes the above issues by:
* Requiring `pack` and `unpack` function in gen-atomicwrapper as the
only place we weren't supplying them was for `String`, and the
branching adds unnecessary complexity, especially with added `nil`
handling.
* Extending `CompareAndSwap` for `Value` wrappers to try an additional
`CompareAndSwap(nil, <new>)` only if the original `CompareAndSwap`
fails and the old value is the zero value.
Adds CompareAndSwap and Swap methods to String, Error, and Value,
implemented by making use of Value.CompareAndSwap and Value.Swap
added in Go 1.17.
Following that, add CompareAndSwap to all other types with "CAS" methods
and deprecate CAS in favor of CompareAndSwap, since that's the convention
the standard library chose for these in Go 1.19.
This change is a renaming with no functional changes.
It includes the following renames:
* `val` for arguments that replace the atomic value (e.g., `Store`).
* `delta` for arguments that offset the atomic value (e.g., `Add`).
* `old`, `new` for arguments to `CAS`.
* `old` named return from `Swap`.
* `swapped` for named return from `CAS`.
This also matches the names used in the stdlib atomic interface:
https://golang.org/pkg/sync/atomic/
The generators gen-atomicint and gen-atomicwrapper hard-coded the year
into the licenses of the generated files.
Update to generate year ranges for the licenses, starting at 2020, going
to whatever today's year is.
The embedded `nocmp` field and other similar fields are unused in tests
and the rest of our code.
We can get the effect of `nocmp` without embedding the fields by using
`_ nocmp` as a field.
valuewrapper can be used only to generate atomic wrapper types for
types which are stored as atomic.Value. This isn't necessary because the
same logic can be applied to atomic wrappers built on other types like
Duration and Bool.
Generalize valuewrapper into atomicwrapper with support for optional
pack/unpack functions which handle conversion to/from `interface{}`.
This lets Error hook in and install the `storedError` struct (now called
`packedError`) to avoid panics from nil storage or value type change.
Generated files should contain the following comment in the first few
lines for them to be considered generated by GitHub.
Code generated by <executable>
The additional `@generated` tag does the same for Phabricator.
Rather than hand-writing wrappers around atomic.Value, generate them
automatically from the same template. The generator is at
internal/gen-valuewrapper. The generator correctly handles generating
wrapper structs for nillable types.
Since String holds textual information, instead of implementing
json.Marshaler and json.Unmarshaler, we should implement
encoding.TextMarshaler and encoding.TextUnmarshaler on String.
This makes it encodable and decodable using a variety of formats
including JSON, XML, YAML, and TOML.
Support serializing and deserializing atomic objects to/from JSON using
the JSON representation of the underlying types. Without this,
marshaling returns `{}`.
Per discussion in #68, `atomic.Value` does not yet implement support
because there's an open question as to whether it should implement it
even if the underlying type doesn't support JSON marshaling/
unmarshaling.
Resolves#49
This optimization causes data races since we're changing the value field
without using atomics. E.g., a caller who has multiple goroutines
calling `Set("1")` and `Set("")` will race on the access to `s.v` since
one goroutine is trying to read it while the other sets it, neither
using atomic operations.
This reverts commit 16b44f14f0.
Unexported field name means the methods on different types look
more similar (e.g., &i.v instead of &i.int32 or &i.uint32).
For String, this is important since we don't want users to be
able to access the underlying atomic.Value