io-memory 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 65cddba6258b4275777fda4eef9777255547ac351b3ca3c7e9f64c84f0540a5f
4
+ data.tar.gz: bf3066d3b0a616346326cfd1df300ce7e0d81183675bb778b62ab77eb1329ef7
5
+ SHA512:
6
+ metadata.gz: c256056fa025c5e215c22b41a672b657e4bb92db4f2fe08dddd679e8a5c9397a1b293139e5122250de4644e9e04583c00a89e0b54f47e5caf9901e9ce60fe6cc
7
+ data.tar.gz: fe1371a70acf30c6e91a4f258bae9aeb82a9ec2e2af148d423c744e8e00f8aedde117ca479ca7f2e781e0bb5c333c0a7f5e766302f656cb1a32a134259429f18
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Shopify Inc.
5
+
6
+ require "tempfile"
7
+
8
+ module IO::Memory
9
+ # Generic implementation of memory-mapped IO using temporary files.
10
+ # This implementation provides maximum compatibility across platforms
11
+ # by using Ruby's built-in Tempfile class and file descriptor mapping.
12
+ # The temporary files are unlinked immediately after creation to behave
13
+ # like anonymous memory objects.
14
+ module Generic
15
+ extend self
16
+
17
+ module Implementation
18
+ # Handle class that wraps the IO and manages tempfile cleanup
19
+ class Handle
20
+ def initialize(io, tempfile, size)
21
+ @io = io
22
+ @tempfile = tempfile
23
+ @size = size
24
+ end
25
+
26
+ def io
27
+ @io
28
+ end
29
+
30
+ def map(size = nil)
31
+ size ||= @size
32
+ ::IO::Buffer.map(@io, size)
33
+ end
34
+
35
+ def close
36
+ @io.close unless @io.closed?
37
+ ensure
38
+ # Clean up tempfile
39
+ if @tempfile && !@tempfile.closed?
40
+ @tempfile.close
41
+ @tempfile = nil
42
+ end
43
+ end
44
+
45
+ def closed?
46
+ @io.closed?
47
+ end
48
+ end
49
+
50
+ def self.create_handle(size)
51
+ # Create a temporary file
52
+ tempfile = Tempfile.new(["io_memory", ".tmp"])
53
+
54
+ begin
55
+ # Set the size
56
+ tempfile.truncate(size) if tempfile.respond_to?(:truncate)
57
+
58
+ # Immediately unlink the file so it's deleted when closed
59
+ # This makes it behave more like memfd - it exists only in memory/cache
60
+ File.unlink(tempfile.path)
61
+
62
+ # Create IO from file descriptor and wrap in Handle
63
+ io = ::IO.for_fd(tempfile.fileno, autoclose: false)
64
+
65
+ return Handle.new(io, tempfile, size)
66
+ rescue => error
67
+ # Clean up on error
68
+ tempfile.close
69
+ tempfile.unlink if File.exist?(tempfile.path)
70
+ raise IO::Memory::MemoryError, "Failed to create temporary file buffer!"
71
+ end
72
+ end
73
+ end
74
+
75
+ private_constant :Implementation
76
+
77
+ # Check if the generic temporary file implementation is supported on this system.
78
+ # This implementation always returns true as it uses standard Ruby temporary files
79
+ # which are available on all platforms. It serves as a fallback when platform-specific
80
+ # implementations like Linux memfd_create or POSIX shm_open are not available.
81
+ # @returns [Boolean] always true, as temporary files are universally supported
82
+ def self.supported?
83
+ true
84
+ end
85
+
86
+ # Create a new memory-mapped buffer using a temporary file.
87
+ # The temporary file is immediately unlinked to behave like
88
+ # anonymous memory, existing only in the filesystem cache.
89
+ # @parameter size [Integer] size of the memory buffer in bytes
90
+ # @returns [Object] a handle object that provides access to the memory buffer
91
+ def new(size)
92
+ Implementation.create_handle(size)
93
+ end
94
+
95
+ # Create a memory-mapped buffer and yield it to a block.
96
+ # The buffer is automatically cleaned up when the block exits,
97
+ # regardless of whether an exception is raised.
98
+ # @parameter size [Integer] size of the memory buffer in bytes
99
+ # @yields {|handle| ...}
100
+ # @parameter handle [Object] the handle to the memory buffer with access to IO and mapping operations
101
+ # @returns [Object] the result of the block execution
102
+ def with(size, &block)
103
+ handle = new(size)
104
+ begin
105
+ yield handle
106
+ ensure
107
+ handle.close
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Shopify Inc.
5
+
6
+ require "fiddle"
7
+ require "fiddle/import"
8
+
9
+ module IO::Memory
10
+ # Linux-specific implementation of memory-mapped IO using memfd_create.
11
+ # This implementation provides the most efficient memory mapping on Linux
12
+ # by using the memfd_create system call to create anonymous memory objects
13
+ # that exist only in memory without being backed by any filesystem.
14
+ module Linux
15
+ extend self
16
+
17
+ module Implementation
18
+ extend Fiddle::Importer
19
+
20
+ def self.supported?
21
+ @supported
22
+ end
23
+
24
+ # memfd_create system call constants
25
+ MFD_CLOEXEC = 0x01
26
+
27
+ # Load system functions
28
+ LIBC = Fiddle.dlopen(nil)
29
+
30
+ # Load memfd_create function
31
+ MEMFD_CREATE = Fiddle::Function.new(
32
+ LIBC["memfd_create"],
33
+ [Fiddle::TYPE_VOIDP, Fiddle::TYPE_UINT],
34
+ Fiddle::TYPE_INT
35
+ )
36
+
37
+ # Load ftruncate function
38
+ FTRUNCATE = Fiddle::Function.new(
39
+ LIBC["ftruncate"],
40
+ [Fiddle::TYPE_INT, Fiddle::TYPE_LONG],
41
+ Fiddle::TYPE_INT
42
+ )
43
+
44
+ CLOSE = Fiddle::Function.new(
45
+ LIBC["close"],
46
+ [Fiddle::TYPE_INT],
47
+ Fiddle::TYPE_INT
48
+ )
49
+
50
+ # Handle class that wraps the IO
51
+ class Handle
52
+ def initialize(io, size)
53
+ @io = io
54
+ @size = size
55
+ end
56
+
57
+ def io
58
+ @io
59
+ end
60
+
61
+ def map(size = nil)
62
+ size ||= @size
63
+ ::IO::Buffer.map(@io, size)
64
+ end
65
+
66
+ def close
67
+ @io.close unless @io.closed?
68
+ end
69
+
70
+ def closed?
71
+ @io.closed?
72
+ end
73
+ end
74
+
75
+ def self.create_handle(size)
76
+ # Create the memory file descriptor
77
+ file_descriptor = MEMFD_CREATE.call("io_memory", MFD_CLOEXEC)
78
+
79
+ if file_descriptor == -1
80
+ raise IO::Memory::MemoryError, "Failed to create memfd!"
81
+ end
82
+
83
+ # Set the size
84
+ if FTRUNCATE.call(file_descriptor, size) == -1
85
+ # Clean up on error
86
+ begin
87
+ CLOSE.call(file_descriptor)
88
+ rescue
89
+ # Ignore cleanup errors
90
+ end
91
+ raise IO::Memory::MemoryError, "Failed to set memfd size!"
92
+ end
93
+
94
+ # Convert to IO object and wrap in Handle
95
+ io = ::IO.for_fd(file_descriptor, autoclose: true)
96
+
97
+ return Handle.new(io, size)
98
+ rescue => error
99
+ # Clean up on any error
100
+ if file_descriptor and file_descriptor != -1
101
+ begin
102
+ CLOSE.call(file_descriptor)
103
+ rescue
104
+ # Ignore cleanup errors
105
+ end
106
+ end
107
+ raise
108
+ end
109
+
110
+ @supported = true
111
+ rescue
112
+ @supported = false
113
+ end
114
+
115
+ private_constant :Implementation
116
+
117
+ # Check if the Linux memfd_create implementation is supported on this system.
118
+ # This implementation uses the memfd_create() system call available on Linux 3.17+
119
+ # and provides the most efficient memory mapping by creating anonymous memory objects.
120
+ # @returns [Boolean] true if memfd_create is available, false otherwise
121
+ def self.supported?
122
+ Implementation.supported?
123
+ end
124
+
125
+ if supported?
126
+ # Create a new memory-mapped buffer using Linux memfd_create.
127
+ # This creates an anonymous memory object that exists only in memory
128
+ # without being backed by any filesystem.
129
+ # @parameter size [Integer] size of the memory buffer in bytes
130
+ # @returns [Object] a handle object that provides access to the memory buffer
131
+ def new(size)
132
+ Implementation.create_handle(size)
133
+ end
134
+
135
+ # Create a memory-mapped buffer and yield it to a block.
136
+ # The buffer is automatically cleaned up when the block exits,
137
+ # regardless of whether an exception is raised.
138
+ # @parameter size [Integer] size of the memory buffer in bytes
139
+ # @yields {|handle| ...}
140
+ # @parameter handle [Object] the handle to the memory buffer with access to IO and mapping operations
141
+ # @returns [Object] the result of the block execution
142
+ def with(size, &block)
143
+ handle = new(size)
144
+ begin
145
+ yield handle
146
+ ensure
147
+ handle.close
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Shopify Inc.
5
+
6
+ require "fiddle"
7
+ require "securerandom"
8
+
9
+ module IO::Memory
10
+ # POSIX implementation of memory-mapped IO using shm_open.
11
+ # This implementation provides efficient memory mapping on POSIX-compliant
12
+ # systems (macOS, BSD, etc.) by using the shm_open system call to create
13
+ # shared memory objects. These objects can be shared between processes
14
+ # and provide zero-copy memory operations.
15
+ module POSIX
16
+ extend self
17
+
18
+ module Implementation
19
+ def self.supported?
20
+ @supported
21
+ end
22
+
23
+ # Use Ruby's File constants instead of hardcoded values for cross-platform compatibility
24
+ O_CREAT = IO::CREAT
25
+ O_EXCL = IO::EXCL
26
+ O_RDWR = IO::RDWR
27
+
28
+ # Load system functions
29
+ LIBC = Fiddle.dlopen(nil)
30
+
31
+ SHM_OPEN = Fiddle::Function.new(
32
+ LIBC["shm_open"],
33
+ [Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
34
+ Fiddle::TYPE_INT
35
+ )
36
+
37
+ SHM_UNLINK = Fiddle::Function.new(
38
+ LIBC["shm_unlink"],
39
+ [Fiddle::TYPE_VOIDP],
40
+ Fiddle::TYPE_INT
41
+ )
42
+
43
+ FTRUNCATE = Fiddle::Function.new(
44
+ LIBC["ftruncate"],
45
+ [Fiddle::TYPE_INT, Fiddle::TYPE_LONG],
46
+ Fiddle::TYPE_INT
47
+ )
48
+
49
+ class MemoryError < StandardError; end
50
+
51
+ # Handle class that wraps the IO and manages shared memory cleanup
52
+ class Handle
53
+ def initialize(io, shm_name, size)
54
+ @io = io
55
+ @shm_name = shm_name
56
+ @size = size
57
+ end
58
+
59
+ def io
60
+ @io
61
+ end
62
+
63
+ def map(size = nil)
64
+ size ||= @size
65
+ ::IO::Buffer.map(@io, size)
66
+ end
67
+
68
+ def close
69
+ @io.close unless @io.closed?
70
+ ensure
71
+ # Unlink the shared memory object
72
+ if @shm_name
73
+ Implementation::SHM_UNLINK.call(@shm_name)
74
+ @shm_name = nil
75
+ end
76
+ end
77
+
78
+ def closed?
79
+ @io.closed?
80
+ end
81
+ end
82
+
83
+ def self.create_handle(size)
84
+ # Generate a unique name using multiple entropy sources to avoid collisions
85
+ # in high-concurrency situations
86
+ max_attempts = 8
87
+ last_error = nil
88
+
89
+ max_attempts.times do
90
+ # The most portable maximum length for a POSIX shared memory name is 14 characters:
91
+ shm_name = "/#{SecureRandom.hex(7)}"
92
+
93
+ # Create shared memory object with O_EXCL to ensure uniqueness
94
+ shm_fd = SHM_OPEN.call(shm_name, O_CREAT | O_EXCL | O_RDWR, 0600)
95
+
96
+ if shm_fd >= 0
97
+ # Success! Set the size of the shared memory object
98
+ if FTRUNCATE.call(shm_fd, size) == 0
99
+ # Create IO object from file descriptor
100
+ io = ::IO.for_fd(shm_fd, autoclose: true)
101
+
102
+ # Return Handle that manages both IO and cleanup
103
+ return Handle.new(io, shm_name, size)
104
+ else
105
+ # ftruncate failed, clean up
106
+ SHM_UNLINK.call(shm_name)
107
+ raise IO::Memory::MemoryError, "Failed to set shared memory size to #{size}!"
108
+ end
109
+ else
110
+ # Store the error for potential debugging
111
+ last_error = Fiddle.last_error
112
+ end
113
+ # If we get here, shm_open failed (likely name collision), try again with new name
114
+ end
115
+
116
+ # If we've exhausted all attempts:
117
+ if last_error
118
+ cause = SystemCallError.new(last_error)
119
+ end
120
+
121
+ raise IO::Memory::MemoryError, "Failed to create shared memory object after #{max_attempts} attempts!", cause: cause
122
+ end
123
+
124
+ @supported = true
125
+ rescue
126
+ @supported = false
127
+ end
128
+
129
+ private_constant :Implementation
130
+
131
+ # Check if the POSIX shared memory implementation is supported on this system.
132
+ # This implementation uses shm_open() and is available on POSIX-compliant systems
133
+ # like macOS, BSD, and some Linux configurations with shared memory support.
134
+ # @returns [Boolean] true if POSIX shared memory is available, false otherwise
135
+ def self.supported?
136
+ Implementation.supported?
137
+ end
138
+
139
+ if supported?
140
+ # Create a new memory-mapped buffer using POSIX shared memory.
141
+ # This creates a shared memory object using shm_open that can be
142
+ # shared between processes and provides zero-copy operations.
143
+ # @parameter size [Integer] size of the memory buffer in bytes
144
+ # @returns [Object] a handle object that provides access to the memory buffer
145
+ def new(size)
146
+ Implementation.create_handle(size)
147
+ end
148
+
149
+ # Create a memory-mapped buffer and yield it to a block.
150
+ # The buffer is automatically cleaned up when the block exits,
151
+ # regardless of whether an exception is raised.
152
+ # @parameter size [Integer] size of the memory buffer in bytes
153
+ # @yields {|handle| ...}
154
+ # @parameter handle [Object] the handle to the memory buffer with access to IO and mapping operations
155
+ # @returns [Object] the result of the block execution
156
+ def with(size, &block)
157
+ handle = new(size)
158
+ begin
159
+ yield handle
160
+ ensure
161
+ handle.close
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Shopify Inc.
5
+
6
+ # @namespace
7
+ class IO
8
+ # @namespace
9
+ module Memory
10
+ VERSION = "0.0.1"
11
+ end
12
+ end
data/lib/io/memory.rb ADDED
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Shopify Inc.
5
+
6
+ require_relative "memory/version"
7
+
8
+ require_relative "memory/linux"
9
+ require_relative "memory/posix"
10
+ require_relative "memory/generic"
11
+
12
+ # Provides memory-mapped IO objects for zero-copy data sharing with cross-platform support.
13
+ # This module automatically selects the best available implementation based on the platform:
14
+ # - Linux: Uses memfd_create() for anonymous memory objects
15
+ # - POSIX: Uses shm_open() for shared memory objects
16
+ # - Generic: Uses temporary files for maximum compatibility
17
+ module IO::Memory
18
+ # Exception raised when memory operations fail.
19
+ # This includes errors during memory buffer creation, mapping, or cleanup operations.
20
+ class MemoryError < StandardError; end
21
+
22
+ # Select the best available implementation
23
+ # Priority: Linux (memfd_create) > POSIX (shm_open) > Generic (tempfile)
24
+ if Linux.supported?
25
+ extend Linux
26
+ elsif POSIX.supported?
27
+ extend POSIX
28
+ else
29
+ extend Generic
30
+ end
31
+ end
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright, 2025, by Shopify Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,80 @@
1
+ # `IO::Memory`
2
+
3
+ Memory-mapped IO objects for zero-copy data sharing with cross-platform support for Linux (`memfd_create`), POSIX (`shm_open`), and generic implementations.
4
+
5
+ [![Development Status](https://github.com/socketry/io-memory/workflows/Test/badge.svg)](https://github.com/socketry/io-memory/actions?workflow=Test)
6
+
7
+ ## Motivation
8
+
9
+ Modern applications increasingly require efficient memory sharing and zero-copy operations, especially in high-performance scenarios like web servers, data processing pipelines, and inter-process communication. `IO::Memory` provides a cross-platform abstraction over memory-mapped files that automatically selects the best available implementation based on your platform:
10
+
11
+ - **Linux**: Uses `memfd_create()` for anonymous memory objects with file descriptor passing
12
+ - **POSIX**: Uses `shm_open()` for POSIX shared memory objects
13
+ - **Generic**: Falls back to temporary files for maximum compatibility
14
+
15
+ This gem is designed to work seamlessly with Ruby's `IO::Buffer` class, providing efficient memory mapping capabilities that integrate well with modern Ruby's IO subsystem.
16
+
17
+ ## Features
18
+
19
+ - **Cross-platform**: Automatically selects the best memory implementation for your platform
20
+ - **Zero-copy**: Direct memory mapping without data copying
21
+ - **IO::Buffer integration**: Works seamlessly with Ruby's built-in buffer objects
22
+ - **File descriptor passing**: Share memory between processes (where supported)
23
+ - **Automatic cleanup**: Built-in resource management with `with` blocks
24
+ - **Multiple sizes**: Support for buffers from zero bytes to multiple gigabytes
25
+
26
+ ## Usage
27
+
28
+ Please see the [project documentation](https://socketry.github.io/io-memory/) for more details.
29
+
30
+ - [Getting Started](https://socketry.github.io/io-memory/guides/getting-started/index) - This guide explains how to use `io-memory` for efficient memory operations and zero-copy data sharing.
31
+
32
+ - [Process Memory Sharing](https://socketry.github.io/io-memory/guides/process-sharing/index) - This guide demonstrates how to share memory between processes using `io-memory` for high-performance inter-process communication (IPC).
33
+
34
+ ## Platform Support
35
+
36
+ | Platform | Implementation | Features |
37
+ | --- | --- | --- |
38
+ | Linux | `memfd_create()` | Anonymous memory, file descriptor passing |
39
+ | macOS/BSD | `shm_open()` | POSIX shared memory, file descriptor passing |
40
+ | Windows/Other | Temporary files | File descriptor passing, maximum compatibility |
41
+
42
+ ## Performance
43
+
44
+ `IO::Memory` provides significant performance benefits for memory-intensive operations:
45
+
46
+ - **Zero-copy**: No data copying when mapping memory
47
+ - **OS-optimized**: Uses the most efficient memory primitives available
48
+ - **Large buffer support**: Handles multi-gigabyte buffers efficiently
49
+ - **Shared memory**: Enable inter-process communication without serialization
50
+
51
+ ## Releases
52
+
53
+ Please see the [project releases](https://socketry.github.io/io-memory/releases/index) for all releases.
54
+
55
+ ### v0.0.1
56
+
57
+ - Initial implementation with cross-platform memory mapping support
58
+ - Linux `memfd_create()` implementation for anonymous memory objects
59
+ - POSIX `shm_open()` implementation for shared memory
60
+ - Generic temporary file fallback for maximum compatibility
61
+ - Integration with Ruby's `IO::Buffer` class
62
+ - Automatic resource cleanup with `with` blocks
63
+
64
+ ## Contributing
65
+
66
+ We welcome contributions to this project.
67
+
68
+ 1. Fork it.
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
71
+ 4. Push to the branch (`git push origin my-new-feature`).
72
+ 5. Create new Pull Request.
73
+
74
+ ### Developer Certificate of Origin
75
+
76
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
77
+
78
+ ### Community Guidelines
79
+
80
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data/releases.md ADDED
@@ -0,0 +1,10 @@
1
+ # Releases
2
+
3
+ ## v0.0.1
4
+
5
+ - Initial implementation with cross-platform memory mapping support
6
+ - Linux `memfd_create()` implementation for anonymous memory objects
7
+ - POSIX `shm_open()` implementation for shared memory
8
+ - Generic temporary file fallback for maximum compatibility
9
+ - Integration with Ruby's `IO::Buffer` class
10
+ - Automatic resource cleanup with `with` blocks
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: io-memory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Shopify Inc.
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: fiddle
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ executables: []
27
+ extensions: []
28
+ extra_rdoc_files: []
29
+ files:
30
+ - lib/io/memory.rb
31
+ - lib/io/memory/generic.rb
32
+ - lib/io/memory/linux.rb
33
+ - lib/io/memory/posix.rb
34
+ - lib/io/memory/version.rb
35
+ - license.md
36
+ - readme.md
37
+ - releases.md
38
+ homepage: https://github.com/socketry/io-memory
39
+ licenses:
40
+ - MIT
41
+ metadata:
42
+ documentation_uri: https://socketry.github.io/io-memory/
43
+ source_code_uri: https://github.com/socketry/io-memory.git
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '3.2'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.6.7
59
+ specification_version: 4
60
+ summary: Memory-mapped IO objects for zero-copy data sharing.
61
+ test_files: []