Skip to content

Commit 0f97fbb

Browse files
authored
SingleThreadedEventHandlingStrategy thread should be interrupted on stop() (#192)
- implemented interrupt() when DedicatedThreadExecutor is used - this should fix failing SocketInitiatorTests as observed in https://travis-ci.org/quickfix-j/quickfixj/builds/384335297
1 parent ce22941 commit 0f97fbb

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

quickfixj-core/src/main/java/quickfix/mina/SingleThreadedEventHandlingStrategy.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ private void block() {
8686
synchronized (this) {
8787
if (isStopped) {
8888
if (!eventQueue.isEmpty()) {
89-
final List<SessionMessageEvent> tempList = new ArrayList<>();
89+
final List<SessionMessageEvent> tempList = new ArrayList<>(eventQueue.size());
9090
queueTracker.drainTo(tempList);
9191
for (SessionMessageEvent event : tempList) {
9292
event.processMessage();
@@ -176,7 +176,7 @@ public synchronized void stopHandlingMessages() {
176176

177177
public void stopHandlingMessages(boolean join) {
178178
stopHandlingMessages();
179-
179+
messageProcessingThread.interrupt();
180180
if (join) {
181181
try {
182182
messageProcessingThread.join();
@@ -207,25 +207,31 @@ static final class ThreadAdapter {
207207
private final RunnableWrapper wrapper;
208208

209209
ThreadAdapter(Runnable command, String name, Executor executor) {
210-
wrapper = new RunnableWrapper(command, name);
211-
this.executor = executor != null ? executor : new DedicatedThreadExecutor(name);
210+
wrapper = new RunnableWrapper(command, name);
211+
this.executor = executor != null ? executor : new DedicatedThreadExecutor(name);
212212
}
213213

214214
public void join() throws InterruptedException {
215-
wrapper.join();
215+
wrapper.join();
216216
}
217217

218218
public void setDaemon(boolean b) {
219-
/* No-Op. Already set for DedicatedThreadExecutor. Not relevant for externally supplied Executors. */
219+
/* No-Op. Already set for DedicatedThreadExecutor. Not relevant for externally supplied Executors. */
220220
}
221221

222222
public boolean isAlive() {
223-
return wrapper.isAlive();
223+
return wrapper.isAlive();
224224
}
225225

226226
public void start() {
227-
executor.execute(wrapper);
227+
executor.execute(wrapper);
228228
}
229+
230+
public void interrupt() {
231+
if (executor instanceof DedicatedThreadExecutor) {
232+
((DedicatedThreadExecutor)executor).interrupt();
233+
}
234+
}
229235

230236
/**
231237
* Provides the Thread::join and Thread::isAlive semantics on the nested Runnable.
@@ -263,28 +269,33 @@ public void join() throws InterruptedException {
263269
public boolean isAlive() {
264270
return latch.getCount() > 0;
265271
}
266-
267272
}
268273

269274
/**
270-
* An Executor that uses it's own dedicated Thread.
275+
* An Executor that uses its own dedicated Thread.
271276
* Provides equivalent behavior to the prior non-Executor approach.
272277
*/
273278
static final class DedicatedThreadExecutor implements Executor {
274279

275280
private final String name;
281+
private Thread thread;
276282

277283
DedicatedThreadExecutor(String name) {
278284
this.name = name;
279285
}
280286

281287
@Override
282288
public void execute(Runnable command) {
283-
Thread thread = new Thread(command, name);
289+
thread = new Thread(command, name);
284290
thread.setDaemon(true);
285291
thread.start();
286292
}
287-
293+
294+
public void interrupt() {
295+
if (thread != null) {
296+
thread.interrupt();
297+
}
298+
}
288299
}
289300

290301
}

0 commit comments

Comments
 (0)