farce 0.0.1.alpha2-x86_64-linux-gnu
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 +7 -0
- data/CODE_OF_CONDUCT.md +26 -0
- data/CONTRIBUTING.md +71 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1524 -0
- data/SECURITY.md +10 -0
- data/docs/benchmarks.md +185 -0
- data/docs/gems/dry-types.md +290 -0
- data/docs/gems/msgpack.md +70 -0
- data/docs/gems/ractor-shim.md +63 -0
- data/docs/modes.md +628 -0
- data/docs/scopes.md +649 -0
- data/docs/variants.md +346 -0
- data/ext/ext_helper.rb +20 -0
- data/ext/farce/README.md +21 -0
- data/ext/farce/atom.c +1023 -0
- data/ext/farce/bounded_map.c +1683 -0
- data/ext/farce/containers.h +77 -0
- data/ext/farce/counter.c +399 -0
- data/ext/farce/darwin.c +100 -0
- data/ext/farce/depend +12 -0
- data/ext/farce/dict.c +1523 -0
- data/ext/farce/dict.h +152 -0
- data/ext/farce/drivers.c +237 -0
- data/ext/farce/exchanger.c +299 -0
- data/ext/farce/extconf.rb +99 -0
- data/ext/farce/farce.c +359 -0
- data/ext/farce/flag.c +288 -0
- data/ext/farce/io.c +338 -0
- data/ext/farce/lock.c +510 -0
- data/ext/farce/map.c +2240 -0
- data/ext/farce/priority_queue.c +2056 -0
- data/ext/farce/queue.c +1059 -0
- data/ext/farce/reactor.c +820 -0
- data/ext/farce/reactor.h +103 -0
- data/ext/farce/shareable.h +31 -0
- data/ext/farce/signal.c +350 -0
- data/ext/farce/transaction.c +354 -0
- data/ext/farce/transaction.h +40 -0
- data/ext/farce/tree_map.c +1953 -0
- data/ext/farce/trie.c +2020 -0
- data/ext/farce/unshareable.c +155 -0
- data/ext/farce/unshared_io_pool.h +234 -0
- data/ext/farce/unshared_signal.c +263 -0
- data/ext/farce/unshared_wait.h +193 -0
- data/ext/farce/unsupported.c +6 -0
- data/ext/farce/vector.c +1195 -0
- data/ext/farce/weak_map.c +1714 -0
- data/ext/java/org/farce/BoundedMap.java +394 -0
- data/ext/java/org/farce/FiberScheduler.java +141 -0
- data/ext/java/org/farce/PriorityKey.java +45 -0
- data/ext/java/org/farce/PriorityQueue.java +373 -0
- data/ext/java/org/farce/QueueSignal.java +28 -0
- data/ext/rebind/README.md +14 -0
- data/ext/rebind/extconf.rb +10 -0
- data/ext/rebind/rebind.c +186 -0
- data/lib/farce/_yard/internal.rb +13 -0
- data/lib/farce/_yard/macros.rb +61 -0
- data/lib/farce/_yard/ractor.rb +46 -0
- data/lib/farce/abstract/atom.rb +186 -0
- data/lib/farce/abstract/bounded_map.rb +232 -0
- data/lib/farce/abstract/collection.rb +151 -0
- data/lib/farce/abstract/concurrent_map.rb +381 -0
- data/lib/farce/abstract/counter.rb +193 -0
- data/lib/farce/abstract/duplicable_map.rb +229 -0
- data/lib/farce/abstract/exchanger.rb +26 -0
- data/lib/farce/abstract/flag.rb +71 -0
- data/lib/farce/abstract/lazy.rb +115 -0
- data/lib/farce/abstract/lease.rb +104 -0
- data/lib/farce/abstract/lease_map.rb +261 -0
- data/lib/farce/abstract/lease_pool.rb +91 -0
- data/lib/farce/abstract/lfu_map.rb +20 -0
- data/lib/farce/abstract/lru_map.rb +25 -0
- data/lib/farce/abstract/map.rb +345 -0
- data/lib/farce/abstract/molecule.rb +245 -0
- data/lib/farce/abstract/port.rb +74 -0
- data/lib/farce/abstract/priority_queue.rb +117 -0
- data/lib/farce/abstract/queue.rb +269 -0
- data/lib/farce/abstract/scheduler.rb +111 -0
- data/lib/farce/abstract/set.rb +910 -0
- data/lib/farce/abstract/sorted_set.rb +172 -0
- data/lib/farce/abstract/timer_queue.rb +136 -0
- data/lib/farce/abstract/tree_map.rb +269 -0
- data/lib/farce/abstract/value.rb +68 -0
- data/lib/farce/abstract/vector.rb +1126 -0
- data/lib/farce/abstract/weak_atom.rb +32 -0
- data/lib/farce/abstract/weak_key_map.rb +12 -0
- data/lib/farce/abstract/weak_map.rb +13 -0
- data/lib/farce/abstract/weak_set.rb +12 -0
- data/lib/farce/abstract/weak_value_map.rb +12 -0
- data/lib/farce/abstract.rb +17 -0
- data/lib/farce/atom.rb +293 -0
- data/lib/farce/class_mirror.rb +87 -0
- data/lib/farce/clock.rb +121 -0
- data/lib/farce/config.rb +229 -0
- data/lib/farce/counter.rb +71 -0
- data/lib/farce/deduper.rb +122 -0
- data/lib/farce/engine/jruby/bounded_map.rb +314 -0
- data/lib/farce/engine/jruby/fiber_scheduler.jar +0 -0
- data/lib/farce/engine/jruby/fiber_scheduler.rb +119 -0
- data/lib/farce/engine/jruby/lease_waiting.rb +19 -0
- data/lib/farce/engine/jruby/map.rb +505 -0
- data/lib/farce/engine/jruby/mutable_numeric_copy.rb +42 -0
- data/lib/farce/engine/jruby/signal.rb +147 -0
- data/lib/farce/engine/jruby.rb +63 -0
- data/lib/farce/engine/jvm/concurrent_weak_registry.rb +55 -0
- data/lib/farce/engine/jvm/counter.rb +102 -0
- data/lib/farce/engine/jvm/extension.rb +32 -0
- data/lib/farce/engine/jvm/farce.jar +0 -0
- data/lib/farce/engine/jvm/flag.rb +79 -0
- data/lib/farce/engine/jvm/priority_queue.rb +217 -0
- data/lib/farce/engine/jvm/tree_map.rb +350 -0
- data/lib/farce/engine/jvm/types.rb +180 -0
- data/lib/farce/engine/jvm.rb +19 -0
- data/lib/farce/engine/ruby/3.4/farce.so +0 -0
- data/lib/farce/engine/ruby/3.4/fiber_scheduler.rb +20 -0
- data/lib/farce/engine/ruby/3.4/port.rb +186 -0
- data/lib/farce/engine/ruby/3.4/ractor_methods.rb +26 -0
- data/lib/farce/engine/ruby/3.4/ractor_selector.rb +92 -0
- data/lib/farce/engine/ruby/3.4/rebind.so +0 -0
- data/lib/farce/engine/ruby/3.4/vault.rb +56 -0
- data/lib/farce/engine/ruby/4.0/farce.so +0 -0
- data/lib/farce/engine/ruby/4.0/port.rb +19 -0
- data/lib/farce/engine/ruby/4.0/ractor_methods.rb +20 -0
- data/lib/farce/engine/ruby/4.0/ractor_selector.rb +108 -0
- data/lib/farce/engine/ruby/4.0/rebind.so +0 -0
- data/lib/farce/engine/ruby/4.0/vault.rb +74 -0
- data/lib/farce/engine/ruby/4.1/port.rb +21 -0
- data/lib/farce/engine/ruby/4.1/ractor_methods.rb +22 -0
- data/lib/farce/engine/ruby/4.1/ractor_selector.rb +25 -0
- data/lib/farce/engine/ruby/4.1/vault.rb +5 -0
- data/lib/farce/engine/ruby/fiber_scheduler.rb +32 -0
- data/lib/farce/engine/ruby/key_lock_map.rb +28 -0
- data/lib/farce/engine/ruby/shared/lease.rb +26 -0
- data/lib/farce/engine/ruby/shared/lease_pool.rb +24 -0
- data/lib/farce/engine/ruby/shared/main_scheduler.rb +9 -0
- data/lib/farce/engine/ruby/shared/parallel_scheduler.rb +9 -0
- data/lib/farce/engine/ruby/shared/proxy_owner.rb +31 -0
- data/lib/farce/engine/ruby/shared/ractor_methods.rb +34 -0
- data/lib/farce/engine/ruby/shared/ractor_selector.rb +328 -0
- data/lib/farce/engine/ruby/shared/strict_map.rb +13 -0
- data/lib/farce/engine/ruby/shared/unshared_vector.rb +14 -0
- data/lib/farce/engine/ruby/shared/vault.rb +144 -0
- data/lib/farce/engine/ruby/shared/vault_weak_map.rb +336 -0
- data/lib/farce/engine/ruby/shared/weak_atom.rb +54 -0
- data/lib/farce/engine/ruby/shared/weak_map.rb +413 -0
- data/lib/farce/engine/ruby.rb +130 -0
- data/lib/farce/engine/shared/atom.rb +10 -0
- data/lib/farce/engine/shared/exchanger.rb +130 -0
- data/lib/farce/engine/shared/identity_key.rb +22 -0
- data/lib/farce/engine/shared/lease.rb +10 -0
- data/lib/farce/engine/shared/lease_pool.rb +10 -0
- data/lib/farce/engine/shared/main_scheduler.rb +20 -0
- data/lib/farce/engine/shared/map_key_coordination.rb +226 -0
- data/lib/farce/engine/shared/parallel_scheduler.rb +9 -0
- data/lib/farce/engine/shared/port.rb +44 -0
- data/lib/farce/engine/shared/portable_bounded_map.rb +619 -0
- data/lib/farce/engine/shared/proxy_owner.rb +43 -0
- data/lib/farce/engine/shared/queue.rb +233 -0
- data/lib/farce/engine/shared/ractor_methods.rb +73 -0
- data/lib/farce/engine/shared/rebindable.rb +15 -0
- data/lib/farce/engine/shared/strict_atom.rb +73 -0
- data/lib/farce/engine/shared/strict_map.rb +117 -0
- data/lib/farce/engine/shared/strict_queue_values.rb +27 -0
- data/lib/farce/engine/shared/strict_tree_map.rb +56 -0
- data/lib/farce/engine/shared/transaction_map_backend.rb +20 -0
- data/lib/farce/engine/shared/trie.rb +317 -0
- data/lib/farce/engine/shared/trie_builder.rb +199 -0
- data/lib/farce/engine/shared/unshareable.rb +14 -0
- data/lib/farce/engine/shared/unshared_atom.rb +256 -0
- data/lib/farce/engine/shared/unshared_priority_queue.rb +9 -0
- data/lib/farce/engine/shared/unshared_queue.rb +18 -0
- data/lib/farce/engine/shared/unshared_signal.rb +21 -0
- data/lib/farce/engine/shared/unshared_vector.rb +377 -0
- data/lib/farce/engine/shared/unshared_weak_atom.rb +30 -0
- data/lib/farce/engine/shared/unshared_weak_map.rb +445 -0
- data/lib/farce/engine/shared/vault.rb +31 -0
- data/lib/farce/engine/shared/vector.rb +83 -0
- data/lib/farce/engine/shared/weak_atom/base.rb +189 -0
- data/lib/farce/engine/shared/weak_atom.rb +20 -0
- data/lib/farce/engine/shared/weak_map/cell.rb +99 -0
- data/lib/farce/engine/shared/weak_map/index.rb +249 -0
- data/lib/farce/engine/shared/weak_map/lock.rb +80 -0
- data/lib/farce/engine/shared/weak_map/reference.rb +33 -0
- data/lib/farce/engine/shared.rb +63 -0
- data/lib/farce/engine/truffleruby/fiber_scheduler.rb +13 -0
- data/lib/farce/engine/truffleruby/lock.rb +121 -0
- data/lib/farce/engine/truffleruby/map.rb +656 -0
- data/lib/farce/engine/truffleruby/native/counter.rb +105 -0
- data/lib/farce/engine/truffleruby/native/flag.rb +77 -0
- data/lib/farce/engine/truffleruby/native/ordered_array_support.rb +67 -0
- data/lib/farce/engine/truffleruby/native/priority_queue.rb +388 -0
- data/lib/farce/engine/truffleruby/native/tree_map.rb +51 -0
- data/lib/farce/engine/truffleruby/native/unsafe_tree_map.rb +350 -0
- data/lib/farce/engine/truffleruby/signal.rb +77 -0
- data/lib/farce/engine/truffleruby.rb +148 -0
- data/lib/farce/envelope.rb +335 -0
- data/lib/farce/error.rb +35 -0
- data/lib/farce/exchanger.rb +41 -0
- data/lib/farce/flag.rb +27 -0
- data/lib/farce/integrations/active_support/blank.rb +68 -0
- data/lib/farce/integrations/active_support/clock.rb +17 -0
- data/lib/farce/integrations/active_support/duplicable.rb +78 -0
- data/lib/farce/integrations/active_support/map.rb +175 -0
- data/lib/farce/integrations/active_support/set.rb +60 -0
- data/lib/farce/integrations/active_support/value_serialization.rb +17 -0
- data/lib/farce/integrations/active_support/vector.rb +231 -0
- data/lib/farce/integrations/active_support.rb +9 -0
- data/lib/farce/integrations/activesupport.rb +5 -0
- data/lib/farce/integrations/bson.rb +108 -0
- data/lib/farce/integrations/cbor.rb +51 -0
- data/lib/farce/integrations/concurrent.rb +112 -0
- data/lib/farce/integrations/dry-types.rb +5 -0
- data/lib/farce/integrations/dry_types.rb +694 -0
- data/lib/farce/integrations/json.rb +7 -0
- data/lib/farce/integrations/msgpack.rb +112 -0
- data/lib/farce/integrations/oj.rb +69 -0
- data/lib/farce/integrations/psych.rb +191 -0
- data/lib/farce/integrations/ractor-sharing.rb +5 -0
- data/lib/farce/integrations/ractor-tmvar.rb +5 -0
- data/lib/farce/integrations/ractor_sharing.rb +172 -0
- data/lib/farce/integrations/ractor_tmvar.rb +64 -0
- data/lib/farce/integrations/shared/to_json.rb +42 -0
- data/lib/farce/integrations/sorted_set.rb +11 -0
- data/lib/farce/integrations/weakref.rb +38 -0
- data/lib/farce/integrations/yajl.rb +10 -0
- data/lib/farce/integrations.rb +156 -0
- data/lib/farce/internal/_frozen_config.rb +11 -0
- data/lib/farce/internal/autoloads.rb +47 -0
- data/lib/farce/internal/blocking_priority_queue.rb +122 -0
- data/lib/farce/internal/converter.rb +106 -0
- data/lib/farce/internal/copyable.rb +31 -0
- data/lib/farce/internal/delegation.rb +20 -0
- data/lib/farce/internal/external_transaction.rb +59 -0
- data/lib/farce/internal/fake_ractor.rb +179 -0
- data/lib/farce/internal/freeze.rb +118 -0
- data/lib/farce/internal/inspect.rb +157 -0
- data/lib/farce/internal/key_lock_map.rb +29 -0
- data/lib/farce/internal/key_normalizer.rb +289 -0
- data/lib/farce/internal/lease_initialization.rb +115 -0
- data/lib/farce/internal/lease_map.rb +441 -0
- data/lib/farce/internal/lease_pool_state.rb +228 -0
- data/lib/farce/internal/lease_state.rb +342 -0
- data/lib/farce/internal/lease_waiting.rb +13 -0
- data/lib/farce/internal/managed_queue.rb +26 -0
- data/lib/farce/internal/map_value_modes.rb +227 -0
- data/lib/farce/internal/marshal_support.rb +227 -0
- data/lib/farce/internal/mixin.rb +20 -0
- data/lib/farce/internal/mutable_ordered_key_lock_map.rb +63 -0
- data/lib/farce/internal/noncopyable.rb +17 -0
- data/lib/farce/internal/ordered_key_lock_map.rb +69 -0
- data/lib/farce/internal/pool_supervisor.rb +41 -0
- data/lib/farce/internal/pool_worker.rb +61 -0
- data/lib/farce/internal/portable_transaction/reservation_entry.rb +29 -0
- data/lib/farce/internal/portable_transaction/strong_map_entry.rb +137 -0
- data/lib/farce/internal/portable_transaction/strong_map_size_entry.rb +44 -0
- data/lib/farce/internal/portable_transaction/tree_entry.rb +64 -0
- data/lib/farce/internal/portable_transaction.rb +164 -0
- data/lib/farce/internal/proxy_owner_notifications.rb +29 -0
- data/lib/farce/internal/reservation_waiting.rb +24 -0
- data/lib/farce/internal/scheduled_task.rb +48 -0
- data/lib/farce/internal/scheduler_io.rb +171 -0
- data/lib/farce/internal/scheduler_lifecycle.rb +314 -0
- data/lib/farce/internal/select_scheduler.rb +235 -0
- data/lib/farce/internal/storage.rb +162 -0
- data/lib/farce/internal/strict_lease.rb +30 -0
- data/lib/farce/internal/strict_lease_map.rb +20 -0
- data/lib/farce/internal/strict_lease_pool.rb +29 -0
- data/lib/farce/internal/thread_pool.rb +166 -0
- data/lib/farce/internal/transaction_conflict.rb +9 -0
- data/lib/farce/internal/transaction_freeze_guard.rb +30 -0
- data/lib/farce/internal/transaction_map_snapshot.rb +123 -0
- data/lib/farce/internal/undefined.rb +22 -0
- data/lib/farce/internal/unshared_lease.rb +29 -0
- data/lib/farce/internal/unshared_lease_pool.rb +34 -0
- data/lib/farce/internal/unshared_queue_waiting.rb +28 -0
- data/lib/farce/internal/value_serialization.rb +13 -0
- data/lib/farce/internal/weak_map_value_modes.rb +58 -0
- data/lib/farce/internal/weak_mode_manager.rb +26 -0
- data/lib/farce/internal.rb +129 -0
- data/lib/farce/lazy.rb +100 -0
- data/lib/farce/lazy_ref.rb +40 -0
- data/lib/farce/lease.rb +28 -0
- data/lib/farce/lease_map.rb +34 -0
- data/lib/farce/lease_pool.rb +29 -0
- data/lib/farce/lfu_map.rb +53 -0
- data/lib/farce/local/atom.rb +23 -0
- data/lib/farce/local/counter.rb +88 -0
- data/lib/farce/local/flag.rb +65 -0
- data/lib/farce/local/lazy.rb +38 -0
- data/lib/farce/local/lazy_ref.rb +36 -0
- data/lib/farce/local/lease.rb +77 -0
- data/lib/farce/local/lease_map.rb +80 -0
- data/lib/farce/local/lease_pool.rb +38 -0
- data/lib/farce/local/lfu_map.rb +55 -0
- data/lib/farce/local/lru_map.rb +62 -0
- data/lib/farce/local/map.rb +47 -0
- data/lib/farce/local/molecule.rb +45 -0
- data/lib/farce/local/priority_queue.rb +53 -0
- data/lib/farce/local/queue.rb +32 -0
- data/lib/farce/local/scoped.rb +166 -0
- data/lib/farce/local/set.rb +18 -0
- data/lib/farce/local/sorted_set.rb +50 -0
- data/lib/farce/local/timer_queue.rb +41 -0
- data/lib/farce/local/tree_map.rb +47 -0
- data/lib/farce/local/vector.rb +30 -0
- data/lib/farce/local/weak_atom.rb +23 -0
- data/lib/farce/local/weak_key_map.rb +39 -0
- data/lib/farce/local/weak_map.rb +39 -0
- data/lib/farce/local/weak_set.rb +18 -0
- data/lib/farce/local/weak_value_map.rb +39 -0
- data/lib/farce/local.rb +35 -0
- data/lib/farce/lock.rb +54 -0
- data/lib/farce/lru_map.rb +63 -0
- data/lib/farce/map.rb +58 -0
- data/lib/farce/mode_manager.rb +142 -0
- data/lib/farce/molecule.rb +60 -0
- data/lib/farce/mutable.rb +171 -0
- data/lib/farce/pool.rb +332 -0
- data/lib/farce/port.rb +134 -0
- data/lib/farce/priority_queue.rb +70 -0
- data/lib/farce/proxy/register.rb +101 -0
- data/lib/farce/proxy/supervisor.rb +137 -0
- data/lib/farce/proxy/wrapper.rb +49 -0
- data/lib/farce/proxy.rb +291 -0
- data/lib/farce/queue.rb +60 -0
- data/lib/farce/ractor.rb +269 -0
- data/lib/farce/read_write_lock.rb +256 -0
- data/lib/farce/reference.rb +158 -0
- data/lib/farce/resolv/dns.rb +42 -0
- data/lib/farce/resolv.rb +85 -0
- data/lib/farce/scheduler.rb +536 -0
- data/lib/farce/set.rb +39 -0
- data/lib/farce/shareable.rb +150 -0
- data/lib/farce/signal.rb +97 -0
- data/lib/farce/sorted_set.rb +36 -0
- data/lib/farce/strict/atom.rb +34 -0
- data/lib/farce/strict/counter.rb +10 -0
- data/lib/farce/strict/exchanger.rb +25 -0
- data/lib/farce/strict/flag.rb +10 -0
- data/lib/farce/strict/lazy.rb +26 -0
- data/lib/farce/strict/lazy_ref.rb +26 -0
- data/lib/farce/strict/lease.rb +27 -0
- data/lib/farce/strict/lease_map.rb +33 -0
- data/lib/farce/strict/lease_pool.rb +28 -0
- data/lib/farce/strict/lfu_map.rb +27 -0
- data/lib/farce/strict/lru_map.rb +28 -0
- data/lib/farce/strict/map.rb +54 -0
- data/lib/farce/strict/molecule.rb +16 -0
- data/lib/farce/strict/port.rb +40 -0
- data/lib/farce/strict/priority_queue.rb +20 -0
- data/lib/farce/strict/queue.rb +17 -0
- data/lib/farce/strict/set.rb +14 -0
- data/lib/farce/strict/sorted_set.rb +19 -0
- data/lib/farce/strict/timer_queue.rb +13 -0
- data/lib/farce/strict/tree_map.rb +27 -0
- data/lib/farce/strict/vector.rb +24 -0
- data/lib/farce/strict/weak_atom.rb +31 -0
- data/lib/farce/strict/weak_key_map.rb +49 -0
- data/lib/farce/strict/weak_map.rb +49 -0
- data/lib/farce/strict/weak_set.rb +14 -0
- data/lib/farce/strict/weak_value_map.rb +48 -0
- data/lib/farce/strict.rb +28 -0
- data/lib/farce/system.rb +40 -0
- data/lib/farce/thread_scheduler.rb +70 -0
- data/lib/farce/timer_queue.rb +66 -0
- data/lib/farce/transaction/atom.rb +73 -0
- data/lib/farce/transaction/map.rb +25 -0
- data/lib/farce/transaction/map_operations.rb +143 -0
- data/lib/farce/transaction/molecule.rb +90 -0
- data/lib/farce/transaction/mutable.rb +61 -0
- data/lib/farce/transaction/set.rb +17 -0
- data/lib/farce/transaction/set_operations.rb +48 -0
- data/lib/farce/transaction/sorted_set.rb +18 -0
- data/lib/farce/transaction/tree_map.rb +78 -0
- data/lib/farce/transaction/vector.rb +139 -0
- data/lib/farce/transaction/wrapper.rb +202 -0
- data/lib/farce/transaction.rb +343 -0
- data/lib/farce/tree_map.rb +56 -0
- data/lib/farce/unsafe/lfu_map.rb +36 -0
- data/lib/farce/unsafe/lru_map.rb +36 -0
- data/lib/farce/unsafe/tree_map.rb +21 -0
- data/lib/farce/unsafe.rb +29 -0
- data/lib/farce/unshareable.rb +67 -0
- data/lib/farce/unshared/atom.rb +24 -0
- data/lib/farce/unshared/counter.rb +10 -0
- data/lib/farce/unshared/flag.rb +10 -0
- data/lib/farce/unshared/lazy.rb +38 -0
- data/lib/farce/unshared/lazy_ref.rb +26 -0
- data/lib/farce/unshared/lease.rb +27 -0
- data/lib/farce/unshared/lease_map.rb +26 -0
- data/lib/farce/unshared/lease_pool.rb +25 -0
- data/lib/farce/unshared/lfu_map.rb +20 -0
- data/lib/farce/unshared/lru_map.rb +20 -0
- data/lib/farce/unshared/map.rb +49 -0
- data/lib/farce/unshared/molecule.rb +16 -0
- data/lib/farce/unshared/priority_queue.rb +16 -0
- data/lib/farce/unshared/queue.rb +27 -0
- data/lib/farce/unshared/set.rb +14 -0
- data/lib/farce/unshared/sorted_set.rb +28 -0
- data/lib/farce/unshared/timer_queue.rb +16 -0
- data/lib/farce/unshared/tree_map.rb +21 -0
- data/lib/farce/unshared/vector.rb +19 -0
- data/lib/farce/unshared/weak_atom.rb +31 -0
- data/lib/farce/unshared/weak_key_map.rb +44 -0
- data/lib/farce/unshared/weak_map.rb +44 -0
- data/lib/farce/unshared/weak_set.rb +14 -0
- data/lib/farce/unshared/weak_value_map.rb +43 -0
- data/lib/farce/unshared.rb +28 -0
- data/lib/farce/vector.rb +228 -0
- data/lib/farce/version.rb +8 -0
- data/lib/farce/walker/definitions.rb +186 -0
- data/lib/farce/walker/modification.rb +355 -0
- data/lib/farce/walker.rb +319 -0
- data/lib/farce/weak_atom.rb +121 -0
- data/lib/farce/weak_key_map.rb +31 -0
- data/lib/farce/weak_map.rb +33 -0
- data/lib/farce/weak_ref.rb +67 -0
- data/lib/farce/weak_set.rb +82 -0
- data/lib/farce/weak_value.rb +195 -0
- data/lib/farce/weak_value_map.rb +32 -0
- data/lib/farce.rb +519 -0
- metadata +468 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mkmf"
|
|
4
|
+
require_relative "../ext_helper"
|
|
5
|
+
|
|
6
|
+
if RUBY_ENGINE != "ruby"
|
|
7
|
+
File.write("Makefile", "all:\ninstall:\n")
|
|
8
|
+
return
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# rubocop:disable Style/GlobalVars -- mkmf configuration variables
|
|
12
|
+
%w[pthread.h ruby/ractor.h ruby/thread.h ruby/fiber/scheduler.h].each do |header|
|
|
13
|
+
have_header(header) or abort "#{header} is required"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ruby_major, ruby_minor = RUBY_VERSION.split(".").first(2).map!(&:to_i)
|
|
17
|
+
ruby_api = (ruby_major * 100) + ruby_minor
|
|
18
|
+
if ruby_api >= 401
|
|
19
|
+
have_macro("RB_OBJ_SET_SHAREABLE", "ruby/ractor.h") or abort "RB_OBJ_SET_SHAREABLE is required"
|
|
20
|
+
$defs << "-DFARCE_HAVE_EXPORTED_SHAREABLE_MARKER"
|
|
21
|
+
elsif ruby_api >= 304
|
|
22
|
+
# CRuby 3.4/4.0 have no exported marker on supported builds. The native
|
|
23
|
+
# publisher rejects Ruby ivars and requires audited typed-data payloads.
|
|
24
|
+
$defs << "-DFARCE_USE_LEGACY_SHAREABLE_FLAG"
|
|
25
|
+
else
|
|
26
|
+
abort "Native unfrozen publication requires CRuby 3.4 or newer"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if ruby_api == 304
|
|
30
|
+
have_func("rb_thread_lock_native_thread", "ruby/thread.h") or abort "rb_thread_lock_native_thread is required"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
have_func("clock_gettime", "time.h")
|
|
34
|
+
|
|
35
|
+
if /mswin|mingw/ =~ RUBY_PLATFORM
|
|
36
|
+
have_func("rb_objspace_reachable_objects_from") or abort "Windows waits require rb_objspace_reachable_objects_from"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if have_header("pthread/qos.h")
|
|
40
|
+
have_func("pthread_set_qos_class_self_np", "pthread/qos.h")
|
|
41
|
+
have_func("pthread_get_qos_class_np", "pthread/qos.h")
|
|
42
|
+
have_func("qos_class_main", "pthread/qos.h")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
have_func("sysctlbyname", "sys/sysctl.h") if have_header("sys/sysctl.h")
|
|
46
|
+
|
|
47
|
+
epoll = have_header("sys/epoll.h")
|
|
48
|
+
kqueue = have_header("sys/event.h")
|
|
49
|
+
$srcs = %w[
|
|
50
|
+
atom.c bounded_map.c counter.c darwin.c dict.c exchanger.c farce.c flag.c lock.c map.c priority_queue.c
|
|
51
|
+
queue.c signal.c transaction.c tree_map.c trie.c unshareable.c unshared_signal.c vector.c weak_map.c
|
|
52
|
+
]
|
|
53
|
+
$srcs.concat(epoll || kqueue ? %w[drivers.c io.c reactor.c] : ["unsupported.c"])
|
|
54
|
+
|
|
55
|
+
if epoll || kqueue
|
|
56
|
+
have_func("epoll_pwait2", "sys/epoll.h") if epoll
|
|
57
|
+
have_func("rb_io_timeout", "ruby/io.h")
|
|
58
|
+
if enable_config("io-uring", true) && have_header("liburing.h") && have_library("uring", "io_uring_queue_init")
|
|
59
|
+
$defs << "-DFARCE_HAVE_LIBURING"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
weak_callback = try_compile(<<~SOURCE)
|
|
64
|
+
#include "ruby.h"
|
|
65
|
+
|
|
66
|
+
static void handle_weak_references(void *pointer) { (void)pointer; }
|
|
67
|
+
static const rb_data_type_t probe_type = {
|
|
68
|
+
.wrap_struct_name = "weak-reference-probe",
|
|
69
|
+
.function = {
|
|
70
|
+
.handle_weak_references = handle_weak_references,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
int main(void) { return probe_type.function.handle_weak_references == 0; }
|
|
75
|
+
SOURCE
|
|
76
|
+
|
|
77
|
+
weak_declare = have_func("rb_gc_declare_weak_references")
|
|
78
|
+
weak_alive = have_func("rb_gc_handle_weak_references_alive_p")
|
|
79
|
+
|
|
80
|
+
# Kazlib deliberately puts full-tree integrity walks behind assert(3).
|
|
81
|
+
# Enable them only while debugging the priority queue.
|
|
82
|
+
$defs << "-DNDEBUG" unless ENV["FARCE_PRIORITY_QUEUE_ASSERTIONS"] == "1"
|
|
83
|
+
$defs << "-DRC_HAVE_NATIVE_WEAK_REFERENCES=1" if weak_callback && weak_declare && weak_alive
|
|
84
|
+
$defs << "-DFARCE_TRIE_FAILURE_INJECTION" if ENV["FARCE_TRIE_FAILURE_INJECTION"] == "1"
|
|
85
|
+
$CFLAGS = "#{$CFLAGS} -std=c11 -fvisibility=hidden -Wall -Wextra -Wno-unused-parameter -Wno-unused-function"
|
|
86
|
+
$LDFLAGS = "#{$LDFLAGS} -pthread" unless /mswin|mingw/ =~ RUBY_PLATFORM
|
|
87
|
+
|
|
88
|
+
if ENV["FARCE_SCHEDULER_SANITIZE"]
|
|
89
|
+
flags = " -O1 -g -fno-omit-frame-pointer -fsanitize=#{ENV.fetch("FARCE_SCHEDULER_SANITIZE")}"
|
|
90
|
+
$CFLAGS << flags
|
|
91
|
+
$LDFLAGS << flags
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if try_cflags("-flto") && try_ldflags("-flto")
|
|
95
|
+
$CFLAGS << " -flto"
|
|
96
|
+
$LDFLAGS << " -flto"
|
|
97
|
+
end
|
|
98
|
+
create_makefile ExtHelper.ext_path("farce")
|
|
99
|
+
# rubocop:enable Style/GlobalVars
|
data/ext/farce/farce.c
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#include "containers.h"
|
|
2
|
+
#include "transaction.h"
|
|
3
|
+
#include "shareable.h"
|
|
4
|
+
#include "ruby/fiber/scheduler.h"
|
|
5
|
+
#include "ruby/io.h"
|
|
6
|
+
|
|
7
|
+
#include <errno.h>
|
|
8
|
+
#include <math.h>
|
|
9
|
+
#include <unistd.h>
|
|
10
|
+
|
|
11
|
+
#ifdef _WIN32
|
|
12
|
+
#include <io.h>
|
|
13
|
+
#include <windows.h>
|
|
14
|
+
/* Older MinGW headers omit this flag even when the runtime supports it. */
|
|
15
|
+
#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
|
|
16
|
+
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
|
|
17
|
+
#endif
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
static VALUE eIsolationError;
|
|
21
|
+
|
|
22
|
+
void farce_init_fiber_scheduler(VALUE namespace);
|
|
23
|
+
|
|
24
|
+
RBIMPL_ATTR_NORETURN()
|
|
25
|
+
static void
|
|
26
|
+
raise_unshareable(VALUE value)
|
|
27
|
+
{
|
|
28
|
+
rb_raise(eIsolationError, "value is not shareable: %" PRIsVALUE, rb_inspect(value));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void
|
|
32
|
+
containers_check_shareable(VALUE value)
|
|
33
|
+
{
|
|
34
|
+
if (!rb_ractor_shareable_p(value)) raise_unshareable(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
bool
|
|
38
|
+
containers_strict_bool(VALUE value, const char *name)
|
|
39
|
+
{
|
|
40
|
+
if (value == Qtrue) return true;
|
|
41
|
+
if (value == Qfalse) return false;
|
|
42
|
+
rb_raise(rb_eArgError, "%s must be true or false", name);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static void
|
|
46
|
+
containers_check_native_publication_target(VALUE self)
|
|
47
|
+
{
|
|
48
|
+
if (!RB_TYPE_P(self, T_DATA) || !RTYPEDDATA_P(self)) {
|
|
49
|
+
rb_raise(rb_eTypeError, "native publication requires a typed-data object");
|
|
50
|
+
}
|
|
51
|
+
if (!(RTYPEDDATA_TYPE(self)->flags & RUBY_TYPED_FROZEN_SHAREABLE)) {
|
|
52
|
+
rb_raise(rb_eTypeError, "native publication requires a shareable typed-data descriptor");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
VALUE instance_variables = rb_obj_instance_variables(self);
|
|
56
|
+
if (RARRAY_LEN(instance_variables) != 0) {
|
|
57
|
+
rb_raise(
|
|
58
|
+
rb_eTypeError,
|
|
59
|
+
"%s cannot be published with Ruby instance variables",
|
|
60
|
+
rb_obj_classname(self)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
RB_GC_GUARD(instance_variables);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
VALUE
|
|
67
|
+
containers_publish_native_reference_free(VALUE self)
|
|
68
|
+
{
|
|
69
|
+
containers_check_native_publication_target(self);
|
|
70
|
+
return farce_ruby_mark_shareable(self);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
VALUE
|
|
74
|
+
containers_publish_native_with_references(
|
|
75
|
+
VALUE self,
|
|
76
|
+
containers_native_reference_validator_t validate_references
|
|
77
|
+
)
|
|
78
|
+
{
|
|
79
|
+
if (!validate_references) {
|
|
80
|
+
rb_raise(rb_eArgError, "native publication requires a reference validator");
|
|
81
|
+
}
|
|
82
|
+
containers_check_native_publication_target(self);
|
|
83
|
+
validate_references(self);
|
|
84
|
+
return farce_ruby_mark_shareable(self);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
VALUE
|
|
88
|
+
containers_raise_unfreezable(VALUE self)
|
|
89
|
+
{
|
|
90
|
+
rb_raise(rb_eTypeError, "%s cannot be frozen", rb_obj_classname(self));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
VALUE
|
|
94
|
+
containers_normalize_string_key(VALUE key)
|
|
95
|
+
{
|
|
96
|
+
VALUE stored_key;
|
|
97
|
+
|
|
98
|
+
if (!RB_TYPE_P(key, T_STRING)) return key;
|
|
99
|
+
if (rb_obj_class(key) == rb_cString) return rb_str_to_interned_str(key);
|
|
100
|
+
|
|
101
|
+
/* Preserve String subclasses and their instance state without dispatching
|
|
102
|
+
* overridable duplication or freezing methods. */
|
|
103
|
+
stored_key = rb_obj_alloc(rb_obj_class(key));
|
|
104
|
+
rb_str_replace(stored_key, key);
|
|
105
|
+
{
|
|
106
|
+
VALUE instance_variables = rb_obj_instance_variables(key);
|
|
107
|
+
long index;
|
|
108
|
+
|
|
109
|
+
for (index = 0; index < RARRAY_LEN(instance_variables); index++) {
|
|
110
|
+
ID id = SYM2ID(RARRAY_AREF(instance_variables, index));
|
|
111
|
+
rb_ivar_set(stored_key, id, rb_ivar_get(key, id));
|
|
112
|
+
}
|
|
113
|
+
RB_GC_GUARD(instance_variables);
|
|
114
|
+
}
|
|
115
|
+
rb_obj_freeze(stored_key);
|
|
116
|
+
return stored_key;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#ifdef _WIN32
|
|
120
|
+
typedef struct {
|
|
121
|
+
int fd;
|
|
122
|
+
bool readable;
|
|
123
|
+
int error;
|
|
124
|
+
} containers_read_context_t;
|
|
125
|
+
|
|
126
|
+
static void *
|
|
127
|
+
containers_poll_without_gvl(void *opaque)
|
|
128
|
+
{
|
|
129
|
+
containers_read_context_t *context = opaque;
|
|
130
|
+
intptr_t descriptor = _get_osfhandle(context->fd);
|
|
131
|
+
if (descriptor == -1) {
|
|
132
|
+
context->error = EBADF;
|
|
133
|
+
return NULL;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
DWORD available = 0;
|
|
137
|
+
if (!PeekNamedPipe((HANDLE)descriptor, NULL, 0, NULL, &available, NULL)) {
|
|
138
|
+
context->error = EIO;
|
|
139
|
+
return NULL;
|
|
140
|
+
}
|
|
141
|
+
/* Match rb_io_wait: observe readiness without consuming the notification.
|
|
142
|
+
* The caller owns its notification's lifetime and cleanup. */
|
|
143
|
+
context->readable = available > 0;
|
|
144
|
+
return NULL;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
RUBY_EXTERN void rb_objspace_reachable_objects_from(VALUE, void (*)(VALUE, void *), void *);
|
|
148
|
+
|
|
149
|
+
void
|
|
150
|
+
containers_wait_safepoint(void)
|
|
151
|
+
{
|
|
152
|
+
/* A Windows VM-barrier interrupt can target a sleeping sibling thread.
|
|
153
|
+
* Checking only this thread's interrupts then misses the pending barrier.
|
|
154
|
+
* The exported reachability API acquires the VM lock and joins that barrier.
|
|
155
|
+
* nil has no children, so this does not traverse, allocate, or collect. */
|
|
156
|
+
rb_objspace_reachable_objects_from(Qnil, NULL, NULL);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static void *
|
|
160
|
+
containers_sleep_without_gvl(void *opaque)
|
|
161
|
+
{
|
|
162
|
+
(void)opaque;
|
|
163
|
+
/* SleepEx rounds short waits to the system timer tick. Keep pipe handoffs
|
|
164
|
+
* responsive without changing the process-wide timer resolution. */
|
|
165
|
+
HANDLE timer = CreateWaitableTimerExW(
|
|
166
|
+
NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
|
|
167
|
+
TIMER_MODIFY_STATE | SYNCHRONIZE
|
|
168
|
+
);
|
|
169
|
+
if (timer) {
|
|
170
|
+
LARGE_INTEGER due = {.QuadPart = -10000}; /* One millisecond. */
|
|
171
|
+
bool armed = SetWaitableTimer(timer, &due, 0, NULL, NULL, FALSE);
|
|
172
|
+
DWORD result = armed ? WaitForSingleObject(timer, 10) : WAIT_FAILED;
|
|
173
|
+
/* Close before returning to Ruby, which may deliver an interrupt. */
|
|
174
|
+
CloseHandle(timer);
|
|
175
|
+
if (result != WAIT_FAILED) return NULL;
|
|
176
|
+
}
|
|
177
|
+
/* Ruby redirects Sleep to rb_w32_Sleep, which requires the GVL. */
|
|
178
|
+
SleepEx(1, FALSE);
|
|
179
|
+
return NULL;
|
|
180
|
+
}
|
|
181
|
+
#endif
|
|
182
|
+
|
|
183
|
+
/* Called only after releasing the container's native mutex. GC and scheduler
|
|
184
|
+
* callbacks can run Ruby, mutate the container, or raise. The caller must
|
|
185
|
+
* recheck its condition and original deadline after every return. */
|
|
186
|
+
void
|
|
187
|
+
containers_wait_without_descriptor(int error, const char *operation, bool *collected, VALUE timeout)
|
|
188
|
+
{
|
|
189
|
+
if (error != EMFILE && error != ENFILE) {
|
|
190
|
+
errno = error;
|
|
191
|
+
rb_sys_fail(operation);
|
|
192
|
+
}
|
|
193
|
+
if (!*collected) {
|
|
194
|
+
*collected = true;
|
|
195
|
+
rb_gc_start();
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Descriptor pressure must not turn a cooperative fiber wait into a
|
|
200
|
+
* whole-thread block. Timed polling needs no new notification descriptor
|
|
201
|
+
* and lets a producer on the same scheduler make progress. */
|
|
202
|
+
double seconds = 0.001;
|
|
203
|
+
if (!NIL_P(timeout)) {
|
|
204
|
+
double remaining = NUM2DBL(timeout);
|
|
205
|
+
if (remaining <= 0) return;
|
|
206
|
+
if (remaining < seconds) seconds = remaining;
|
|
207
|
+
}
|
|
208
|
+
VALUE scheduler = rb_fiber_scheduler_current();
|
|
209
|
+
if (!NIL_P(scheduler)) {
|
|
210
|
+
rb_fiber_scheduler_kernel_sleep(scheduler, DBL2NUM(seconds));
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
struct timeval interval = {.tv_sec = 0, .tv_usec = (int)ceil(seconds * 1000000)};
|
|
214
|
+
rb_thread_wait_for(interval);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static VALUE
|
|
219
|
+
containers_io_wait(VALUE opaque)
|
|
220
|
+
{
|
|
221
|
+
VALUE *arguments = (VALUE *)opaque;
|
|
222
|
+
return rb_io_wait(arguments[0], INT2NUM(RUBY_IO_READABLE), arguments[1]);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static VALUE
|
|
226
|
+
containers_io_close(VALUE opaque)
|
|
227
|
+
{
|
|
228
|
+
VALUE *arguments = (VALUE *)opaque;
|
|
229
|
+
return rb_io_close(arguments[0]);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
bool
|
|
233
|
+
containers_wait_for_readable(int fd, VALUE timeout)
|
|
234
|
+
{
|
|
235
|
+
#ifdef _WIN32
|
|
236
|
+
/* Blocking CRT pipe reads do not reliably unblock on Thread#kill.
|
|
237
|
+
* Use short no-GVL probes even for indefinite waits so Ruby can deliver
|
|
238
|
+
* interrupts between slices and run the caller's waiter cleanup.
|
|
239
|
+
* Scheduler-backed waits retain rb_io_wait integration. */
|
|
240
|
+
if (NIL_P(rb_fiber_scheduler_current())) {
|
|
241
|
+
double seconds = NIL_P(timeout) ? 0 : NUM2DBL(timeout);
|
|
242
|
+
bool finite = !NIL_P(timeout);
|
|
243
|
+
ULONGLONG deadline = GetTickCount64() + (ULONGLONG)ceil(seconds * 1000);
|
|
244
|
+
containers_read_context_t context = {
|
|
245
|
+
.fd = fd,
|
|
246
|
+
.readable = false,
|
|
247
|
+
.error = 0,
|
|
248
|
+
};
|
|
249
|
+
for (;;) {
|
|
250
|
+
context.readable = false;
|
|
251
|
+
context.error = 0;
|
|
252
|
+
rb_thread_call_without_gvl(
|
|
253
|
+
containers_poll_without_gvl,
|
|
254
|
+
&context,
|
|
255
|
+
NULL,
|
|
256
|
+
NULL
|
|
257
|
+
);
|
|
258
|
+
if (context.error) {
|
|
259
|
+
errno = context.error;
|
|
260
|
+
rb_sys_fail("PeekNamedPipe");
|
|
261
|
+
}
|
|
262
|
+
if (context.readable) return true;
|
|
263
|
+
if (finite && GetTickCount64() >= deadline) return false;
|
|
264
|
+
containers_wait_safepoint();
|
|
265
|
+
rb_thread_call_without_gvl(
|
|
266
|
+
containers_sleep_without_gvl,
|
|
267
|
+
NULL,
|
|
268
|
+
NULL,
|
|
269
|
+
NULL
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
#endif
|
|
274
|
+
|
|
275
|
+
VALUE arguments[] = {
|
|
276
|
+
rb_io_open_descriptor(
|
|
277
|
+
rb_cIO,
|
|
278
|
+
fd,
|
|
279
|
+
FMODE_READABLE | FMODE_EXTERNAL,
|
|
280
|
+
Qnil,
|
|
281
|
+
Qnil,
|
|
282
|
+
NULL
|
|
283
|
+
),
|
|
284
|
+
timeout,
|
|
285
|
+
};
|
|
286
|
+
VALUE result = rb_ensure(
|
|
287
|
+
containers_io_wait,
|
|
288
|
+
(VALUE)arguments,
|
|
289
|
+
containers_io_close,
|
|
290
|
+
(VALUE)arguments
|
|
291
|
+
);
|
|
292
|
+
RB_GC_GUARD(arguments[0]);
|
|
293
|
+
return RTEST(result);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
void
|
|
297
|
+
containers_raise_key_error(VALUE receiver, VALUE key)
|
|
298
|
+
{
|
|
299
|
+
VALUE message = rb_sprintf("key not found: %" PRIsVALUE, rb_inspect(key));
|
|
300
|
+
VALUE keywords = rb_hash_new();
|
|
301
|
+
rb_hash_aset(keywords, ID2SYM(rb_intern("receiver")), receiver);
|
|
302
|
+
rb_hash_aset(keywords, ID2SYM(rb_intern("key")), key);
|
|
303
|
+
VALUE arguments[] = {message, keywords};
|
|
304
|
+
VALUE exception = rb_class_new_instance_kw(2, arguments, rb_eKeyError, RB_PASS_KEYWORDS);
|
|
305
|
+
rb_exc_raise(exception);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
static VALUE
|
|
309
|
+
farce_load_native_fiber_scheduler(VALUE namespace)
|
|
310
|
+
{
|
|
311
|
+
farce_init_fiber_scheduler(namespace);
|
|
312
|
+
return Qnil;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
#if RUBY_API_VERSION_CODE == 30400
|
|
316
|
+
static VALUE
|
|
317
|
+
farce_lock_native_thread(VALUE namespace)
|
|
318
|
+
{
|
|
319
|
+
rb_thread_lock_native_thread();
|
|
320
|
+
return Qnil;
|
|
321
|
+
}
|
|
322
|
+
#endif
|
|
323
|
+
|
|
324
|
+
RUBY_FUNC_EXPORTED void
|
|
325
|
+
Init_farce(void)
|
|
326
|
+
{
|
|
327
|
+
rb_ext_ractor_safe(true);
|
|
328
|
+
VALUE mFarce = rb_const_get(rb_cObject, rb_intern("Farce"));
|
|
329
|
+
VALUE mInternal = rb_const_get(mFarce, rb_intern("Internal"));
|
|
330
|
+
VALUE singleton = rb_singleton_class(mInternal);
|
|
331
|
+
eIsolationError = rb_const_get(rb_cRactor, rb_intern("IsolationError"));
|
|
332
|
+
#if RUBY_API_VERSION_CODE == 30400
|
|
333
|
+
rb_define_singleton_method(mInternal, "lock_native_thread", farce_lock_native_thread, 0);
|
|
334
|
+
#endif
|
|
335
|
+
rb_define_private_method(
|
|
336
|
+
singleton,
|
|
337
|
+
"load_native_fiber_scheduler",
|
|
338
|
+
farce_load_native_fiber_scheduler,
|
|
339
|
+
0
|
|
340
|
+
);
|
|
341
|
+
containers_init_transaction(mInternal);
|
|
342
|
+
containers_init_atom(mInternal);
|
|
343
|
+
containers_init_counter(mInternal);
|
|
344
|
+
containers_init_exchanger(mInternal);
|
|
345
|
+
containers_init_flag(mInternal);
|
|
346
|
+
containers_init_lock(mInternal);
|
|
347
|
+
containers_init_lru_maps(mInternal);
|
|
348
|
+
containers_init_map(mInternal);
|
|
349
|
+
containers_init_priority_queue(mInternal);
|
|
350
|
+
containers_init_darwin(mInternal);
|
|
351
|
+
containers_init_queue(mInternal);
|
|
352
|
+
containers_init_signal(mInternal);
|
|
353
|
+
containers_init_unshared_signal(mInternal);
|
|
354
|
+
containers_init_unshareable(mInternal);
|
|
355
|
+
containers_init_vector(mInternal);
|
|
356
|
+
containers_init_weak_maps(mInternal);
|
|
357
|
+
containers_init_tree_maps(mInternal);
|
|
358
|
+
containers_init_trie(mInternal);
|
|
359
|
+
}
|