2929import java .util .concurrent .ScheduledExecutorService ;
3030import java .util .concurrent .ScheduledFuture ;
3131import java .util .concurrent .TimeUnit ;
32+ import java .util .concurrent .atomic .AtomicReference ;
3233import java .util .function .Function ;
3334
3435import org .apache .sshd .agent .SshAgentFactory ;
@@ -83,8 +84,8 @@ public abstract class AbstractFactoryManager extends AbstractKexFactoryManager i
8384 protected FileSystemFactory fileSystemFactory ;
8485 protected List <? extends ServiceFactory > serviceFactories ;
8586 protected List <RequestHandler <ConnectionService >> globalRequestHandlers ;
86- protected SessionTimeoutListener sessionTimeoutListener ;
87- protected ScheduledFuture <?> timeoutListenerFuture ;
87+ protected final AtomicReference < SessionTimeoutListener > sessionTimeoutListener = new AtomicReference <>() ;
88+ protected final AtomicReference < ScheduledFuture <?>> timeoutListenerFuture = new AtomicReference <>() ;
8889 protected final Collection <SessionListener > sessionListeners = new CopyOnWriteArraySet <>();
8990 protected final SessionListener sessionListenerProxy ;
9091 protected final Collection <ChannelListener > channelListeners = new CopyOnWriteArraySet <>();
@@ -473,8 +474,9 @@ public void removePortForwardingEventListener(PortForwardingEventListener listen
473474 }
474475
475476 protected void setupSessionTimeout (AbstractSessionFactory <?, ?> sessionFactory ) {
476- sessionTimeoutListener = createSessionTimeoutListener ();
477- addSessionListener (sessionTimeoutListener );
477+ SessionTimeoutListener listener = createSessionTimeoutListener ();
478+ sessionTimeoutListener .set (listener );
479+ addSessionListener (listener );
478480 }
479481
480482 protected void removeSessionTimeout (AbstractSessionFactory <?, ?> sessionFactory ) {
@@ -507,19 +509,16 @@ public void sessionClosed(Session s) {
507509 }
508510
509511 private void ensureTimeoutScheduled () {
510- if (timeoutListenerFuture == null ) {
511- timeoutListenerFuture = getScheduledExecutorService (). scheduleAtFixedRate ( sessionTimeoutListener , 1 , 1 ,
512- TimeUnit .SECONDS );
512+ if (isOpen () && timeoutListenerFuture . get () == null ) {
513+ timeoutListenerFuture . set (
514+ getScheduledExecutorService (). scheduleAtFixedRate ( sessionTimeoutListener . get (), 1 , 1 , TimeUnit .SECONDS ) );
513515 }
514516 }
515517
516518 private void cancelSessionTimeout () {
517- if (timeoutListenerFuture != null ) {
518- try {
519- timeoutListenerFuture .cancel (true );
520- } finally {
521- timeoutListenerFuture = null ;
522- }
519+ ScheduledFuture <?> future = timeoutListenerFuture .getAndSet (null );
520+ if (future != null ) {
521+ future .cancel (true );
523522 }
524523 }
525524
@@ -528,12 +527,9 @@ protected void stopSessionTimeoutListener(AbstractSessionFactory<?, ?> sessionFa
528527
529528 // remove the sessionTimeoutListener completely; should the SSH server/client be restarted, a new one
530529 // will be created.
531- if (sessionTimeoutListener != null ) {
532- try {
533- removeSessionListener (sessionTimeoutListener );
534- } finally {
535- sessionTimeoutListener = null ;
536- }
530+ SessionTimeoutListener listener = sessionTimeoutListener .getAndSet (null );
531+ if (listener != null ) {
532+ removeSessionListener (listener );
537533 }
538534 }
539535
0 commit comments