Skip to content

Conversation

@artembilan
Copy link
Member

Fixes #3980

When not isSharedSession, the initClient() is called for every session we request from the factory and in concurrent calls we end up with not initialized SSH client in some threads.

  • Add synchronized to the initClient() to block other threads while the first one initialize the client

Fixes spring-projects#3980

When not `isSharedSession`, the `initClient()` is called for every session
we request from the factory and in concurrent calls we end up with not initialized SSH client
in some threads.

* Add `synchronized` to the `initClient()` to block other threads while the first one
initialize the client
@kdebski85
Copy link
Contributor

kdebski85 commented Jan 4, 2023

I prepared slightly different approach with Double-checked locking: #3982

My approach might be slightly faster because:

  1. I do not use synchronized
  2. I do not use AtomicBoolean

}

private void initClient() throws IOException {
private synchronized void initClient() throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

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

Synchronization has to be higher up - otherwise if isSharedSession is true, we could orphan a session; see code in getSession.

if (this.isSharedSession && freshSftpClient) {
this.sharedSftpClient = sftpClient;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

If isSharedSession we do this.sharedSessionLock.lock();

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops - right; ignore.


private void initClient() throws IOException {
private synchronized void initClient() throws IOException {
if (this.initialized.compareAndSet(false, true)) {
Copy link
Contributor

@kdebski85 kdebski85 Jan 4, 2023

Choose a reason for hiding this comment

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

this.initialized should not be set at the beginning of the method.
If initialisation fails, the variable will be set to true for uninitialized client.

Also, we can use volatile boolean instead of AtomicBoolean

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah... Makes sense.
OK closing my PR.
Feel free to copy my unit test into your PR then we will review it and merge properly.

@artembilan
Copy link
Member Author

Closed in favor: #3982

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.

Concurrent threads might use uninitialised SFTP client

3 participants