diff --git a/fairmq/shmem/UnmanagedRegion.h b/fairmq/shmem/UnmanagedRegion.h index 7ecf5f29..9b81dba5 100644 --- a/fairmq/shmem/UnmanagedRegion.h +++ b/fairmq/shmem/UnmanagedRegion.h @@ -99,16 +99,25 @@ struct UnmanagedRegion fRegion = mapped_region(fFileMapping, read_write, 0, size, 0, cfg.creationFlags); } else { try { - fShmemObject = shared_memory_object(open_or_create, fName.c_str(), read_write); - if (size != 0) { + // if opening fails, create + try { + fShmemObject = shared_memory_object(open_only, fName.c_str(), read_write); + } catch (interprocess_exception& e) { + LOG(debug) << "Could not open " << (remote ? "remote" : "local") << " shared_memory_object for region id '" << cfg.id.value() << "': " << e.what() << ", creating..."; + fShmemObject = shared_memory_object(create_only, fName.c_str(), read_write); fShmemObject.truncate(size); } } catch (interprocess_exception& e) { LOG(error) << "Failed " << (remote ? "opening" : "creating") << " shared_memory_object for region id '" << cfg.id.value() << "': " << e.what(); throw; } + try { fRegion = mapped_region(fShmemObject, read_write, 0, 0, 0, cfg.creationFlags); + if (size != 0 && size != fRegion.get_size()) { + LOG(error) << "Created/opened region size (" << fRegion.get_size() << ") does not match configured size (" << size << ")"; + throw TransportError(tools::ToString("Created/opened region size (", fRegion.get_size(), ") does not match configured size (", size, ")")); + } } catch (interprocess_exception& e) { LOG(error) << "Failed mapping shared_memory_object for region id '" << cfg.id.value() << "': " << e.what(); throw; diff --git a/test/region/_region.cxx b/test/region/_region.cxx index b6947e3f..c76eb1e3 100644 --- a/test/region/_region.cxx +++ b/test/region/_region.cxx @@ -25,6 +25,26 @@ namespace using namespace std; using namespace fair::mq; +void RegionsSizeMismatch() +{ + size_t session = tools::UuidHash(); + + ProgOptions config; + config.SetProperty("session", to_string(session)); + config.SetProperty("shm-segment-size", 100000000); + + auto factory = TransportFactory::CreateTransportFactory("shmem", tools::Uuid(), &config); + + fair::mq::RegionConfig rCfg; + rCfg.id = 10; + UnmanagedRegionPtr region1 = nullptr; + ASSERT_NO_THROW(region1 = factory->CreateUnmanagedRegion(10000, [](void*, size_t, void*) {}, rCfg)); + ASSERT_NE(region1, nullptr); + UnmanagedRegionPtr region2 = nullptr; + ASSERT_THROW(region2 = factory->CreateUnmanagedRegion(16000, [](void*, size_t, void*) {}, rCfg), fair::mq::TransportError); + ASSERT_EQ(region2, nullptr); +} + void RegionsCache(const string& transport, const string& address) { size_t session1 = tools::UuidHash(); @@ -226,6 +246,11 @@ void RegionCallbacks(const string& transport, const string& _address) LOG(info) << "2 done."; } +TEST(RegionsSizeMismatch, shmem) +{ + RegionsSizeMismatch(); +} + TEST(Cache, zeromq) { RegionsCache("zeromq", "ipc://test_region_cache");