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

[UNDERTOW-2072] DefaultByteBufferPool.getBuffer() may return null #1333

Merged
merged 2 commits into from
Oct 11, 2023

Conversation

baranowb
Copy link
Contributor

@e-ts
Copy link

e-ts commented Jun 10, 2022

Hi @baranowb, are you sure this change actually removes the race? If I understand Java Memory Model correctly, referenceCountUpdate.compareAndSet(0,1) will act as a publish and getBuffers reading 0 will act as acquire. This only provides ordering between actions before publish and actions after acquire. The subsequent write to buffer after publish would still race with the read of buffer, before acquire.

See for example the section JMM Interpretation: Roach Motel on https://shipilev.net/blog/2014/jmm-pragmatics/, and the subsequent quiz examples.

@@ -256,20 +256,26 @@ private static class DefaultPooledBuffer implements PooledByteBuffer {

@Override
public ByteBuffer getBuffer() {
final ByteBuffer tmp = this.buffer;
if(referenceCount == 0) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe we should throw exception if tmp is null

@baranowb
Copy link
Contributor Author

baranowb commented Jun 15, 2022

Hi @baranowb, are you sure this change actually removes the race? If I understand Java Memory Model correctly, referenceCountUpdate.compareAndSet(0,1) will act as a publish and getBuffers reading 0 will act as acquire. This only provides ordering between actions before publish and actions after acquire. The subsequent write to buffer after publish would still race with the read of buffer, before acquire.

See for example the section JMM Interpretation: Roach Motel on https://shipilev.net/blog/2014/jmm-pragmatics/, and the subsequent quiz examples.

Oh, Im fairly sure it does not, the problem here is that this part of code wasnt synced for reason and Im sort of forced to accept some trade off - try to mitigate the problem as best as it can be done. Though Im not 100% happy with even this PR, I will change it a bit.

@fl4via fl4via added under verification Currently being verified (running tests, reviewing) before posting a review to contributor waiting PR update Awaiting PR update(s) from contributor before merging and removed under verification Currently being verified (running tests, reviewing) before posting a review to contributor labels Jun 22, 2022
@fl4via fl4via added under verification Currently being verified (running tests, reviewing) before posting a review to contributor and removed waiting PR update Awaiting PR update(s) from contributor before merging labels Aug 11, 2022
Copy link
Member

@fl4via fl4via left a comment

Choose a reason for hiding this comment

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

There is just a small change pending, other than that it looks very good @baranowb . I'll add it myself to make it possible adding this commit to the 2.3.0.Beta1 release

leakDetector.closed = true;
}
pool.freeInternal(buffer);
this.buffer = null;
if (tmp != null) {
Copy link
Member

Choose a reason for hiding this comment

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

assert tmp != null
If the referenceCountUpdaters is 1, it means it is not null.

@fl4via fl4via added bug fix Contains bug fix(es) next release This PR will be merged before next release or has already been merged (for payload double check) waiting PR update Awaiting PR update(s) from contributor before merging and removed under verification Currently being verified (running tests, reviewing) before posting a review to contributor labels Sep 17, 2022
@fl4via fl4via added waiting CI check Ready to be merged but waiting for CI check and removed waiting PR update Awaiting PR update(s) from contributor before merging labels Sep 17, 2022
@fl4via fl4via force-pushed the UNDERTOW-2072 branch 5 times, most recently from 374984c to 24bd330 Compare September 17, 2022 10:56
@fl4via fl4via added failed CI Introduced new regession(s) during CI check waiting PR update Awaiting PR update(s) from contributor before merging under verification Currently being verified (running tests, reviewing) before posting a review to contributor and removed waiting CI check Ready to be merged but waiting for CI check labels Sep 17, 2022
@fl4via
Copy link
Member

fl4via commented Sep 17, 2022

@baranowb I need to figure out why my proposed commit brokes the tests. I'll update this PR as soon as I'm done with my investigation.

@fl4via fl4via removed the next release This PR will be merged before next release or has already been merged (for payload double check) label Sep 17, 2022
@fl4via fl4via added waiting CI check Ready to be merged but waiting for CI check and removed waiting PR update Awaiting PR update(s) from contributor before merging under verification Currently being verified (running tests, reviewing) before posting a review to contributor failed CI Introduced new regession(s) during CI check labels Oct 12, 2022
@fl4via
Copy link
Member

fl4via commented Oct 12, 2022

this PR still breaks CI and it will require further investigation

@fl4via fl4via added waiting PR update Awaiting PR update(s) from contributor before merging failed CI Introduced new regession(s) during CI check and removed waiting CI check Ready to be merged but waiting for CI check labels Oct 12, 2022
@fl4via
Copy link
Member

fl4via commented Oct 12, 2022

The test failure is:
Running io.undertow.websockets.extensions.WebSocketExtensionBasicTestCase
[ERROR] Tests run: 3, Failures: 2, Errors: 0, Skipped: 1, Time elapsed: 310.17 s <<< FAILURE! - in io.undertow.websockets.extensions.WebSocketExtensionBasicTestCase
[ERROR] testExtensionsHeaders(io.undertow.websockets.extensions.WebSocketExtensionBasicTestCase) Time elapsed: 10.094 s <<< FAILURE!
I canceled the workflow because it seems this causes the CI to hang (or it was just a bad coincidence...)

@@ -153,7 +154,6 @@ public PooledByteBuffer allocate() {
local.allocationDepth++;
}
}
buffer.clear();
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be deleted. E.g. thread local cached buffers will not be cleared anymore.

Copy link
Member

Choose a reason for hiding this comment

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

Great catch @ropalka !

@@ -139,6 +139,7 @@ public PooledByteBuffer allocate() {
buffer = queue.poll();
if (buffer != null) {
currentQueueLengthUpdater.decrementAndGet(this);
buffer.clear();
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't clear all buffers created / reused in this method, see below comment.

@baranowb baranowb force-pushed the UNDERTOW-2072 branch 3 times, most recently from 01ae7b4 to f10109b Compare January 25, 2023 07:40
@fl4via fl4via added waiting CI check Ready to be merged but waiting for CI check and removed failed CI Introduced new regession(s) during CI check labels Apr 23, 2023
baranowb and others added 2 commits April 23, 2023 07:03
…omicIntegerFieldUpdater.addAndGet method by the original volatile read statement, it is more efficient and there is no gain in concurrency safety when using the former, as far as I could find out when investigating this.

Also, I removed the check for temp being null before invoking freeInternal, because it must be non-null if referenceCount was 1 when we retrieved it.

Signed-off-by: Flavia Rainone <frainone@redhat.com>
@fl4via fl4via removed the waiting PR update Awaiting PR update(s) from contributor before merging label Apr 23, 2023
@fl4via
Copy link
Member

fl4via commented Apr 23, 2023

I need to see if that fixes the PR so it can be merged. However, it seems that github actions is down, the checks are queued forever. Because I'll be away on PTO until May 2nd, I'm passing the ball to you, @ropalka ! If it passes, it is ready to be merged, unless there are other issues that need to be fixed in the PR. In that case, if someone wants to give it a try, feel free to do so. See you all on the way back!

@fl4via fl4via added next release This PR will be merged before next release or has already been merged (for payload double check) and removed waiting CI check Ready to be merged but waiting for CI check labels Oct 11, 2023
@fl4via fl4via merged commit e92f244 into undertow-io:master Oct 11, 2023
25 checks passed
@fl4via fl4via removed the next release This PR will be merged before next release or has already been merged (for payload double check) label Oct 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug fix Contains bug fix(es)
Projects
None yet
5 participants