thread_tools 0.26 → 0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  A collection of utilities that I often use for threaded code.
8
8
 
9
- == FEATURES/PROBLEMS:
9
+ == FEATURES:
10
10
 
11
11
  * Thread pool
12
12
  * Mongrel patch (thread pool)
@@ -40,6 +40,19 @@ A collection of utilities that I often use for threaded code.
40
40
  server = Mongrel::HttpServer.new(host, port)
41
41
  server.run(10).join
42
42
 
43
+ * An annoying mutex
44
+ require 'thread_tools/debugmutex'
45
+ mtxA = ThreadTools::DebugMutex.new
46
+ mtxB = ThreadTools::DebugMutex.new
47
+ begin
48
+ mtxA.lock
49
+ mtxB.lock
50
+ mtxA.unlock # <= kboom!!!
51
+ rescue
52
+ # Warning, the next line unlocks all mutex acquired by this thread
53
+ ThreadTools::DebugMutex.unlock_all(Thread.current)
54
+ end
55
+
43
56
  == REQUIREMENTS:
44
57
 
45
58
  * Mongrel patch requires mongrel (duh)
@@ -1,15 +1,29 @@
1
- # Author: Daniel Tralamazza
2
- # Date: 29 Sep 2009
3
- #
4
- # Mutex
1
+ # = Synopsis
2
+ # An annoying mutex for debugging
5
3
  #
4
+ # = Description
6
5
  # This class will make things slower, expect more contentions than normal, so
7
- # don't use to protect small blocks or tight loops
8
- #
6
+ # <b>do not</b> use it to protect small blocks or tight loops.
9
7
  # I derived this mutex because I needed to check contention levels, trace
10
- # ownership changes and catch simple lock inversions
8
+ # ownership changes and catch simple lock inversions.
9
+ #
10
+ # Tip:: Use .inspect method to get a small report.
11
11
  #
12
- # Use .inspect method to get a small report
12
+ # = Usage
13
+ # mtxA = ThreadTools::DebugMutex.new
14
+ # mtxB = ThreadTools::DebugMutex.new
15
+ # begin
16
+ # mtxA.lock
17
+ # mtxB.lock
18
+ # mtxA.unlock # <= kboom!!!
19
+ # rescue
20
+ # ThreadTools::DebugMutex.unlock_all(Thread.current)
21
+ # end
22
+ #
23
+ #
24
+ # Author:: Daniel Tralamazza
25
+ # License:: {MIT # License.}[http://www.opensource.org/licenses/mit-license.php]
26
+
13
27
 
14
28
  require 'thread'
15
29
 
@@ -20,8 +34,11 @@ module ThreadTools
20
34
  end
21
35
 
22
36
  class DebugMutex < Mutex
37
+ # number of out of order unlocks
23
38
  attr_reader :out_of_order_locks
39
+ # number of contentions
24
40
  attr_reader :contentions
41
+ # owner thread, nil if unlocked
25
42
  attr_reader :owner
26
43
 
27
44
  def initialize
@@ -85,7 +102,7 @@ module ThreadTools
85
102
  "Owner #{@owner}, Contentions #{@contentions}, Out of order acquisitions #{@out_of_order_locks}"
86
103
  end
87
104
 
88
- # just for fun
105
+ # *thread* thread object
89
106
  def self.unlock_all(thread)
90
107
  thread[:locks].reverse_each do |l|
91
108
  l.unlock
@@ -1,10 +1,21 @@
1
- # Author: Daniel Tralamazza
2
- # Date: 28 Sep 2009
1
+ # = Synopsis
2
+ # Quick and dirty patch to mongrel
3
3
  #
4
+ # = Description
4
5
  # This code patches mongrel to use a thread pool instead of creating a new thread
5
- # for every request. It also traps SIGTERM to close all connections
6
- # Changed method run to accept an extra parameter to set thread pool size
6
+ # for every request. It also traps SIGTERM to close all connections.
7
+ # I also changed the run method to accept an extra parameter to set thread pool size.
7
8
  #
9
+ # = Usage
10
+ # Just add <tt>require 'thread_tools/mongrel_patch'</tt> after the mongrel require
11
+ # require 'mongrel'
12
+ # require 'thread_tools/mongrel_pool'
13
+ #
14
+ # server = Mongrel::HttpServer.new(host, port)
15
+ # server.run(10).join
16
+ #
17
+ # Author:: Daniel Tralamazza
18
+ # License:: {MIT # License.}[http://www.opensource.org/licenses/mit-license.php]
8
19
 
9
20
 
10
21
  require File.expand_path(File.dirname(__FILE__)+'/threadpool')
@@ -1,9 +1,16 @@
1
- # Author: Daniel Tralamazza
2
- # Date:
1
+ # = Synopsis
2
+ # Stupid simple semaphore
3
3
  #
4
- # Semaphore
4
+ # = Description
5
+ # ...
5
6
  #
6
-
7
+ # = Usage
8
+ # sem = ThreadTools::Semaphore.new(1)
9
+ # sem.acquire
10
+ # sem.release
11
+ #
12
+ # Author:: Daniel Tralamazza
13
+ # License:: {MIT # License.}[http://www.opensource.org/licenses/mit-license.php]
7
14
 
8
15
  require 'thread'
9
16
 
@@ -1,17 +1,22 @@
1
- # Author: Daniel Tralamazza
2
- # Date: 25 Sep 2009
1
+ # = Synopsis
2
+ # A bounded thread pool
3
3
  #
4
- # ThreadPool
4
+ # = Description
5
+ # This threadpool pre allocates _N_ threads to serve .spawn calls.
6
+ # By default workers are not killed if an exception is thrown, you can
7
+ # change this behavior by setting +kill_worker_on_exception+.
5
8
  #
6
- # Usage:
9
+ # = Usage
10
+ # tpool = ThreadTools::ThreadPool.new(3)
11
+ # 12.times do |i|</tt>
12
+ # tpool.spawn(i, "hi") {|ti, ts|
13
+ # puts "#{Thread.current} (#{ti}) says #{ts}\n"
14
+ # }
15
+ # end
16
+ # tpool.shutdown
7
17
  #
8
- # tpool = ThreadTools::ThreadPool.new(3)
9
- # 12.times do |i|
10
- # tpool.spawn(i, "hi") {|ti, ts|
11
- # puts "#{Thread.current} (#{ti}) says #{ts}\n"
12
- # }
13
- # end
14
- # tpool.shutdown
18
+ # Author:: Daniel Tralamazza
19
+ # License:: {MIT # License.}[http://www.opensource.org/licenses/mit-license.php]
15
20
 
16
21
 
17
22
  require 'thread'
@@ -28,7 +33,7 @@ module ThreadTools
28
33
  # if set to true a new worker is created if the pool is empty
29
34
  attr_accessor :create_on_spawn
30
35
 
31
- # _size should be at least 1
36
+ # *_size* should be at least 1, *_thr_group* (optional) thread group
32
37
  def initialize(_size, _thr_group = nil)
33
38
  @kill_worker_on_exception = false
34
39
  @size = 0
@@ -91,7 +96,7 @@ module ThreadTools
91
96
  thr
92
97
  end
93
98
 
94
- def shutdown
99
+ def shutdown(_sync = true)
95
100
  thr = nil
96
101
  while !@pool.empty? do
97
102
  @pool_mtx.synchronize do
@@ -100,7 +105,9 @@ module ThreadTools
100
105
  thr[:jobs].clear # clear any pending job
101
106
  thr[:jobs] << nil # queue a nil job
102
107
  thr[:sem].release
103
- thr.join # wait here for the thread to die
108
+ if (_sync)
109
+ thr.join # wait here for the thread to die
110
+ end
104
111
  end
105
112
  end
106
113
  end
@@ -1,3 +1,8 @@
1
+ # Author:: Daniel Tralamazza
2
+ # Date:: 29 Sep 2009
3
+ #
4
+
5
+
1
6
  require 'test/unit'
2
7
  require File.expand_path(File.dirname(__FILE__)+'/../lib/thread_tools/debugmutex')
3
8
 
@@ -18,7 +18,7 @@ class SemaphoreTest < Test::Unit::TestCase
18
18
  sem.release
19
19
  sleep 0.1
20
20
  # release should unblock acquire
21
- assert_equal(ok, true)
21
+ assert(ok)
22
22
  # semaphore count has to be 0
23
23
  assert_equal(sem.count, 0)
24
24
  end
data/thread_tools.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{thread_tools}
3
- s.version = '0.26'
3
+ s.version = '0.27'
4
4
  s.summary = %q{Utilities for threaded apps}
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.email = %q{daniel@tralamazza.com}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thread_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.26"
4
+ version: "0.27"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Tralamazza