thwait 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5a0906e3fbcba8466f400788c2aa1dc49358a6128f2235e26c822e34fc2affd0
4
+ data.tar.gz: 79eaa003a91adf0131cf941b06c04adaa86b5bf4fff937c9ead26e0b1ceeee0e
5
+ SHA512:
6
+ metadata.gz: 8dd2618bd3d76aa346a67cb3ba63d85a83508ee4e3920c08ec69f4d65c38e000174e4e7f8f27607124bc098e4b7d64c8c032062e9f452be5549c3f269a3fcca6
7
+ data.tar.gz: fd36fda399a7f0d3ea6fb594bc087eba1fff4a639088a430fef209a6549027e31d4f92dd140c3002813d15756b82bc4d98afd19a9c49f30bdeec88afddae7a68
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # ThreadsWait
2
+
3
+ This class watches for termination of multiple threads. Basic functionality (wait until specified threads have terminated) can be accessed through the class method ThreadsWait::all_waits. Finer control can be gained using instance methods.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'thwait'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install thwait
20
+
21
+ ## Usage
22
+
23
+ ```
24
+ ThreadsWait.all_waits(thr1, thr2, ...) do |t|
25
+ STDERR.puts "Thread #{t} has terminated."
26
+ end
27
+
28
+ th = ThreadsWait.new(thread1,...)
29
+ th.next_wait # next one to be done
30
+ ```
31
+
32
+ ## Development
33
+
34
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
35
+
36
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
37
+
38
+ ## Contributing
39
+
40
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/thwait.
41
+
42
+ ## License
43
+
44
+ The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require_relative "../lib/thwait"
5
+
6
+ require "irb"
7
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
data/lib/thwait.rb ADDED
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # thwait.rb - thread synchronization class
4
+ # $Release Version: 0.9 $
5
+ # $Revision: 1.3 $
6
+ # by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.)
7
+
8
+ require "e2mmap"
9
+
10
+ #
11
+ # This class watches for termination of multiple threads. Basic functionality
12
+ # (wait until specified threads have terminated) can be accessed through the
13
+ # class method ThreadsWait::all_waits. Finer control can be gained using
14
+ # instance methods.
15
+ #
16
+ # Example:
17
+ #
18
+ # ThreadsWait.all_waits(thr1, thr2, ...) do |t|
19
+ # STDERR.puts "Thread #{t} has terminated."
20
+ # end
21
+ #
22
+ #
23
+ # th = ThreadsWait.new(thread1,...)
24
+ # th.next_wait # next one to be done
25
+ #
26
+ #
27
+ class ThreadsWait
28
+ extend Exception2MessageMapper
29
+ def_exception("ErrNoWaitingThread", "No threads for waiting.")
30
+ def_exception("ErrNoFinishedThread", "No finished threads.")
31
+
32
+ #
33
+ # Waits until all specified threads have terminated. If a block is provided,
34
+ # it is executed for each thread as they terminate.
35
+ #
36
+ def ThreadsWait.all_waits(*threads) # :yield: thread
37
+ tw = ThreadsWait.new(*threads)
38
+ if block_given?
39
+ tw.all_waits do |th|
40
+ yield th
41
+ end
42
+ else
43
+ tw.all_waits
44
+ end
45
+ end
46
+
47
+ #
48
+ # Creates a ThreadsWait object, specifying the threads to wait on.
49
+ # Non-blocking.
50
+ #
51
+ def initialize(*threads)
52
+ @threads = []
53
+ @wait_queue = Thread::Queue.new
54
+ join_nowait(*threads) unless threads.empty?
55
+ end
56
+
57
+ # Returns the array of threads that have not terminated yet.
58
+ attr_reader :threads
59
+
60
+ #
61
+ # Returns +true+ if there are no threads in the pool still running.
62
+ #
63
+ def empty?
64
+ @threads.empty?
65
+ end
66
+
67
+ #
68
+ # Returns +true+ if any thread has terminated and is ready to be collected.
69
+ #
70
+ def finished?
71
+ !@wait_queue.empty?
72
+ end
73
+
74
+ #
75
+ # Waits for specified threads to terminate, and returns when one of
76
+ # the threads terminated.
77
+ #
78
+ def join(*threads)
79
+ join_nowait(*threads)
80
+ next_wait
81
+ end
82
+
83
+ #
84
+ # Specifies the threads that this object will wait for, but does not actually
85
+ # wait.
86
+ #
87
+ def join_nowait(*threads)
88
+ threads.flatten!
89
+ @threads.concat threads
90
+ for th in threads
91
+ Thread.start(th) do |t|
92
+ begin
93
+ t.join
94
+ ensure
95
+ @wait_queue.push t
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ #
102
+ # Waits until any of the specified threads has terminated, and returns the one
103
+ # that does.
104
+ #
105
+ # If there is no thread to wait, raises +ErrNoWaitingThread+. If +nonblock+
106
+ # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.
107
+ #
108
+ def next_wait(nonblock = nil)
109
+ ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
110
+ begin
111
+ @threads.delete(th = @wait_queue.pop(nonblock))
112
+ th
113
+ rescue ThreadError
114
+ ThreadsWait.fail ErrNoFinishedThread
115
+ end
116
+ end
117
+
118
+ #
119
+ # Waits until all of the specified threads are terminated. If a block is
120
+ # supplied for the method, it is executed for each thread termination.
121
+ #
122
+ # Raises exceptions in the same manner as +next_wait+.
123
+ #
124
+ def all_waits
125
+ until @threads.empty?
126
+ th = next_wait
127
+ yield th if block_given?
128
+ end
129
+ end
130
+ end
131
+
132
+ ##
133
+ # An alias for ThreadsWait from thwait.rb
134
+
135
+ ThWait = ThreadsWait
136
+
137
+ # Documentation comments:
138
+ # - Source of documentation is evenly split between Nutshell, existing
139
+ # comments, and my own rephrasing.
140
+ # - I'm not particularly confident that the comments are all exactly correct.
@@ -0,0 +1,3 @@
1
+ class ThreadsWait
2
+ VERSION = "0.1.0"
3
+ end
data/thwait.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ begin
2
+ require_relative "lib/thwait/version"
3
+ rescue LoadError
4
+ # for Ruby core repository
5
+ require_relative "version"
6
+ end
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "thwait"
10
+ spec.version = ThreadsWait::VERSION
11
+ spec.authors = ["Keiju ISHITSUKA"]
12
+ spec.email = ["keiju@ruby-lang.org"]
13
+
14
+ spec.summary = %q{Watches for termination of multiple threads.}
15
+ spec.description = %q{Watches for termination of multiple threads.}
16
+ spec.homepage = "https://github.com/ruby/thwait"
17
+ spec.license = "BSD-2-Clause"
18
+
19
+ spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/thwait.rb", "lib/thwait/version.rb", "thwait.gemspec"]
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.16"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thwait
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Keiju ISHITSUKA
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Watches for termination of multiple threads.
42
+ email:
43
+ - keiju@ruby-lang.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - bin/console
54
+ - bin/setup
55
+ - lib/thwait.rb
56
+ - lib/thwait/version.rb
57
+ - thwait.gemspec
58
+ homepage: https://github.com/ruby/thwait
59
+ licenses:
60
+ - BSD-2-Clause
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.7.6
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Watches for termination of multiple threads.
82
+ test_files: []