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

Issue #4383 - avoid NPE from MultiPart Cleanup #4388

Closed
wants to merge 9 commits into from

Conversation

lachlan-roberts
Copy link
Contributor

@lachlan-roberts lachlan-roberts commented Dec 3, 2019

Always assign _parts when constructed so it is never null.

Signed-off-by: Lachlan Roberts lachlan@webtide.com

Closes #4383

Always assign _parts when constructed so it is never null.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Copy link
Contributor

@janbartel janbartel left a comment

Choose a reason for hiding this comment

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

Looks fine.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
@lachlan-roberts lachlan-roberts added this to In progress in Jetty 9.4.25 via automation Dec 9, 2019
This will stop two threads from parsing at the same time.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Jetty 9.4.25 automation moved this from In progress to Review in progress Dec 10, 2019
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Copy link
Contributor

@janbartel janbartel left a comment

Choose a reason for hiding this comment

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

As per offline discussion, lets remove the synchronization and just ensure that creation and cleaning of parts is sane.

- Removed synchronization for parsing by two threads.

- Introduced an atomic state to decide when it is safe to remove
the parts. The call to deleteParts will now cancel the parsing and
only delete the parts when the parser exits.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
@lachlan-roberts
Copy link
Contributor Author

@janbartel I added an atomic state to decide when it is safe to remove the parts.

When you call deleteParts() we will move to ERROR state which will cause an error in the parser before the next read, the parser will eventually move into COMPLETED state and that is when deleteParts() knows it is safe to delete the parts.

private volatile File _tmpDir;
private volatile boolean _deleteOnExit;
private volatile boolean _writeFilesWithFilenames;
private volatile boolean _parsed;
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need _parsed if you have the state variable.

public boolean isEmpty()
{
if (_parts == null)
if (!_parsed)
Copy link
Contributor

Choose a reason for hiding this comment

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

See previous comment.

@@ -397,6 +407,31 @@ public boolean isEmpty()
*/
public void deleteParts()
{
while (true)
Copy link
Contributor

Choose a reason for hiding this comment

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

Really would prefer not to have these kind of loops.

continue;
break;

case ERROR:
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe both ERROR and COMPLETED are both terminal states?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just moving to ERROR state is not enough, the ERROR state is indicating that the parsing thread should exit, and the move to COMPLETED indicates that it has exited and will not create anymore parts.

@@ -431,15 +466,7 @@ public void deleteParts()
if (!_parsed)
Copy link
Contributor

Choose a reason for hiding this comment

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

See previous comment

@@ -588,6 +617,27 @@ else if (len == -1)
if (parser != null)
parser.parse(BufferUtil.EMPTY_BUFFER, true);
}
finally
{
while (true)
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, would really prefer to avoid loops if possible.

…s called

use synchronized state instead of atomic reference

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
@lachlan-roberts
Copy link
Contributor Author

@janbartel nudge

@joakime joakime removed this from Review in progress in Jetty 9.4.25 Jan 13, 2020
@joakime joakime added this to In progress in Jetty 9.4.26 via automation Jan 13, 2020
@joakime joakime moved this from In progress to Review in progress in Jetty 9.4.26 Jan 13, 2020
@joakime joakime removed this from Review in progress in Jetty 9.4.26 Jan 15, 2020
@joakime joakime added this to In progress in Jetty 9.4.27 via automation Jan 15, 2020
@joakime joakime moved this from In progress to Review in progress in Jetty 9.4.27 Jan 15, 2020
@joakime
Copy link
Contributor

joakime commented Jan 17, 2020

@lachlan-roberts move these changes over to jetty-10.0.x in a new PR.

@joakime joakime closed this Jan 17, 2020
Jetty 9.4.27 automation moved this from Review in progress to Done Jan 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Jetty 9.4.27
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

4 participants