Пример #1
0
Optional<Reflector> Reflector::create(size_t size)
{
    static const char *path = "reflector.shm";
    FileDescriptor fd;
    void *lower = nullptr;
    void *upper = nullptr;
    void *both = nullptr;
    int sts = -1;

    if ((size == 0) || (size % 4096)) {
        return Optional<Reflector>();
    }

    fd.reset(shm_open(path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR));
    if (fd.empty()) {
        return Optional<Reflector>();
    }

    sts = shm_unlink(path);
    if (sts < 0) {
        return Optional<Reflector>();
    }

    sts = ftruncate(fd.get(), size);
    if (sts < 0) {
        return Optional<Reflector>();
    }
    
    both = mmap(nullptr, size * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
    if (both == MAP_FAILED) {
        return Optional<Reflector>();
    }

    lower = mremap(both, size * 2, size, 0);
    if (lower == MAP_FAILED) {
        sts = munmap(both, size * 2);
        assert(sts >= 0);
        return Optional<Reflector>();
    }
    else if (lower != both) {
        sts = munmap(lower, size);
        assert(sts);
        return Optional<Reflector>();
    }

    upper = static_cast<uint8_t*>(lower) + size;
    upper = mmap(upper, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd.get(), 0);
    if (upper == MAP_FAILED) {
        sts = munmap(lower, size);
        assert(sts >= 0);
        return Optional<Reflector>();
    }

    return Optional<Reflector>(Reflector(std::move(fd), lower, size));
}
Пример #2
0
MMap::MMap (const FileDescriptor& fd, bool const sequential)
    :
    size   (fd.size()),
    ptr    (mmap (NULL, size, PROT_READ|PROT_WRITE,
                 MAP_SHARED|MAP_NORESERVE, fd.get(), 0)),
    mapped (ptr != GU_MAP_FAILED)
{
    if (!mapped)
    {
        gu_throw_error(errno) << "mmap() on '" << fd.name()
                              << "' failed";
    }

#if !defined(__sun__) && !defined(__APPLE__) && !defined(__FreeBSD__)
    /* Solaris, Darwin, and FreeBSD do not have MADV_DONTFORK */
    if (posix_madvise (ptr, size, MADV_DONTFORK))
    {
        int const err(errno);
        log_warn << "Failed to set MADV_DONTFORK on " << fd.name()
                 << ": " << err << " (" << strerror(err) << ")";
    }
#endif

    /* benefits are questionable */
    if (sequential && posix_madvise (ptr, size, MADV_SEQUENTIAL))
    {
        int const err(errno);
        log_warn << "Failed to set MADV_SEQUENTIAL on " << fd.name()
                 << ": " << err << " (" << strerror(err) << ")";
    }

    log_debug << "Memory mapped: " << ptr << " (" << size << " bytes)";
}