bool SharedMemory::createHandle(Handle& handle, Protection) { ASSERT_ARG(handle, !handle.m_size); ASSERT_ARG(handle, handle.isNull()); // FIXME: Handle the case where the passed Protection is ReadOnly. // See https://bugs.webkit.org/show_bug.cgi?id=131542. int duplicatedHandle; while ((duplicatedHandle = dup(m_fileDescriptor)) == -1) { if (errno != EINTR) { ASSERT_NOT_REACHED(); return false; } } while (fcntl(duplicatedHandle, F_SETFD, FD_CLOEXEC) == -1) { if (errno != EINTR) { ASSERT_NOT_REACHED(); closeWithRetry(duplicatedHandle); return false; } } handle.m_fileDescriptor = duplicatedHandle; handle.m_size = m_size; return true; }
SharedMemory::~SharedMemory() { if (m_isWrappingMap) return; munmap(m_data, m_size); if (m_fileDescriptor) closeWithRetry(m_fileDescriptor.value()); }
RefPtr<SharedMemory> SharedMemory::create(void* address, size_t size, Protection protection) { CString tempName; int fileDescriptor = -1; for (int tries = 0; fileDescriptor == -1 && tries < 10; ++tries) { String name = String("/WK2SharedMemory.") + String::number(static_cast<unsigned>(WTF::randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))); tempName = name.utf8(); do { fileDescriptor = shm_open(tempName.data(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); } while (fileDescriptor == -1 && errno == EINTR); } if (fileDescriptor == -1) { WTFLogAlways("Failed to create shared memory file %s: %s", tempName.data(), strerror(errno)); return 0; } while (ftruncate(fileDescriptor, size) == -1) { if (errno != EINTR) { closeWithRetry(fileDescriptor); shm_unlink(tempName.data()); return 0; } } void* data = mmap(address, size, accessModeMMap(protection), MAP_SHARED, fileDescriptor, 0); if (data == MAP_FAILED) { closeWithRetry(fileDescriptor); shm_unlink(tempName.data()); return 0; } shm_unlink(tempName.data()); RefPtr<SharedMemory> instance = adoptRef(new SharedMemory()); instance->m_data = data; instance->m_fileDescriptor = fileDescriptor; instance->m_size = size; return instance.release(); }
RefPtr<SharedMemory> SharedMemory::map(const Handle& handle, Protection protection) { ASSERT(!handle.isNull()); int fd = handle.m_attachment.releaseFileDescriptor(); void* data = mmap(0, handle.m_attachment.size(), accessModeMMap(protection), MAP_SHARED, fd, 0); closeWithRetry(fd); if (data == MAP_FAILED) return nullptr; RefPtr<SharedMemory> instance = wrapMap(data, handle.m_attachment.size(), -1); instance->m_fileDescriptor = std::nullopt; instance->m_isWrappingMap = false; return instance; }
void Connection::platformInvalidate() { // In GTK+ platform the socket is closed by the work queue. #if !PLATFORM(GTK) if (m_socketDescriptor != -1) closeWithRetry(m_socketDescriptor); #endif if (!m_isConnected) return; #if PLATFORM(GTK) || PLATFORM(EFL) m_connectionQueue->unregisterSocketEventHandler(m_socketDescriptor); #endif m_socketDescriptor = -1; m_isConnected = false; }
void SharedMemory::Handle::clear() { if (!isNull()) closeWithRetry(m_fileDescriptor); }
SharedMemory::~SharedMemory() { munmap(m_data, m_size); closeWithRetry(m_fileDescriptor); }