IOBuffer back to Ruby (#1980)

This commit is contained in:
Nate Berkopec 2020-02-27 13:50:34 -06:00 committed by GitHub
parent a647a9a733
commit 510f39d330
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 18 additions and 241 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -1,155 +0,0 @@
#define RSTRING_NOT_MODIFIED 1
#include "ruby.h"
#include <sys/types.h>
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);
}

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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