thwait-0.2.0/0000755000004100000410000000000013752544275013057 5ustar www-datawww-datathwait-0.2.0/README.md0000644000004100000410000000261213752544275014337 0ustar www-datawww-data# ThreadsWait 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. ## Installation Add this line to your application's Gemfile: ```ruby gem 'thwait' ``` And then execute: $ bundle Or install it yourself as: $ gem install thwait ## Usage ``` ThreadsWait.all_waits(thr1, thr2, ...) do |t| STDERR.puts "Thread #{t} has terminated." end th = ThreadsWait.new(thread1,...) th.next_wait # next one to be done ``` ## Development 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. 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). ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/thwait. ## License The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). thwait-0.2.0/bin/0000755000004100000410000000000013752544275013627 5ustar www-datawww-datathwait-0.2.0/bin/console0000755000004100000410000000016113752544275015215 0ustar www-datawww-data#!/usr/bin/env ruby require "bundler/setup" require_relative "../lib/thwait" require "irb" IRB.start(__FILE__) thwait-0.2.0/bin/setup0000755000004100000410000000011213752544275014707 0ustar www-datawww-data#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' set -vx bundle install thwait-0.2.0/.gitignore0000644000004100000410000000012613752544275015046 0ustar www-datawww-data/.bundle/ /.yardoc /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ Gemfile.lock thwait-0.2.0/thwait.gemspec0000644000004100000410000000162113752544275015724 0ustar www-datawww-databegin require_relative "lib/thwait/version" rescue LoadError # for Ruby core repository require_relative "version" end Gem::Specification.new do |spec| spec.name = "thwait" spec.version = ThreadsWait::VERSION spec.authors = ["Keiju ISHITSUKA"] spec.email = ["keiju@ruby-lang.org"] spec.summary = %q{Watches for termination of multiple threads.} spec.description = %q{Watches for termination of multiple threads.} spec.homepage = "https://github.com/ruby/thwait" spec.license = "BSD-2-Clause" spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/thwait.rb", "lib/thwait/version.rb", "thwait.gemspec"] spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] spec.add_dependency "e2mmap" end thwait-0.2.0/Rakefile0000644000004100000410000000003413752544275014521 0ustar www-datawww-datarequire "bundler/gem_tasks" thwait-0.2.0/lib/0000755000004100000410000000000013752544275013625 5ustar www-datawww-datathwait-0.2.0/lib/thwait/0000755000004100000410000000000013752544275015125 5ustar www-datawww-datathwait-0.2.0/lib/thwait/version.rb0000644000004100000410000000005213752544275017134 0ustar www-datawww-dataclass ThreadsWait VERSION = "0.2.0" end thwait-0.2.0/lib/thwait.rb0000644000004100000410000000660313752544275015457 0ustar www-datawww-data# frozen_string_literal: false # # thwait.rb - thread synchronization class # $Release Version: 0.9 $ # $Revision: 1.3 $ # by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.) require "e2mmap" # # 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. # # Example: # # ThreadsWait.all_waits(thr1, thr2, ...) do |t| # STDERR.puts "Thread #{t} has terminated." # end # # # th = ThreadsWait.new(thread1,...) # th.next_wait # next one to be done # # class ThreadsWait extend Exception2MessageMapper def_exception("ErrNoWaitingThread", "No threads for waiting.") def_exception("ErrNoFinishedThread", "No finished threads.") # # Waits until all specified threads have terminated. If a block is provided, # it is executed for each thread as they terminate. # def ThreadsWait.all_waits(*threads) # :yield: thread tw = ThreadsWait.new(*threads) if block_given? tw.all_waits do |th| yield th end else tw.all_waits end end # # Creates a ThreadsWait object, specifying the threads to wait on. # Non-blocking. # def initialize(*threads) @threads = [] @wait_queue = Thread::Queue.new join_nowait(*threads) unless threads.empty? end # Returns the array of threads that have not terminated yet. attr_reader :threads # # Returns +true+ if there are no threads in the pool still running. # def empty? @threads.empty? end # # Returns +true+ if any thread has terminated and is ready to be collected. # def finished? !@wait_queue.empty? end # # Waits for specified threads to terminate, and returns when one of # the threads terminated. # def join(*threads) join_nowait(*threads) next_wait end # # Specifies the threads that this object will wait for, but does not actually # wait. # def join_nowait(*threads) threads.flatten! @threads.concat threads for th in threads Thread.start(th) do |t| Thread.current.report_on_exception = false begin t.join ensure @wait_queue.push t end end end end # # Waits until any of the specified threads has terminated, and returns the one # that does. # # If there is no thread to wait, raises +ErrNoWaitingThread+. If +nonblock+ # is true, and there is no terminated thread, raises +ErrNoFinishedThread+. # def next_wait(nonblock = nil) ThreadsWait.fail ErrNoWaitingThread if @threads.empty? begin @threads.delete(th = @wait_queue.pop(nonblock)) th rescue ThreadError ThreadsWait.fail ErrNoFinishedThread end end # # Waits until all of the specified threads are terminated. If a block is # supplied for the method, it is executed for each thread termination. # # Raises exceptions in the same manner as +next_wait+. # def all_waits until @threads.empty? th = next_wait yield th if block_given? end end end ## # An alias for ThreadsWait from thwait.rb ThWait = ThreadsWait # Documentation comments: # - Source of documentation is evenly split between Nutshell, existing # comments, and my own rephrasing. # - I'm not particularly confident that the comments are all exactly correct. thwait-0.2.0/Gemfile0000644000004100000410000000020713752544275014351 0ustar www-datawww-datasource "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gemspec gem "bundler" gem "rake" thwait-0.2.0/LICENSE.txt0000644000004100000410000000240213752544275014700 0ustar www-datawww-dataCopyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.