Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5247d3e
Add support for using FFI in Ractor
larskanis Apr 16, 2023
8f77740
Use a Ractor-local callback dispatcher for calls from non-ruby threads
larskanis Apr 18, 2023
82f5942
Ensure errno is usable in Ractor
larskanis Apr 18, 2023
1b78458
Freeze global typedefs and add per Ractor local custom typedefs
larskanis Apr 16, 2023
1689cc0
Fix compat to JRuby and TuffleRuby regarding Ractor
larskanis Apr 18, 2023
bc48722
Freeze constant in StructLayoutBuilder
larskanis Apr 18, 2023
88fa99a
Skip struct specs on Ruby-3.0
larskanis Apr 18, 2023
80726b2
Add a spec file for FFI::DynamicLibrary
larskanis Apr 20, 2023
ad1a2e0
Ensure some relevant constants are available in Ractor
larskanis Apr 20, 2023
e987ab5
Add the possibility to query attached funtions and variables
larskanis Apr 21, 2023
4fc6a8c
Store each FFI::Function in it's own instance variabe in the module t…
larskanis Apr 26, 2023
0093113
Rename result_type to return_type
larskanis Apr 26, 2023
e880997
Do not run any Ractor specs on ruby-3.0
larskanis Apr 27, 2023
89d23a5
Bump required ruby version to 2.5
larskanis Apr 27, 2023
23e88be
Ensure enums are usable in Ractor
larskanis May 2, 2023
fe556f1
Freeze immutable objects and add explicit make_shareable to make libr…
larskanis May 5, 2023
b0ed471
Add documentation to new query methods
larskanis May 7, 2023
b448759
Register functions in Ruby code
larskanis May 8, 2023
9ff5782
Add Ractor compatibility to README
larskanis May 8, 2023
938b5d8
Exclude JRuby and Truffleruby at retrieval of function types
larskanis May 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu, macos, windows ]
ruby: [ 2.3, 2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, ruby-head, truffleruby-head, jruby-head ]
ruby: [ 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, ruby-head, truffleruby-head, jruby-head ]
exclude:
- os: windows
ruby: truffleruby-head
- os: windows
ruby: 2.3 # compilation fails
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi).
* C structs (also nested), enums and global variables
* Callbacks from C to Ruby
* Automatic garbage collection of native memory
* Usable in Ractor

## Synopsis

Expand Down Expand Up @@ -62,7 +63,7 @@ On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and
From rubygems:

[sudo] gem install ffi

From a Gemfile using git or GitHub

gem 'ffi', github: 'ffi/ffi', submodules: true
Expand Down
18 changes: 17 additions & 1 deletion ext/ffi_c/AbstractMemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const rb_data_type_t rbffi_abstract_memory_data_type = { /* extern */
},
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};

static size_t
Expand Down Expand Up @@ -316,6 +316,7 @@ static VALUE
memory_clear(VALUE self)
{
AbstractMemory* ptr = MEMORY(self);
checkWrite(ptr);
memset(ptr->address, 0, ptr->size);
return self;
}
Expand Down Expand Up @@ -687,6 +688,20 @@ memory_copy_from(VALUE self, VALUE rbsrc, VALUE rblen)
return self;
}

/*
* call-seq:
* res.freeze
*
* Freeze the AbstractMemory object and unset the writable flag.
*/
static VALUE
memory_freeze(VALUE self)
{
AbstractMemory* ptr = MEMORY(self);
ptr->flags &= ~MEM_WR;
return rb_call_super(0, NULL);
}

AbstractMemory*
rbffi_AbstractMemory_Cast(VALUE obj, const rb_data_type_t *data_type)
{
Expand Down Expand Up @@ -1102,6 +1117,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
rb_define_method(classMemory, "type_size", memory_type_size, 0);
rb_define_method(classMemory, "[]", memory_aref, 1);
rb_define_method(classMemory, "__copy_from__", memory_copy_from, 2);
rb_define_method(classMemory, "freeze", memory_freeze, 0 );

id_to_ptr = rb_intern("to_ptr");
id_call = rb_intern("call");
Expand Down
2 changes: 1 addition & 1 deletion ext/ffi_c/ArrayType.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const rb_data_type_t rbffi_array_type_data_type = { /* extern */
.parent = &rbffi_type_data_type,
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};


Expand Down
4 changes: 2 additions & 2 deletions ext/ffi_c/Buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static const rb_data_type_t buffer_data_type = {
.parent = &rbffi_abstract_memory_data_type,
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};

static const rb_data_type_t allocated_buffer_data_type = {
Expand All @@ -80,7 +80,7 @@ static const rb_data_type_t allocated_buffer_data_type = {
.parent = &buffer_data_type,
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};


Expand Down
11 changes: 7 additions & 4 deletions ext/ffi_c/DynamicLibrary.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static const rb_data_type_t rbffi_library_data_type = {
},
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};

static const rb_data_type_t library_symbol_data_type = {
Expand All @@ -87,7 +87,7 @@ static const rb_data_type_t library_symbol_data_type = {
.parent = &rbffi_pointer_data_type,
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
// macro to update VALUE references, as to trigger write barriers.
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};

static VALUE LibraryClass = Qnil, SymbolClass = Qnil;
Expand Down Expand Up @@ -161,7 +161,9 @@ library_initialize(VALUE self, VALUE libname, VALUE libflags)
library->handle = RTLD_DEFAULT;
}
#endif
rb_iv_set(self, "@name", libname != Qnil ? libname : rb_str_new2("[current process]"));
rb_iv_set(self, "@name", libname != Qnil ? rb_str_new_frozen(libname) : rb_str_new2("[current process]"));

rb_obj_freeze(self);
return self;
}

Expand Down Expand Up @@ -266,8 +268,9 @@ symbol_new(VALUE library, void* address, VALUE name)
sym->base.memory.typeSize = 1;
sym->base.memory.flags = MEM_RD | MEM_WR;
RB_OBJ_WRITE(obj, &sym->base.rbParent, library);
RB_OBJ_WRITE(obj, &sym->name, name);
RB_OBJ_WRITE(obj, &sym->name, rb_str_new_frozen(name));

rb_obj_freeze(obj);
return obj;
}

Expand Down
Loading