static inline void* get_pointer_value(VALUE value) { const int type = TYPE(value); if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_PointerClass)) { return memory_address(value); } else if (type == T_NIL) { return NULL; } else if (type == T_FIXNUM) { return (void *) (uintptr_t) FIX2INT(value); } else if (type == T_BIGNUM) { return (void *) (uintptr_t) NUM2ULL(value); } else if (rb_respond_to(value, id_to_ptr)) { return MEMORY_PTR(rb_funcall2(value, id_to_ptr, 0, NULL)); } else { rb_raise(rb_eArgError, "value is not a pointer"); return NULL; } }
// remote call to AGAS void register_worker(registration_header const& header) { // This lock acquires the bbb mutex on creation. When it goes out of scope, // it's dtor calls big_boot_barrier::notify(). big_boot_barrier::scoped_lock lock(get_big_boot_barrier()); naming::resolver_client& agas_client = get_runtime().get_agas_client(); if (HPX_UNLIKELY(agas_client.is_connecting())) { HPX_THROW_EXCEPTION(internal_server_error , "agas::register_worker" , "runtime_mode_connect can't find running application."); } if (HPX_UNLIKELY(!agas_client.is_bootstrap())) { HPX_THROW_EXCEPTION(internal_server_error , "agas::register_worker" , "registration parcel received by non-bootstrap locality."); } naming::gid_type prefix , parcel_lower, parcel_upper , heap_lower, heap_upper; agas_client.register_locality(header.locality, prefix); agas_client.get_id_range(header.locality, header.parcelport_allocation , parcel_lower, parcel_upper); agas_client.get_id_range(header.locality, header.response_allocation , heap_lower, heap_upper); naming::gid_type runtime_support_gid(prefix.get_msb() , header.component_runtime_support_ptr) , memory_gid(prefix.get_msb() , header.component_memory_ptr); naming::address runtime_support_address (header.locality, components::get_component_type<components::server::runtime_support>(), header.component_runtime_support_ptr); naming::address memory_address (header.locality, components::get_component_type<components::server::memory>(), header.component_memory_ptr); agas_client.bind(runtime_support_gid, runtime_support_address); agas_client.bind(memory_gid, memory_address); agas_client.bind_range(heap_lower, header.response_allocation , header.response_heap_address , header.response_heap_offset); naming::address primary_addr(get_runtime().here(), server::primary_namespace::get_component_type(), static_cast<void*>(&agas_client.bootstrap->primary_ns_server)); naming::address component_addr(get_runtime().here(), server::component_namespace::get_component_type(), static_cast<void*>(&agas_client.bootstrap->component_ns_server)); naming::address symbol_addr(get_runtime().here(), server::symbol_namespace::get_component_type(), static_cast<void*>(&agas_client.bootstrap->symbol_ns_server)); actions::base_action* p = new actions::transfer_action<notify_console_action>( notification_header( prefix, header.response_heap_address, header.response_heap_ptr, heap_lower, heap_upper, parcel_lower, parcel_upper, primary_addr, component_addr, symbol_addr)); // FIXME: This could screw with startup. // TODO: Handle cases where localities try to connect to AGAS while it's // shutting down. if (agas_client.status() != starting) { // We can just send the parcel now, the connecting locality isn't a part // of startup synchronization. get_big_boot_barrier().apply(naming::get_locality_id_from_gid(prefix) , naming::address(header.locality), p); } else // AGAS is starting up; this locality is participating in startup { // synchronization. HPX_STD_FUNCTION<void()>* thunk = new HPX_STD_FUNCTION<void()> (boost::bind(&big_boot_barrier::apply , boost::ref(get_big_boot_barrier()) , naming::get_locality_id_from_gid(prefix) , naming::address(header.locality) , p)); get_big_boot_barrier().add_thunk(thunk); } }