zaela-Server/common/ipc_mutex.cpp

137 lines
2.9 KiB
C++
Raw Permalink Normal View History

2013-05-09 10:44:08 -04:00
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
2013-05-09 10:44:08 -04:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
2013-05-09 10:44:08 -04:00
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
2013-05-09 10:44:08 -04:00
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2013-05-09 10:44:08 -04:00
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
2013-02-17 11:35:50 -08:00
#include "ipc_mutex.h"
#ifdef _WINDOWS
#define WIN32_LEAN_AND_MEAN
2013-02-17 11:35:50 -08:00
#include <Windows.h>
#undef WIN32_LEAN_AND_MEAN
2013-02-17 11:35:50 -08:00
#else
#include <sys/types.h>
2013-02-17 11:35:50 -08:00
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
2013-02-17 11:35:50 -08:00
#endif
#include "types.h"
#include "eqemu_exception.h"
2016-05-24 23:49:25 -07:00
#include "eqemu_config.h"
2013-02-17 11:35:50 -08:00
namespace EQ {
2013-05-09 10:44:08 -04:00
struct IPCMutex::Implementation {
2013-02-17 11:35:50 -08:00
#ifdef _WINDOWS
2013-05-09 10:44:08 -04:00
HANDLE mut_;
2013-02-17 11:35:50 -08:00
#else
2013-05-09 10:44:08 -04:00
int fd_;
2013-02-17 11:35:50 -08:00
#endif
2013-05-09 10:44:08 -04:00
};
2013-02-17 11:35:50 -08:00
2013-05-09 10:44:08 -04:00
IPCMutex::IPCMutex(std::string name) : locked_(false) {
imp_ = new Implementation;
2013-02-17 11:35:50 -08:00
#ifdef _WINDOWS
2016-05-24 23:49:25 -07:00
auto Config = EQEmuConfig::get();
2016-05-20 21:03:34 -05:00
std::string final_name = Config->SharedMemDir + "EQEmuMutex_";
2013-05-09 10:44:08 -04:00
final_name += name;
2013-02-17 11:35:50 -08:00
2013-05-09 10:44:08 -04:00
imp_->mut_ = CreateMutex(nullptr,
FALSE,
final_name.c_str());
2013-02-17 11:35:50 -08:00
2013-05-09 10:44:08 -04:00
if(!imp_->mut_) {
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
}
2013-02-17 11:35:50 -08:00
#else
auto Config = EQEmuConfig::get();
2016-05-20 21:03:34 -05:00
std::string final_name = Config->SharedMemDir + name;
2013-05-09 10:44:08 -04:00
final_name += ".lock";
#ifdef __DARWIN
#if __DARWIN_C_LEVEL < 200809L
2013-05-09 10:44:08 -04:00
imp_->fd_ = open(final_name.c_str(),
O_RDWR | O_CREAT,
2013-05-09 10:44:08 -04:00
S_IRUSR | S_IWUSR);
#else
imp_->fd_ = open(final_name.c_str(),
O_RDWR | O_CREAT | O_CLOEXEC,
S_IRUSR | S_IWUSR);
#endif
#else
imp_->fd_ = open(final_name.c_str(),
O_RDWR | O_CREAT | O_CLOEXEC,
S_IRUSR | S_IWUSR);
#endif
2013-05-09 10:44:08 -04:00
if(imp_->fd_ == -1) {
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
}
2013-02-17 11:35:50 -08:00
#endif
2013-05-09 10:44:08 -04:00
}
2013-02-17 11:35:50 -08:00
2013-05-09 10:44:08 -04:00
IPCMutex::~IPCMutex() {
2013-02-17 11:35:50 -08:00
#ifdef _WINDOWS
2013-05-09 10:44:08 -04:00
if(locked_) {
ReleaseMutex(imp_->mut_);
}
CloseHandle(imp_->mut_);
2013-02-17 11:35:50 -08:00
#else
2013-05-09 10:44:08 -04:00
if(locked_) {
lockf(imp_->fd_, F_ULOCK, 0);
}
close(imp_->fd_);
2013-02-17 11:35:50 -08:00
#endif
2013-05-09 10:44:08 -04:00
delete imp_;
}
2013-02-17 11:35:50 -08:00
2013-05-09 10:44:08 -04:00
bool IPCMutex::Lock() {
if(locked_) {
return false;
}
2013-02-17 11:35:50 -08:00
#ifdef _WINDOWS
2013-05-09 10:44:08 -04:00
DWORD wait_result = WaitForSingleObject(imp_->mut_, INFINITE);
if(wait_result != WAIT_OBJECT_0) {
return false;
}
2013-02-17 11:35:50 -08:00
#else
2013-05-09 10:44:08 -04:00
if(lockf(imp_->fd_, F_LOCK, 0) != 0) {
return false;
}
2013-02-17 11:35:50 -08:00
#endif
2013-05-09 10:44:08 -04:00
locked_ = true;
return true;
}
bool IPCMutex::Unlock() {
if(!locked_) {
return false;
}
2013-02-17 11:35:50 -08:00
#ifdef _WINDOWS
2013-05-09 10:44:08 -04:00
if(!ReleaseMutex(imp_->mut_)) {
return false;
}
2013-02-17 11:35:50 -08:00
#else
2013-05-09 10:44:08 -04:00
if(lockf(imp_->fd_, F_ULOCK, 0) != 0) {
return false;
}
2013-02-17 11:35:50 -08:00
#endif
2013-05-09 10:44:08 -04:00
locked_ = false;
return true;
}
2013-02-17 11:35:50 -08:00
}