From 32284c67f8afbdfc68f759597e854812bcda2d24 Mon Sep 17 00:00:00 2001 From: Ian Ker-Seymer Date: Thu, 11 Jan 2024 16:31:21 -0500 Subject: [PATCH 1/3] Explicitly return thread interrupt state in zstream_run_func --- ext/zlib/zlib.c | 10 ++++++++-- test/zlib/test_zlib.rb | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index dc608ee..fecd63b 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -592,6 +592,7 @@ struct zstream { #define ZSTREAM_REUSE_BUFFER_P(z) ((z)->flags & ZSTREAM_REUSE_BUFFER) #define ZSTREAM_EXPAND_BUFFER_OK 0 +#define ZSTREAM_THREAD_INTERRUPTED 9 /* I think that more better value should be found, but I gave up finding it. B) */ @@ -1019,7 +1020,7 @@ zstream_run_func(void *ptr) uInt n; err = Z_OK; - while (!args->interrupt) { + while (1) { n = z->stream.avail_out; err = z->func->run(&z->stream, flush); rb_str_set_len(z->buf, ZSTREAM_BUF_FILLED(z) + (n - z->stream.avail_out)); @@ -1059,6 +1060,11 @@ zstream_run_func(void *ptr) args->jump_state = state; break; } + + if (args->interrupt) { + err = ZSTREAM_THREAD_INTERRUPTED; + break; + } } return (void *)(VALUE)err; @@ -1118,7 +1124,7 @@ zstream_run_try(VALUE value_arg) #endif /* retry if no exception is thrown */ - if (err == Z_OK && args->interrupt) { + if (err == ZSTREAM_THREAD_INTERRUPTED) { args->interrupt = 0; goto loop; } diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 779c583..1908b82 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1473,5 +1473,42 @@ def test_gunzip_no_memory_leak 10_000.times {Zlib.gunzip(d)} }; end + + def test_gzip_thread_interrupts + content = Random.bytes(5000) + stop = false + ret = nil + + thr = Thread.new do + until stop + ret = Zlib.gzip(content) + end + end + + 10000000.times { thr.wakeup } + stop = true + thr.join + + assert_equal content, Zlib.gunzip(ret) + end + + def test_gzipreader_thread_interrupts + content = Random.bytes(5000).b + gzipped = Zlib.gzip(content) + stop = false + ret = nil + + thr = Thread.new do + until stop + ret = Zlib::GzipReader.new(StringIO.new(gzipped), encoding: Encoding::BINARY).read + end + end + + 10000000.times { thr.wakeup } + stop = true + thr.join + + assert_equal content, ret + end end end From 5f74963a34c19ca4f57e6057bc6afdad8d9595d2 Mon Sep 17 00:00:00 2001 From: Ian Ker-Seymer Date: Thu, 11 Jan 2024 17:26:00 -0500 Subject: [PATCH 2/3] Use SecureRandom in tests for Ruby 2.5 --- test/zlib/test_zlib.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 1908b82..b5dbefc 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1475,7 +1475,7 @@ def test_gunzip_no_memory_leak end def test_gzip_thread_interrupts - content = Random.bytes(5000) + content = SecureRandom.random_bytes(5000) stop = false ret = nil @@ -1493,7 +1493,7 @@ def test_gzip_thread_interrupts end def test_gzipreader_thread_interrupts - content = Random.bytes(5000).b + content = SecureRandom.random_bytes(5000) gzipped = Zlib.gzip(content) stop = false ret = nil From fe21505547cc7c55ba01b8cae6ef365c2ff1b3f1 Mon Sep 17 00:00:00 2001 From: Ian Ker-Seymer Date: Thu, 11 Jan 2024 17:58:33 -0500 Subject: [PATCH 3/3] Exclude truffleruby CI tests on macos --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bc565e0..0d09b12 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,6 +27,8 @@ jobs: os: windows-latest - ruby: truffleruby-head os: windows-latest + - ruby: truffleruby-head + os: macos-latest runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4