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: expand ReentrantLock scope in MonitorThreadContainer for better … #601

Merged
merged 1 commit into from
Aug 18, 2023

Conversation

aaronchung-bitquill
Copy link
Contributor

@aaronchung-bitquill aaronchung-bitquill commented Aug 14, 2023

…thread safety

Summary

Remove race condition in MonitorThreadContainer between getInstance() and releaseInstance() methods.

Description

In the MonitorThreadContainer, there are possible race conditions between the getInstance() and releaseInstance() methods.

In one of the race conditions is in the getInstance().

...
      } finally {
        LOCK_OBJECT.unlock();
      }
    }
    CLASS_USAGE_COUNT.getAndIncrement();
    return singleton;
  }

Just after the lock object is unlocked, is an opportunity for a race condition with another thread in the releaseInstance() method.

...
    if (CLASS_USAGE_COUNT.decrementAndGet() <= 0) {
      LOCK_OBJECT.lock();
      try {
        if (singleton != null) {
          singleton.releaseResources();
          singleton = null;
          CLASS_USAGE_COUNT.set(0);
...

If the locked block is entered, a race condition may result. getInstance() may return a null singleton which will be followed by a NPE. Or another scenario is that a non-null singleton will be returned, but singleton.releaseResources() is called so the MonitorThreadContainer's threadPool will be shutdown and subsequent usage of the threadPool will result in a RejectedExecutionException.

Additional Reviewers

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@aaronchung-bitquill aaronchung-bitquill force-pushed the fix/monitor-thread-container-locks branch 4 times, most recently from 2111d9e to f5996c3 Compare August 16, 2023 00:06
@aaronchung-bitquill
Copy link
Contributor Author

aaronchung-bitquill commented Aug 16, 2023

Just realized that perhaps using synchronized on both methods may make more sense since the scope of the locks are pretty much the entirety of both getInstance() and releaseInstance().

@aaronchung-bitquill aaronchung-bitquill force-pushed the fix/monitor-thread-container-locks branch 2 times, most recently from 84633c0 to e784af6 Compare August 16, 2023 01:56
@@ -0,0 +1,68 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: can we rename it to ConcurrencyEFMTest ?

Copy link
Contributor Author

@aaronchung-bitquill aaronchung-bitquill Aug 16, 2023

Choose a reason for hiding this comment

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

ConcurrencyEFMTest may be too general. There is also another pre-existing test class MultiThreadedDefaultMonitorServiceTest that also tests concurrency in EFM.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is the nit b/c MultiThreadedMonitorThreadContainerTest is extremely verbose? :D

I was thinking of replacing MultiThreaded with Concurrency so the test class name would be ConcurrencyMonitorTheadContainerTest but that still seems a bit wordy.

What do you think?

CHANGELOG.md Outdated Show resolved Hide resolved
@davecramer
Copy link
Contributor

Instead of using synchronized it would be better to use the re-entrant lock before the first check. synchronized is still a heavier lock.

@aaronchung-bitquill aaronchung-bitquill force-pushed the fix/monitor-thread-container-locks branch 2 times, most recently from f63e6d2 to 05f3fa3 Compare August 16, 2023 23:08
@aaronchung-bitquill aaronchung-bitquill force-pushed the fix/monitor-thread-container-locks branch 4 times, most recently from b3ee732 to 9c5cb33 Compare August 17, 2023 21:35
Comment on lines 33 to 34
@Mock
ExecutorServiceInitializer mockExecutorServiceInitializer;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
@Mock
ExecutorServiceInitializer mockExecutorServiceInitializer;
@Mock ExecutorServiceInitializer mockExecutorServiceInitializer;

Comment on lines 35 to 36
@Mock
ExecutorService mockExecutorService;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
@Mock
ExecutorService mockExecutorService;
@Mock ExecutorService mockExecutorService;

@karenc-bq karenc-bq merged commit 0ebbda7 into aws:main Aug 18, 2023
5 checks passed
@karenc-bq karenc-bq deleted the fix/monitor-thread-container-locks branch August 18, 2023 21:25
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.

5 participants