예제 #1
0
bool SharedMemory::createHandle(Handle& handle, Protection protection)
{
    ASSERT(!handle.m_port);
    ASSERT(!handle.m_size);

    mach_vm_address_t address = toVMAddress(m_data);
    memory_object_size_t size = round_page(m_size);

    mach_port_t port;

    if (protection == ReadWrite && m_port) {
        // Just re-use the port we have.
        port = m_port;
        if (mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, 1) != KERN_SUCCESS)
            return false;
    } else {
        // Create a mach port that represents the shared memory.
        kern_return_t kr = mach_make_memory_entry_64(mach_task_self(), &size, address, machProtection(protection), &port, MACH_PORT_NULL);
        if (kr != KERN_SUCCESS)
            return false;

        ASSERT(size >= round_page(m_size));
    }

    handle.m_port = port;
    handle.m_size = size;

    return true;
}
예제 #2
0
SharedMemory::~SharedMemory()
{
    if (m_data) {
        kern_return_t kr = mach_vm_deallocate(mach_task_self(), toVMAddress(m_data), round_page(m_size));
#if RELEASE_LOG_DISABLED
        ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
#else
        if (kr != KERN_SUCCESS) {
            RELEASE_LOG_ERROR(VirtualMemory, "%p - SharedMemory::~SharedMemory: Failed to deallocate shared memory. %{public}s (%x)", this, mach_error_string(kr), kr);
            ASSERT_NOT_REACHED();
        }
#endif
    }

    if (m_port) {
        kern_return_t kr = mach_port_deallocate(mach_task_self(), m_port);
#if RELEASE_LOG_DISABLED
        ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
#else
        if (kr != KERN_SUCCESS) {
            RELEASE_LOG_ERROR(VirtualMemory, "%p - SharedMemory::~SharedMemory: Failed to deallocate port. %{public}s (%x)", this, mach_error_string(kr), kr);
            ASSERT_NOT_REACHED();
        }
#endif
    }        
}
예제 #3
0
SharedMemory::~SharedMemory()
{
    if (!m_data)
        return;
    
    kern_return_t kr = mach_vm_deallocate(mach_task_self(), toVMAddress(m_data), round_page(m_size));
    ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
}
예제 #4
0
WebCore::MachSendRight SharedMemory::createSendRight(Protection protection) const
{
    ASSERT(m_protection == protection || m_protection == Protection::ReadWrite && protection == Protection::ReadOnly);
    ASSERT(!!m_data ^ !!m_port);

    if (m_port && m_protection == protection)
        return WebCore::MachSendRight::create(m_port);

    ASSERT(m_data);
    return makeMemoryEntry(m_size, toVMAddress(m_data), protection, MACH_PORT_NULL);
}
예제 #5
0
SharedMemory::~SharedMemory()
{
    if (m_data && m_shouldVMDeallocateData) {
        kern_return_t kr = mach_vm_deallocate(mach_task_self(), toVMAddress(m_data), round_page(m_size));
        ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
    }

    if (m_port) {
        kern_return_t kr = mach_port_deallocate(mach_task_self(), m_port);
        ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
    }        
}
예제 #6
0
RefPtr<SharedMemory> SharedMemory::create(void* data, size_t size, Protection protection)
{
    ASSERT(size);

    auto sendRight = makeMemoryEntry(size, toVMAddress(data), protection, MACH_PORT_NULL);
    if (!sendRight)
        return nullptr;

    auto sharedMemory(adoptRef(*new SharedMemory));
    sharedMemory->m_size = size;
    sharedMemory->m_data = nullptr;
    sharedMemory->m_port = sendRight.leakSendRight();
    sharedMemory->m_protection = protection;

    return WTFMove(sharedMemory);
}
예제 #7
0
bool SharedMemory::createHandle(Handle& handle, Protection protection)
{
    ASSERT(!handle.m_port);
    ASSERT(!handle.m_size);

    mach_vm_address_t address = toVMAddress(m_data);
    memory_object_size_t size = round_page(m_size);

    // Create a mach port that represents the shared memory.
    mach_port_t port;
    kern_return_t kr = mach_make_memory_entry_64(mach_task_self(), &size, address, machProtection(protection), &port, MACH_PORT_NULL);
    if (kr != KERN_SUCCESS)
        return false;

    handle.m_port = port;
    handle.m_size = size;

    return true;
}
예제 #8
0
PassRefPtr<SharedMemory> SharedMemory::createWithVMCopy(void* data, size_t size)
{
    ASSERT(size);

    mach_vm_address_t address;
    kern_return_t kr = mach_vm_allocate(mach_task_self(), &address, round_page(size), VM_FLAGS_ANYWHERE);
    if (kr != KERN_SUCCESS) {
        LOG_ERROR("Failed to allocate mach_vm_allocate shared memory (%zu bytes). %s (%x)", size, mach_error_string(kr), kr); 
        return 0;
    }
    
    if (data) {
        kr = mach_vm_copy(mach_task_self(), toVMAddress(data), round_page(size), address);
        if (kr != KERN_SUCCESS) {
            LOG_ERROR("Failed to vm_copy in to shared memory (%zu bytes). %s (%x)", size, mach_error_string(kr), kr); 
            mach_vm_deallocate(mach_task_self(), address, round_page(size));
            return 0;
        }
    }

    // Create a Mach port that represents the shared memory.
    mach_port_t port;
    memory_object_size_t memoryObjectSize = round_page(size);
    kr = mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, address, VM_PROT_DEFAULT, &port, MACH_PORT_NULL);

    if (kr != KERN_SUCCESS) {
        LOG_ERROR("Failed to create a mach port for shared memory. %s (%x)", mach_error_string(kr), kr);
        mach_vm_deallocate(mach_task_self(), address, round_page(size));
        return 0;
    }

    ASSERT(memoryObjectSize >= round_page(size));

    RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory));
    sharedMemory->m_size = size;
    sharedMemory->m_data = toPointer(address);
    sharedMemory->m_port = port;

    return sharedMemory.release();
}
예제 #9
0
PassRefPtr<SharedMemory> SharedMemory::createFromVMBuffer(void* data, size_t size)  
{
    ASSERT(size);
    
    // Create a Mach port that represents the shared memory.
    mach_port_t port;
    memory_object_size_t memoryObjectSize = round_page(size);
    kern_return_t kr = mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, toVMAddress(data), VM_PROT_DEFAULT | VM_PROT_IS_MASK, &port, MACH_PORT_NULL);
    
    if (kr != KERN_SUCCESS) {
        LOG_ERROR("Failed to create a mach port for shared memory. %s (%x)", mach_error_string(kr), kr);
        return 0;
    }

    ASSERT(memoryObjectSize >= round_page(size));
    if (memoryObjectSize < round_page(size)) {
        mach_port_deallocate(mach_task_self(), port);
        return 0;
    }

    RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory));
    sharedMemory->m_size = size;
    sharedMemory->m_data = data;
    sharedMemory->m_shouldVMDeallocateData = false;
    sharedMemory->m_port = port;

    return sharedMemory.release();
}