From 3e6cd180308c06f368832693150ae00312553eca Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Wed, 18 May 2022 12:35:25 -0700 Subject: [PATCH] Reset concurrency to the initial default by setting 0 or nil `Vips.concurrency_set(0)` suggests it'll set concurrency back to the default value, but it does nothing if concurrency is already set, which is always true because Vips.init has already configured thread pools. The result is that if you set concurrency to any value, setting it to zero will leave that value in place. This reads the default concurrency immediately after Vips.init so we can make good on having `concurrency_set 0` reset to default. Also allows setting `nil` to reset to default. Note that setting concurrency does not reconfigure existing thread pools. It affects thread pools spawned for future operations. --- lib/vips.rb | 21 +++++++++++++++++++-- spec/spec_helper.rb | 8 ++++++++ spec/vips_spec.rb | 25 ++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/vips.rb b/lib/vips.rb index 1edd735d..4342b65c 100644 --- a/lib/vips.rb +++ b/lib/vips.rb @@ -626,6 +626,10 @@ def to_s attach_function :vips_leak_set, [:int], :void attach_function :vips_vector_set_enabled, [:int], :void attach_function :vips_concurrency_set, [:int], :void + attach_function :vips_concurrency_get, [], :int + + # Track the original default concurrency so we can reset to it. + DEFAULT_CONCURRENCY = vips_concurrency_get # vips_foreign_get_suffixes was added in libvips 8.8 begin @@ -663,10 +667,23 @@ def self.cache_set_max_files size vips_cache_set_max_files size end - # Set the size of the libvips worker pool. This defaults to the number of - # hardware threads on your computer. Set to 1 to disable threading. + # Get the size of libvips worker pools. Defaults to the VIPS_CONCURRENCY env + # var or the number of hardware threads on your computer. + def self.concurrency + vips_concurrency_get + end + + # Get the default size of libvips worker pools. + def self.concurrency_default + DEFAULT_CONCURRENCY + end + + # Set the size of each libvips worker pool. Max 1024 threads. Set to 1 to + # disable threading. Set to 0 or nil to reset to default. def self.concurrency_set n + n = DEFAULT_CONCURRENCY if n.to_i == 0 vips_concurrency_set n + concurrency end # Enable or disable SIMD and the run-time compiler. This can give a nice diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0410b1ba..2bb56931 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,11 @@ +# Set default concurrency so we can check against it later. Must be set +# before Vips.init sets concurrency to the default. +DEFAULT_VIPS_CONCURRENCY = 5 +ENV["VIPS_CONCURRENCY"] = DEFAULT_VIPS_CONCURRENCY.to_s + +# Disable stderr output since we purposefully trigger warn-able behavior. +ENV["VIPS_WARNING"] = "1" + require "vips" require "tempfile" diff --git a/spec/vips_spec.rb b/spec/vips_spec.rb index 6f28cde1..42cbb6d4 100644 --- a/spec/vips_spec.rb +++ b/spec/vips_spec.rb @@ -2,8 +2,31 @@ RSpec.describe Vips do describe "Vips" do + it "can get default concurrency" do + expect(Vips.concurrency_default).to eq DEFAULT_VIPS_CONCURRENCY + end + + it "can get concurrency" do + expect(Vips.concurrency).to eq Vips.concurrency_default + end + it "can set concurrency" do - Vips.concurrency_set 12 + expect(Vips.concurrency_set(12)).to eq 12 + expect(Vips.concurrency).to eq 12 + end + + it "clips concurrency to 1024" do + expect(Vips.concurrency_set(1025)).to eq 1024 + end + + it "can set concurrency to 0 to reset to default" do + Vips.concurrency_set(rand(100)) + expect(Vips.concurrency_set(0)).to eq Vips.concurrency_default + end + + it "can set concurrency to nil to reset to default" do + Vips.concurrency_set(rand(100)) + expect(Vips.concurrency_set(nil)).to eq Vips.concurrency_default end it "can set SIMD" do