thread_tools 0.26 → 0.27

Sign up to get free protection for your applications and to get access to all the features.
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