1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Make usage of boost::interprocess optional

If shared memory allocation failed on client server will be started without shared memory option.
Only downside of this is that server wouldn't be able to fallback to random port if default is busy.
This commit is contained in:
Arseniy Shestakov 2017-05-31 07:13:24 +03:00
parent cc163c4e05
commit c7e7a4d7be
2 changed files with 49 additions and 21 deletions

View File

@ -963,10 +963,13 @@ void CServerHandler::waitForServer()
th.update();
#ifndef VCMI_ANDROID
intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex);
while(!shared->sr->ready)
if(shared)
{
shared->sr->cond.wait(slock);
intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex);
while(!shared->sr->ready)
{
shared->sr->cond.wait(slock);
}
}
#else
logNetwork->infoStream() << "waiting for server";
@ -985,9 +988,12 @@ void CServerHandler::waitForServer()
CConnection * CServerHandler::connectToServer()
{
#ifndef VCMI_ANDROID
if(!shared->sr->ready)
waitForServer();
port = boost::lexical_cast<std::string>(shared->sr->port);
if(shared)
{
if(!shared->sr->ready)
waitForServer();
port = boost::lexical_cast<std::string>(shared->sr->port);
}
#else
waitForServer();
#endif
@ -1013,6 +1019,9 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
verbose = true;
#ifndef VCMI_ANDROID
if(DO_NOT_START_SERVER)
return;
boost::interprocess::shared_memory_object::remove("vcmi_memory"); //if the application has previously crashed, the memory may not have been removed. to avoid problems - try to destroy it
try
{
@ -1020,6 +1029,7 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
}
catch(...)
{
vstd::clear_pointer(shared);
logNetwork->error("Cannot open interprocess memory.");
handleException();
throw;
@ -1038,7 +1048,12 @@ void CServerHandler::callServer()
#ifndef VCMI_ANDROID
setThreadName("CServerHandler::callServer");
const std::string logName = (VCMIDirs::get().userCachePath() / "server_log.txt").string();
const std::string comm = VCMIDirs::get().serverPath().string() + " --port=" + port + " > \"" + logName + '\"';
const std::string comm = VCMIDirs::get().serverPath().string()
+ " --port=" + port
+ " --run-by-client"
+ (shared ? " --use-shm" : "")
+ " > \"" + logName + '\"';
int result = std::system(comm.c_str());
if (result == 0)
{

View File

@ -339,6 +339,11 @@ CVCMIServer::CVCMIServer()
catch(...)
{
logNetwork->info("Port %d is busy, trying to use random port instead", port);
if(cmdLineOptions.count("run-by-client") && !cmdLineOptions.count("use-shm"))
{
logNetwork->error("Cant pass port number to client without shared memory!", port);
exit(0);
}
acceptor = new TAcceptor(*io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
port = acceptor->local_endpoint().port();
}
@ -422,19 +427,22 @@ void CVCMIServer::start()
#ifndef VCMI_ANDROID
ServerReady *sr = nullptr;
intpr::mapped_region *mr;
try
if(cmdLineOptions.count("use-shm"))
{
intpr::shared_memory_object smo(intpr::open_only,"vcmi_memory",intpr::read_write);
smo.truncate(sizeof(ServerReady));
mr = new intpr::mapped_region(smo,intpr::read_write);
sr = reinterpret_cast<ServerReady*>(mr->get_address());
}
catch(...)
{
intpr::shared_memory_object smo(intpr::create_only,"vcmi_memory",intpr::read_write);
smo.truncate(sizeof(ServerReady));
mr = new intpr::mapped_region(smo,intpr::read_write);
sr = new(mr->get_address())ServerReady();
try
{
intpr::shared_memory_object smo(intpr::open_only,"vcmi_memory",intpr::read_write);
smo.truncate(sizeof(ServerReady));
mr = new intpr::mapped_region(smo,intpr::read_write);
sr = reinterpret_cast<ServerReady*>(mr->get_address());
}
catch(...)
{
intpr::shared_memory_object smo(intpr::create_only,"vcmi_memory",intpr::read_write);
smo.truncate(sizeof(ServerReady));
mr = new intpr::mapped_region(smo,intpr::read_write);
sr = new(mr->get_address())ServerReady();
}
}
#endif
@ -452,8 +460,11 @@ void CVCMIServer::start()
logNetwork->info("Sending server ready message to client");
}
#else
sr->setToTrueAndNotify(port);
delete mr;
if(cmdLineOptions.count("use-shm"))
{
sr->setToTrueAndNotify(port);
delete mr;
}
#endif
acc.join();
@ -545,6 +556,8 @@ static void handleCommandOptions(int argc, char *argv[])
opts.add_options()
("help,h", "display help and exit")
("version,v", "display version information and exit")
("run-by-client", "indicate that server launched by client on same machine")
("use-shm", "enable usage of shared memory")
("port", po::value<ui16>(), "port at which server will listen to connections from client")
("resultsFile", po::value<std::string>()->default_value("./results.txt"), "file to which the battle result will be appended. Used only in the DUEL mode.");