Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Swap and CompareAndSwap for Value wrappers #130

Merged
merged 3 commits into from Feb 6, 2023

Conversation

prashantv
Copy link
Collaborator

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.

This change is reviewable by commit.

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.
@codecov
Copy link

codecov bot commented Feb 6, 2023

Codecov Report

Merging #130 (ec1ed35) into master (78a3b8e) will not change coverage.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##            master      #130   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           23        23           
  Lines          232       242   +10     
=========================================
+ Hits           232       242   +10     
Impacted Files Coverage Δ
bool.go 100.00% <ø> (ø)
duration.go 100.00% <ø> (ø)
float32.go 100.00% <ø> (ø)
float64.go 100.00% <ø> (ø)
int32.go 100.00% <ø> (ø)
int64.go 100.00% <ø> (ø)
time.go 100.00% <ø> (ø)
uint32.go 100.00% <ø> (ø)
uint64.go 100.00% <ø> (ø)
uintptr.go 100.00% <ø> (ø)
... and 3 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Contributor

@sywhang sywhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for fixing this 🙏

@sywhang sywhang merged commit 1505d28 into uber-go:master Feb 6, 2023
@eNV25 eNV25 mentioned this pull request Feb 6, 2023
4 tasks
@prashantv prashantv deleted the value-wrapper-nil branch February 6, 2023 15:30
@abhinav abhinav mentioned this pull request May 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Atomic String Swap panics if created with empty string
2 participants