1 | // |
---|
2 | // SharedMemoryImpl.cpp |
---|
3 | // |
---|
4 | // $Id: //poco/1.3/Foundation/src/SharedMemory_POSIX.cpp#2 $ |
---|
5 | // |
---|
6 | // Library: Foundation |
---|
7 | // Package: Processes |
---|
8 | // Module: SharedMemoryImpl |
---|
9 | // |
---|
10 | // Copyright (c) 2007, Applied Informatics Software Engineering GmbH. |
---|
11 | // and Contributors. |
---|
12 | // |
---|
13 | // Permission is hereby granted, free of charge, to any person or organization |
---|
14 | // obtaining a copy of the software and accompanying documentation covered by |
---|
15 | // this license (the "Software") to use, reproduce, display, distribute, |
---|
16 | // execute, and transmit the Software, and to prepare derivative works of the |
---|
17 | // Software, and to permit third-parties to whom the Software is furnished to |
---|
18 | // do so, all subject to the following: |
---|
19 | // |
---|
20 | // The copyright notices in the Software and this entire statement, including |
---|
21 | // the above license grant, this restriction and the following disclaimer, |
---|
22 | // must be included in all copies of the Software, in whole or in part, and |
---|
23 | // all derivative works of the Software, unless such copies or derivative |
---|
24 | // works are solely in the form of machine-executable object code generated by |
---|
25 | // a source language processor. |
---|
26 | // |
---|
27 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
28 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
29 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT |
---|
30 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE |
---|
31 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, |
---|
32 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
---|
33 | // DEALINGS IN THE SOFTWARE. |
---|
34 | // |
---|
35 | |
---|
36 | |
---|
37 | #include "Poco/SharedMemory_POSIX.h" |
---|
38 | #include "Poco/Exception.h" |
---|
39 | #include "Poco/File.h" |
---|
40 | #include <sys/types.h> |
---|
41 | #include <sys/stat.h> |
---|
42 | #include <sys/mman.h> |
---|
43 | #include <fcntl.h> |
---|
44 | #include <unistd.h> |
---|
45 | |
---|
46 | |
---|
47 | namespace Poco { |
---|
48 | |
---|
49 | |
---|
50 | SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, SharedMemory::AccessMode mode, const void* addrHint, bool server): |
---|
51 | _size(size), |
---|
52 | _fd(-1), |
---|
53 | _address(0), |
---|
54 | _access(mode), |
---|
55 | _name("/"), |
---|
56 | _fileMapped(false), |
---|
57 | _server(server) |
---|
58 | { |
---|
59 | #if POCO_OS == POCO_OS_HPUX |
---|
60 | _name.append("tmp/"); |
---|
61 | #endif |
---|
62 | |
---|
63 | _name.append(name); |
---|
64 | |
---|
65 | int flags = O_CREAT; |
---|
66 | if (_access == SharedMemory::AM_WRITE) |
---|
67 | flags |= O_RDWR; |
---|
68 | else |
---|
69 | flags |= O_RDONLY; |
---|
70 | |
---|
71 | // open the shared memory segment |
---|
72 | _fd = ::shm_open(_name.c_str(), flags, S_IRUSR | S_IWUSR); |
---|
73 | if (_fd == -1) |
---|
74 | throw SystemException("Cannot create shared memory object", _name); |
---|
75 | |
---|
76 | // now set the correct size for the segment |
---|
77 | if (-1 == ::ftruncate(_fd, size)) |
---|
78 | { |
---|
79 | ::close(_fd); |
---|
80 | _fd = -1; |
---|
81 | ::shm_unlink(_name.c_str()); |
---|
82 | throw SystemException("Cannot resize shared memory object", _name); |
---|
83 | } |
---|
84 | map(addrHint); |
---|
85 | } |
---|
86 | |
---|
87 | |
---|
88 | SharedMemoryImpl::SharedMemoryImpl(const Poco::File& file, SharedMemory::AccessMode mode, const void* addrHint): |
---|
89 | _size(0), |
---|
90 | _fd(-1), |
---|
91 | _address(0), |
---|
92 | _access(mode), |
---|
93 | _name(file.path()), |
---|
94 | _fileMapped(true), |
---|
95 | _server(false) |
---|
96 | { |
---|
97 | if (!file.exists() || !file.isFile()) |
---|
98 | throw FileNotFoundException(file.path()); |
---|
99 | |
---|
100 | _size = file.getSize(); |
---|
101 | int flag = O_RDONLY; |
---|
102 | if (mode == SharedMemory::AM_WRITE) |
---|
103 | flag = O_RDWR; |
---|
104 | _fd = ::open(_name.c_str(), flag); |
---|
105 | if (-1 == _fd) |
---|
106 | throw OpenFileException("Cannot open memory mapped file", _name); |
---|
107 | |
---|
108 | map(addrHint); |
---|
109 | } |
---|
110 | |
---|
111 | |
---|
112 | SharedMemoryImpl::~SharedMemoryImpl() |
---|
113 | { |
---|
114 | unmap(); |
---|
115 | close(); |
---|
116 | } |
---|
117 | |
---|
118 | |
---|
119 | void SharedMemoryImpl::map(const void* addrHint) |
---|
120 | { |
---|
121 | int access = PROT_READ; |
---|
122 | if (_access == SharedMemory::AM_WRITE) |
---|
123 | access |= PROT_WRITE; |
---|
124 | |
---|
125 | void* addr = ::mmap(const_cast<void*>(addrHint), _size, access, MAP_SHARED, _fd, 0); |
---|
126 | if (addr == MAP_FAILED) |
---|
127 | throw SystemException("Cannot map file into shared memory", _name); |
---|
128 | |
---|
129 | _address = static_cast<char*>(addr); |
---|
130 | } |
---|
131 | |
---|
132 | |
---|
133 | void SharedMemoryImpl::unmap() |
---|
134 | { |
---|
135 | if (_address) |
---|
136 | { |
---|
137 | ::munmap(_address, _size); |
---|
138 | } |
---|
139 | } |
---|
140 | |
---|
141 | |
---|
142 | void SharedMemoryImpl::close() |
---|
143 | { |
---|
144 | if (_fd != -1) |
---|
145 | { |
---|
146 | ::close(_fd); |
---|
147 | _fd = -1; |
---|
148 | } |
---|
149 | if (!_fileMapped && _server) |
---|
150 | { |
---|
151 | ::shm_unlink(_name.c_str()); |
---|
152 | } |
---|
153 | } |
---|
154 | |
---|
155 | |
---|
156 | } // namespace Poco |
---|