Skip to content

Commit 760b618

Browse files
make shared memory exclusive
1 parent 5ad63e7 commit 760b618

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

src/main.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ int main(int argc, char **argv) {
107107
"tcp timeout in seconds. Set to 0 to use the system defaults (not recommended).",
108108
cxxopts::value<std::size_t>()->default_value("5"))
109109
#endif
110+
("force",
111+
"Force the use of the shared memory even if it already exists. "
112+
"Do not use this option per default! "
113+
"It should only be used if the shared memory of an improperly terminated instance continues "
114+
"to exist as an orphan and is no longer used.")
110115
("h,help",
111116
"print usage")
112117
("version",
@@ -181,18 +186,25 @@ int main(int argc, char **argv) {
181186
}
182187

183188
// create shared memory object for modbus registers
184-
Modbus::shm::Shm_Mapping mapping(args["do-registers"].as<std::size_t>(),
185-
args["di-registers"].as<std::size_t>(),
186-
args["ao-registers"].as<std::size_t>(),
187-
args["ai-registers"].as<std::size_t>(),
188-
args["name-prefix"].as<std::string>());
189+
std::unique_ptr<Modbus::shm::Shm_Mapping> mapping;
190+
try {
191+
mapping = std::make_unique<Modbus::shm::Shm_Mapping>(args["do-registers"].as<std::size_t>(),
192+
args["di-registers"].as<std::size_t>(),
193+
args["ao-registers"].as<std::size_t>(),
194+
args["ai-registers"].as<std::size_t>(),
195+
args["name-prefix"].as<std::string>(),
196+
args.count("force") > 0);
197+
} catch (const std::system_error &e) {
198+
std::cerr << e.what() << std::endl;
199+
exit(EX_OSERR);
200+
}
189201

190202
// create slave
191203
std::unique_ptr<Modbus::TCP::Slave> slave;
192204
try {
193205
slave = std::make_unique<Modbus::TCP::Slave>(args["ip"].as<std::string>(),
194206
args["port"].as<uint16_t>(),
195-
mapping.get_mapping(),
207+
mapping->get_mapping(),
196208
#ifdef OS_LINUX
197209
args["tcp-timeout"].as<std::size_t>());
198210
#else

src/modbus_shm.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ Shm_Mapping::Shm_Mapping(std::size_t nb_bits,
1818
std::size_t nb_input_bits,
1919
std::size_t nb_registers,
2020
std::size_t nb_input_registers,
21-
const std::string &prefix) {
21+
const std::string &prefix,
22+
bool force) {
2223
// check argument ranges
2324
if (nb_bits > 0x10000 || !nb_bits) throw std::invalid_argument("invalid number of digital output registers.");
2425
if (nb_input_bits > 0x10000 || !nb_input_bits)
@@ -50,8 +51,11 @@ Shm_Mapping::Shm_Mapping(std::size_t nb_bits,
5051
for (std::size_t i = 0; i < reg_index_t::REG_COUNT; ++i) {
5152
auto &shm = shm_data[i];
5253

54+
int flags = O_RDWR | O_CREAT;
55+
if (!force) flags |= O_EXCL;
56+
5357
// create shm object
54-
shm.fd = shm_open(shm.name.c_str(), O_RDWR | O_CREAT, 0660);
58+
shm.fd = shm_open(shm.name.c_str(), flags, 0660);
5559
if (shm.fd < 0) {
5660
throw std::system_error(
5761
errno, std::generic_category(), "Failed to create shared memory '" + shm.name + '\'');

src/modbus_shm.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ class Shm_Mapping {
5050
* @param nb_registers number of analog output registers (AO)
5151
* @param nb_input_registers number of analog input registers (AI)
5252
* @param shm_name_prefix name prefix of the created shared memory object
53+
* @param force do not fail if the shared memory exist, but use the existing shared memory
5354
*/
5455
Shm_Mapping(std::size_t nb_bits,
5556
std::size_t nb_input_bits,
5657
std::size_t nb_registers,
5758
std::size_t nb_input_registers,
58-
const std::string &shm_name_prefix = "modbus_");
59+
const std::string &shm_name_prefix = "modbus_",
60+
bool force = false);
5961

6062
~Shm_Mapping();
6163

0 commit comments

Comments
 (0)