@@ -64,8 +64,8 @@ public int getMs() {
6464 }
6565
6666 private final ConnectionHandler connectionHandler ;
67- private final EventManager eventManager = new EventManager ( this ) ;
68- private final ExecutorService userThreadPool = Executors . newCachedThreadPool () ;
67+ private final EventManager eventManager ;
68+ private final ExecutorService userThreadPool ;
6969 private final FileTransferHelper fileTransferHelper ;
7070 private final TS3Api api ;
7171 private final TS3ApiAsync asyncApi ;
@@ -93,34 +93,55 @@ public TS3Query() {
9393 */
9494 public TS3Query (TS3Config config ) {
9595 this .config = config ;
96+ this .eventManager = new EventManager (this );
97+ this .userThreadPool = Executors .newCachedThreadPool ();
9698 this .fileTransferHelper = new FileTransferHelper (config .getHost ());
9799 this .connectionHandler = config .getReconnectStrategy ().create (config .getConnectionHandler ());
98100
99101 this .asyncApi = new TS3ApiAsync (this );
100102 this .api = new TS3Api (asyncApi );
101103 }
102104
103- // PUBLIC
105+ /*
106+ * Copy constructor only used for ReconnectQuery
107+ */
108+ private TS3Query (TS3Query query ) {
109+ this .config = query .config ;
110+ this .eventManager = query .eventManager ;
111+ this .userThreadPool = query .userThreadPool ;
112+ this .fileTransferHelper = query .fileTransferHelper ;
113+ this .connectionHandler = null ;
104114
105- public synchronized void connect () {
106- if (userThreadPool .isShutdown ()) {
107- throw new IllegalStateException ("The query has already been shut down" );
108- }
115+ this .asyncApi = new TS3ApiAsync (this );
116+ this .api = new TS3Api (asyncApi );
117+ }
118+
119+ // PUBLIC
109120
110- QueryIO oldIO = io ;
111- if (oldIO != null ) {
112- oldIO .disconnect ();
121+ public void connect () {
122+ synchronized (this ) {
123+ if (userThreadPool .isShutdown ()) {
124+ throw new IllegalStateException ("The query has already been shut down" );
125+ }
113126 }
114127
115- io = new QueryIO (this , config );
116- connected .set (true );
128+ QueryIO newIO = new QueryIO (this , config );
117129
118130 try {
119- connectionHandler .onConnect (this );
131+ connectionHandler .onConnect (new ReconnectQuery ( this , newIO ) );
120132 } catch (Exception e ) {
121133 log .error ("ConnectionHandler threw exception in connect handler" , e );
122134 }
123- io .continueFrom (oldIO );
135+
136+ synchronized (this ) {
137+ QueryIO oldIO = io ;
138+ io = newIO ;
139+ if (oldIO != null ) {
140+ oldIO .disconnect ();
141+ newIO .continueFrom (io );
142+ }
143+ connected .set (true );
144+ }
124145 }
125146
126147 /**
@@ -247,4 +268,25 @@ private synchronized void handleDisconnect() {
247268 }
248269 }
249270 }
271+
272+ private static class ReconnectQuery extends TS3Query {
273+
274+ private final TS3Query parent ;
275+
276+ private ReconnectQuery (TS3Query query , QueryIO io ) {
277+ super (query );
278+ super .io = io ;
279+ this .parent = query ;
280+ }
281+
282+ @ Override
283+ public void connect () {
284+ throw new UnsupportedOperationException ("Can't call connect from onConnect" );
285+ }
286+
287+ @ Override
288+ public void exit () {
289+ parent .exit ();
290+ }
291+ }
250292}
0 commit comments