IPCMutex::IPCMutex(std::string name) : locked_(false) { imp_ = new Implementation; #ifdef _WINDOWS std::string final_name = "EQEmuMutex_"; final_name += name; imp_->mut_ = CreateMutex(NULL, FALSE, final_name.c_str()); if(!imp_->mut_) { EQ_EXCEPT("IPC Mutex", "Could not create mutex."); } #else std::string final_name = name; final_name += ".lock"; imp_->fd_ = open(final_name.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); if(imp_->fd_ == -1) { EQ_EXCEPT("IPC Mutex", "Could not create mutex."); } #endif }
MemoryMappedFile::MemoryMappedFile(std::string filename, uint32 size) : filename_(filename), size_(size) { imp_ = new Implementation; #ifdef _WINDOWS DWORD total_size = size + sizeof(shared_memory_struct); HANDLE file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, 0, nullptr); if(file == INVALID_HANDLE_VALUE) { EQ_EXCEPT("Shared Memory", "Could not open a file for this shared memory segment."); } imp_->mapped_object_ = CreateFileMapping(file, nullptr, PAGE_READWRITE, 0, total_size, filename.c_str()); if(!imp_->mapped_object_) { EQ_EXCEPT("Shared Memory", "Could not create a file mapping for this shared memory file."); } memory_ = reinterpret_cast<shared_memory_struct*>(MapViewOfFile(imp_->mapped_object_, FILE_MAP_ALL_ACCESS, 0, 0, total_size)); if(!memory_) { EQ_EXCEPT("Shared Memory", "Could not map a view of the shared memory file."); } #else size_t total_size = size + sizeof(shared_memory_struct); imp_->fd_ = open(filename.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if(imp_->fd_ == -1) { EQ_EXCEPT("Shared Memory", "Could not open a file for this shared memory segment."); } if(ftruncate(imp_->fd_, total_size) == -1) { EQ_EXCEPT("Shared Memory", "Could not set file size for this shared memory segment."); } memory_ = reinterpret_cast<shared_memory_struct*>( mmap(nullptr, total_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, imp_->fd_, 0)); if(memory_ == MAP_FAILED) { EQ_EXCEPT("Shared Memory", "Could not create a file mapping for this shared memory file."); } #endif }
void LoadSpells(SharedDatabase *database) { EQEmu::IPCMutex mutex("spells"); mutex.Lock(); int records = database->GetMaxSpellID() + 1; if(records == 0) { EQ_EXCEPT("Shared Memory", "Unable to get any spells from the database."); } uint32 size = records * sizeof(SPDat_Spell_Struct); EQEmu::MemoryMappedFile mmf("shared/spells", size); mmf.ZeroFile(); void *ptr = mmf.Get(); database->LoadSpells(ptr, records); mutex.Unlock(); }
void LoadBaseData(SharedDatabase *database) { EQEmu::IPCMutex mutex("base_data"); mutex.Lock(); int records = (database->GetMaxBaseDataLevel() + 1); if(records == 0) { EQ_EXCEPT("Shared Memory", "Unable to get base data from the database."); } uint32 size = records * 16 * sizeof(BaseDataStruct); EQEmu::MemoryMappedFile mmf("shared/base_data", size); mmf.ZeroFile(); void *ptr = mmf.Get(); database->LoadBaseData(ptr, records); mutex.Unlock(); }
void LoadFactions(SharedDatabase *database) { EQEmu::IPCMutex mutex("faction"); mutex.Lock(); uint32 lists = 0; uint32 max_list = 0; database->GetFactionListInfo(lists, max_list); if(lists == 0) { EQ_EXCEPT("Shared Memory", "Unable to get any factions from the database."); } uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<NPCFactionList>::estimated_size(lists, max_list)); EQEmu::MemoryMappedFile mmf("shared/faction", size); mmf.ZeroFile(); void *ptr = mmf.Get(); database->LoadNPCFactionLists(ptr, size, lists, max_list); mutex.Unlock(); }
void LoadItems(SharedDatabase *database) { EQEmu::IPCMutex mutex("items"); mutex.Lock(); int32 items = -1; uint32 max_item = 0; database->GetItemsCount(items, max_item); if(items == -1) { EQ_EXCEPT("Shared Memory", "Unable to get any items from the database."); } uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<Item_Struct>::estimated_size(items, max_item)); EQEmu::MemoryMappedFile mmf("shared/items", size); mmf.ZeroFile(); void *ptr = mmf.Get(); database->LoadItems(ptr, size, items, max_item); mutex.Unlock(); }