File size: 2,056 Bytes
9560f9f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

#include <string>
#include <utility>

#include "libipc/shm.h"

#include "libipc/utility/pimpl.h"
#include "libipc/memory/resource.h"

namespace ipc {
namespace shm {

class handle::handle_ : public pimpl<handle_> {
public:
    shm::id_t id_ = nullptr;
    void*     m_  = nullptr;

    ipc::string n_;
    std::size_t s_ = 0;
};

handle::handle()
    : p_(p_->make()) {
}

handle::handle(char const * name, std::size_t size, unsigned mode)
    : handle() {
    acquire(name, size, mode);
}

handle::handle(handle&& rhs)
    : handle() {
    swap(rhs);
}

handle::~handle() {
    release();
    p_->clear();
}

void handle::swap(handle& rhs) {
    std::swap(p_, rhs.p_);
}

handle& handle::operator=(handle rhs) {
    swap(rhs);
    return *this;
}

bool handle::valid() const noexcept {
    return impl(p_)->m_ != nullptr;
}

std::size_t handle::size() const noexcept {
    return impl(p_)->s_;
}

char const * handle::name() const noexcept {
    return impl(p_)->n_.c_str();
}

std::int32_t handle::ref() const noexcept {
    return shm::get_ref(impl(p_)->id_);
}

void handle::sub_ref() noexcept {
    shm::sub_ref(impl(p_)->id_);
}

bool handle::acquire(char const * name, std::size_t size, unsigned mode) {
    release();
    impl(p_)->id_ = shm::acquire((impl(p_)->n_ = name).c_str(), size, mode);
    impl(p_)->m_  = shm::get_mem(impl(p_)->id_, &(impl(p_)->s_));
    return valid();
}

std::int32_t handle::release() {
    if (impl(p_)->id_ == nullptr) return -1;
    return shm::release(detach());
}

void* handle::get() const {
    return impl(p_)->m_;
}

void handle::attach(id_t id) {
    if (id == nullptr) return;
    release();
    impl(p_)->id_ = id;
    impl(p_)->m_  = shm::get_mem(impl(p_)->id_, &(impl(p_)->s_));
}

id_t handle::detach() {
    auto old = impl(p_)->id_;
    impl(p_)->id_ = nullptr;
    impl(p_)->m_  = nullptr;
    impl(p_)->s_  = 0;
    impl(p_)->n_.clear();
    return old;
}

} // namespace shm
} // namespace ipc