From 510f39d330d44b233fd1a31c085478ec82e40afc Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Thu, 27 Feb 2020 13:50:34 -0600 Subject: [PATCH] IOBuffer back to Ruby (#1980) --- History.md | 1 + ext/puma_http11/PumaHttp11Service.java | 5 +- ext/puma_http11/io_buffer.c | 155 ------------------- ext/puma_http11/org/jruby/puma/IOBuffer.java | 72 --------- ext/puma_http11/puma_http11.c | 2 - lib/puma/io_buffer.rb | 11 +- lib/puma/server.rb | 3 +- test/test_iobuffer.rb | 10 +- 8 files changed, 18 insertions(+), 241 deletions(-) delete mode 100644 ext/puma_http11/io_buffer.c delete mode 100644 ext/puma_http11/org/jruby/puma/IOBuffer.java diff --git a/History.md b/History.md index 4d5696ba..510b4b9d 100644 --- a/History.md +++ b/History.md @@ -19,6 +19,7 @@ * Remove unused loader argument from Plugin initializer (#2095) * Simplify `Configuration.random_token` and remove insecure fallback (#2102) * Simplify `Runner#start_control` URL parsing (#2111) + * Removed the IOBuffer extension and replaced with Ruby (#1980) ## 4.3.2 and 3.12.3 / 2020-02-27 diff --git a/ext/puma_http11/PumaHttp11Service.java b/ext/puma_http11/PumaHttp11Service.java index 28add0d1..da7c2719 100644 --- a/ext/puma_http11/PumaHttp11Service.java +++ b/ext/puma_http11/PumaHttp11Service.java @@ -1,7 +1,7 @@ package puma; import java.io.IOException; - + import org.jruby.Ruby; import org.jruby.runtime.load.BasicLibraryService; @@ -9,10 +9,9 @@ import org.jruby.puma.Http11; import org.jruby.puma.IOBuffer; import org.jruby.puma.MiniSSL; -public class PumaHttp11Service implements BasicLibraryService { +public class PumaHttp11Service implements BasicLibraryService { public boolean basicLoad(final Ruby runtime) throws IOException { Http11.createHttp11(runtime); - IOBuffer.createIOBuffer(runtime); MiniSSL.createMiniSSL(runtime); return true; } diff --git a/ext/puma_http11/io_buffer.c b/ext/puma_http11/io_buffer.c deleted file mode 100644 index 1c1c0d57..00000000 --- a/ext/puma_http11/io_buffer.c +++ /dev/null @@ -1,155 +0,0 @@ -#define RSTRING_NOT_MODIFIED 1 -#include "ruby.h" - -#include - -struct buf_int { - uint8_t* top; - uint8_t* cur; - - size_t size; -}; - -#define BUF_DEFAULT_SIZE 4096 -#define BUF_TOLERANCE 32 - -static void buf_free(struct buf_int* internal) { - xfree(internal->top); - xfree(internal); -} - -static VALUE buf_alloc(VALUE self) { - VALUE buf; - struct buf_int* internal; - - buf = Data_Make_Struct(self, struct buf_int, 0, buf_free, internal); - - internal->size = BUF_DEFAULT_SIZE; - internal->top = ALLOC_N(uint8_t, BUF_DEFAULT_SIZE); - internal->cur = internal->top; - - return buf; -} - -static VALUE buf_append(VALUE self, VALUE str) { - struct buf_int* b; - size_t used, str_len, new_size; - - Data_Get_Struct(self, struct buf_int, b); - - used = b->cur - b->top; - - StringValue(str); - str_len = RSTRING_LEN(str); - - new_size = used + str_len; - - if(new_size > b->size) { - size_t n = b->size + (b->size / 2); - uint8_t* top; - uint8_t* old; - - new_size = (n > new_size ? n : new_size + BUF_TOLERANCE); - - top = ALLOC_N(uint8_t, new_size); - old = b->top; - memcpy(top, old, used); - b->top = top; - b->cur = top + used; - b->size = new_size; - xfree(old); - } - - memcpy(b->cur, RSTRING_PTR(str), str_len); - b->cur += str_len; - - return self; -} - -static VALUE buf_append2(int argc, VALUE* argv, VALUE self) { - struct buf_int* b; - size_t used, new_size; - int i; - VALUE str; - - Data_Get_Struct(self, struct buf_int, b); - - used = b->cur - b->top; - new_size = used; - - for(i = 0; i < argc; i++) { - StringValue(argv[i]); - - str = argv[i]; - - new_size += RSTRING_LEN(str); - } - - if(new_size > b->size) { - size_t n = b->size + (b->size / 2); - uint8_t* top; - uint8_t* old; - - new_size = (n > new_size ? n : new_size + BUF_TOLERANCE); - - top = ALLOC_N(uint8_t, new_size); - old = b->top; - memcpy(top, old, used); - b->top = top; - b->cur = top + used; - b->size = new_size; - xfree(old); - } - - for(i = 0; i < argc; i++) { - long str_len; - str = argv[i]; - str_len = RSTRING_LEN(str); - memcpy(b->cur, RSTRING_PTR(str), str_len); - b->cur += str_len; - } - - return self; -} - -static VALUE buf_to_str(VALUE self) { - struct buf_int* b; - Data_Get_Struct(self, struct buf_int, b); - - return rb_str_new((const char*)(b->top), b->cur - b->top); -} - -static VALUE buf_used(VALUE self) { - struct buf_int* b; - Data_Get_Struct(self, struct buf_int, b); - - return INT2FIX(b->cur - b->top); -} - -static VALUE buf_capa(VALUE self) { - struct buf_int* b; - Data_Get_Struct(self, struct buf_int, b); - - return INT2FIX(b->size); -} - -static VALUE buf_reset(VALUE self) { - struct buf_int* b; - Data_Get_Struct(self, struct buf_int, b); - - b->cur = b->top; - return self; -} - -void Init_io_buffer(VALUE puma) { - VALUE buf = rb_define_class_under(puma, "IOBuffer", rb_cObject); - - rb_define_alloc_func(buf, buf_alloc); - rb_define_method(buf, "<<", buf_append, 1); - rb_define_method(buf, "append", buf_append2, -1); - rb_define_method(buf, "to_str", buf_to_str, 0); - rb_define_method(buf, "to_s", buf_to_str, 0); - rb_define_method(buf, "used", buf_used, 0); - rb_define_method(buf, "capacity", buf_capa, 0); - rb_define_method(buf, "reset", buf_reset, 0); -} diff --git a/ext/puma_http11/org/jruby/puma/IOBuffer.java b/ext/puma_http11/org/jruby/puma/IOBuffer.java deleted file mode 100644 index ff245a8d..00000000 --- a/ext/puma_http11/org/jruby/puma/IOBuffer.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.jruby.puma; - -import org.jruby.*; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.util.ByteList; - -/** - * @author kares - */ -public class IOBuffer extends RubyObject { - - private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klass) { - return new IOBuffer(runtime, klass); - } - }; - - public static void createIOBuffer(Ruby runtime) { - RubyModule mPuma = runtime.defineModule("Puma"); - RubyClass cIOBuffer = mPuma.defineClassUnder("IOBuffer", runtime.getObject(), ALLOCATOR); - cIOBuffer.defineAnnotatedMethods(IOBuffer.class); - } - - private static final int DEFAULT_SIZE = 4096; - - final ByteList buffer = new ByteList(DEFAULT_SIZE); - - IOBuffer(Ruby runtime, RubyClass klass) { - super(runtime, klass); - } - - @JRubyMethod - public RubyInteger used(ThreadContext context) { - return context.runtime.newFixnum(buffer.getRealSize()); - } - - @JRubyMethod - public RubyInteger capacity(ThreadContext context) { - return context.runtime.newFixnum(buffer.unsafeBytes().length); - } - - @JRubyMethod - public IRubyObject reset() { - buffer.setRealSize(0); - return this; - } - - @JRubyMethod(name = { "to_s", "to_str" }) - public RubyString to_s(ThreadContext context) { - return RubyString.newStringShared(context.runtime, buffer.unsafeBytes(), 0, buffer.getRealSize()); - } - - @JRubyMethod(name = "<<") - public IRubyObject add(IRubyObject str) { - addImpl(str.convertToString()); - return this; - } - - @JRubyMethod(rest = true) - public IRubyObject append(IRubyObject[] strs) { - for (IRubyObject str : strs) addImpl(str.convertToString()); - return this; - } - - private void addImpl(RubyString str) { - buffer.append(str.getByteList()); - } - -} diff --git a/ext/puma_http11/puma_http11.c b/ext/puma_http11/puma_http11.c index 89ed1af8..86baba22 100644 --- a/ext/puma_http11/puma_http11.c +++ b/ext/puma_http11/puma_http11.c @@ -434,7 +434,6 @@ VALUE HttpParser_body(VALUE self) { return http->body; } -void Init_io_buffer(VALUE puma); void Init_mini_ssl(VALUE mod); void Init_puma_http11() @@ -464,6 +463,5 @@ void Init_puma_http11() rb_define_method(cHttpParser, "body", HttpParser_body, 0); init_common_fields(); - Init_io_buffer(mPuma); Init_mini_ssl(mPuma); } diff --git a/lib/puma/io_buffer.rb b/lib/puma/io_buffer.rb index 7af21452..48146719 100644 --- a/lib/puma/io_buffer.rb +++ b/lib/puma/io_buffer.rb @@ -1,4 +1,11 @@ # frozen_string_literal: true -require 'puma/detect' -require 'puma/puma_http11' +module Puma + class IOBuffer < String + def append(*args) + args.each { |a| concat(a) } + end + + alias reset clear + end +end diff --git a/lib/puma/server.rb b/lib/puma/server.rb index a57bd387..a6bbb5f2 100644 --- a/lib/puma/server.rb +++ b/lib/puma/server.rb @@ -11,6 +11,7 @@ require 'puma/client' require 'puma/binder' require 'puma/accept_nonblock' require 'puma/util' +require 'puma/io_buffer' require 'puma/puma_http11' @@ -297,7 +298,7 @@ module Puma @thread_pool = ThreadPool.new(@min_threads, @max_threads, - IOBuffer) do |client, buffer| + ::Puma::IOBuffer) do |client, buffer| # Advertise this server into the thread Thread.current[ThreadLocalKey] = self diff --git a/test/test_iobuffer.rb b/test/test_iobuffer.rb index d075b794..f30ad8c5 100644 --- a/test/test_iobuffer.rb +++ b/test/test_iobuffer.rb @@ -9,8 +9,7 @@ class TestIOBuffer < Minitest::Test end def test_initial_size - assert_equal 0, iobuf.used - assert iobuf.capacity > 0 + assert_equal 0, iobuf.size end def test_append_op @@ -18,22 +17,21 @@ class TestIOBuffer < Minitest::Test assert_equal "abc", iobuf.to_s iobuf << "123" assert_equal "abc123", iobuf.to_s - assert_equal 6, iobuf.used + assert_equal 6, iobuf.size end def test_append expected = "mary had a little lamb" iobuf.append("mary", " ", "had ", "a little", " lamb") assert_equal expected, iobuf.to_s - assert_equal expected.length, iobuf.used + assert_equal expected.length, iobuf.size end def test_reset iobuf << "content" assert_equal "content", iobuf.to_s iobuf.reset - assert_equal 0, iobuf.used + assert_equal 0, iobuf.size assert_equal "", iobuf.to_s end - end