Skip to content

Commit 94fd5d8

Browse files
committed
Introduce DaemonThreadFactory
Introduce a ThreadFactory that will set `Thread#setDaemon` according to the _auto_terminate_ value. This makes the need for the `AtExit` functionality uneeded since all threads can now be started daemonized. Furthermore, the gross **hack** of `Configuration#disable_at_exit_handlers!` is especially not needed since this allows the JVM to properly terminate even with minitest. You can test this with: ``` ruby test/concurrent/executor/test_cached_thread_pool.rb ``` fixes #839 fixes #817
1 parent 5ee426c commit 94fd5d8

File tree

5 files changed

+38
-4
lines changed

5 files changed

+38
-4
lines changed

lib/concurrent/executor/cached_thread_pool.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require 'concurrent/utility/engine'
22
require 'concurrent/executor/thread_pool_executor'
3-
43
module Concurrent
54

65
# A thread pool that dynamically grows and shrinks to fit the current workload.
@@ -51,11 +50,11 @@ def initialize(opts = {})
5150
def ns_initialize(opts)
5251
super(opts)
5352
if Concurrent.on_jruby?
53+
self.auto_terminate = opts.fetch(:auto_terminate, true)
5454
@max_queue = 0
55-
@executor = java.util.concurrent.Executors.newCachedThreadPool
55+
@executor = java.util.concurrent.Executors.newCachedThreadPool Concurrent::DaemonThreadFactory.new(self.auto_terminate?)
5656
@executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new)
5757
@executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS)
58-
self.auto_terminate = opts.fetch(:auto_terminate, true)
5958
end
6059
end
6160
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Concurrent
2+
3+
class DaemonThreadFactory
4+
include java.util.concurrent.ThreadFactory
5+
6+
def initialize(daemonize = true)
7+
@daemonize = daemonize
8+
end
9+
10+
def newThread(runnable)
11+
thread = java.util.concurrent.Executors.defaultThreadFactory().newThread(runnable)
12+
thread.setDaemon(@daemonize)
13+
return thread
14+
end
15+
16+
end
17+
18+
end

lib/concurrent/executor/java_thread_pool_executor.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,17 @@ def ns_initialize(opts)
108108
queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue)
109109
end
110110

111+
self.auto_terminate = opts.fetch(:auto_terminate, true)
112+
111113
@executor = java.util.concurrent.ThreadPoolExecutor.new(
112114
min_length,
113115
max_length,
114116
idletime,
115117
java.util.concurrent.TimeUnit::SECONDS,
116118
queue,
119+
Concurrent::DaemonThreadFactory.new(self.auto_terminate?),
117120
FALLBACK_POLICY_CLASSES[@fallback_policy].new)
118121

119-
self.auto_terminate = opts.fetch(:auto_terminate, true)
120122
end
121123
end
122124
end

lib/concurrent/executor/thread_pool_executor.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module Concurrent
55

66
if Concurrent.on_jruby?
77
require 'concurrent/executor/java_thread_pool_executor'
8+
require 'concurrent/executor/java_daemon_thread_factory'
89
end
910

1011
ThreadPoolExecutorImplementation = case
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
$LOAD_PATH.unshift File.expand_path("../../../lib", __dir__)
2+
3+
require 'minitest/autorun'
4+
require 'concurrent'
5+
class CachedThreadPoolTest < Minitest::Test
6+
7+
def test_cached_thread_pool_does_not_impede_shutdown
8+
pool = Concurrent::CachedThreadPool.new
9+
pool.post do
10+
sleep
11+
end
12+
13+
end
14+
end

0 commit comments

Comments
 (0)