1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-09-03 23:42:03 +03:00
Files
mariadb-columnstore-engine/versioning/BRM/brmshmimpl.cpp
Patrick LeBlanc 4215a47b5c MCOL-520. More untested changes.
Went down the list in shmkeys.h, added sane error msgs on perms
errors accessing rest of the shmsegs there.
Realized we probably do need 666 to the shmsegs.
Also deleted a little dead code that was copy-pasted everywhere.
2018-10-04 14:25:01 -05:00

239 lines
6.1 KiB
C++

/* Copyright (C) 2014 InfiniDB, Inc.
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/*****************************************************************************
* $Id$
*
****************************************************************************/
#include <iostream>
#include <string>
//#define NDEBUG
#include <cassert>
#include <algorithm>
using namespace std;
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/version.hpp>
namespace bi = boost::interprocess;
#include "shmkeys.h"
#include "brmshmimpl.h"
#include "brmtypes.h"
#include "installdir.h"
namespace BRM
{
BRMShmImpl::BRMShmImpl(unsigned key, off_t size, bool readOnly) :
fKey(key), fSize(size), fReadOnly(readOnly)
{
string keyName = ShmKeys::keyToName(fKey);
if (fSize == 0)
{
unsigned tries = 0;
again:
try
{
bi::shared_memory_object shm(bi::open_only, keyName.c_str(), bi::read_write);
off_t curSize = 0;
#ifdef _MSC_VER
bi::offset_t tmp = 0;
shm.get_size(tmp);
curSize = static_cast<off_t>(tmp);
#else
shm.get_size(curSize);
#endif
if (curSize == 0) throw
bi::interprocess_exception("shm size is zero");
}
catch (bi::interprocess_exception&)
{
if (++tries > 10)
{
log("BRMShmImpl::BRMShmImpl(): retrying on size==0");
throw;
}
cerr << "BRMShmImpl::BRMShmImpl(): retrying on size==0" << endl;
usleep(500 * 1000);
goto again;
}
}
try
{
bi::permissions perms;
perms.set_unrestricted();
bi::shared_memory_object shm(bi::create_only, keyName.c_str(), bi::read_write, perms);
idbassert(fSize > 0);
shm.truncate(fSize);
fShmobj.swap(shm);
}
catch (bi::interprocess_exception &b)
{
if (b.get_error_code() != bi::already_exists_error) {
ostringstream o;
o << "BRM caught an exception creating a shared memory segment: " << b.what();
log(o.str());
throw;
}
bi::shared_memory_object *shm = NULL;
try {
shm = new bi::shared_memory_object(bi::open_only, keyName.c_str(), bi::read_write);
}
catch (exception &e) {
ostringstream o;
o << "BRM caught an exception attaching to a shared memory segment (" << keyName << "): " << b.what();
log(o.str());
throw;
}
off_t curSize = 0;
#ifdef _MSC_VER
bi::offset_t tmp = 0;
shm->get_size(tmp);
curSize = static_cast<off_t>(tmp);
#else
shm->get_size(curSize);
#endif
idbassert(curSize > 0);
idbassert(curSize >= fSize);
fShmobj.swap(*shm);
delete shm;
fSize = curSize;
}
if (fReadOnly)
{
bi::mapped_region ro_region(fShmobj, bi::read_only);
fMapreg.swap(ro_region);
}
else
{
bi::mapped_region region(fShmobj, bi::read_write);
fMapreg.swap(region);
}
}
int BRMShmImpl::grow(unsigned newKey, off_t newSize)
{
idbassert(newKey != fKey);
idbassert(newSize >= fSize);
string oldName = fShmobj.get_name();
string keyName = ShmKeys::keyToName(newKey);
bi::permissions perms;
perms.set_unrestricted();
bi::shared_memory_object shm(bi::create_only, keyName.c_str(), bi::read_write, perms);
shm.truncate(newSize);
bi::mapped_region region(shm, bi::read_write);
//Copy old data into new region
memcpy(region.get_address(), fMapreg.get_address(), fSize);
//clear new region
//make some versions of gcc happier...
memset(reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(region.get_address()) + fSize), 0, newSize - fSize);
fShmobj.swap(shm);
fMapreg.swap(region);
if (!oldName.empty()) bi::shared_memory_object::remove(oldName.c_str());
fKey = newKey;
fSize = newSize;
if (fReadOnly)
{
bi::mapped_region ro_region(fShmobj, bi::read_only);
fMapreg.swap(ro_region);
}
return 0;
}
int BRMShmImpl::clear(unsigned newKey, off_t newSize)
{
idbassert(newKey != fKey);
string oldName = fShmobj.get_name();
string keyName = ShmKeys::keyToName(newKey);
bi::permissions perms;
perms.set_unrestricted();
bi::shared_memory_object shm(bi::create_only, keyName.c_str(), bi::read_write, perms);
shm.truncate(newSize);
bi::mapped_region region(shm, bi::read_write);
//clear new region
memset(region.get_address(), 0, newSize);
fShmobj.swap(shm);
fMapreg.swap(region);
if (!oldName.empty()) bi::shared_memory_object::remove(oldName.c_str());
fKey = newKey;
fSize = newSize;
if (fReadOnly)
{
bi::mapped_region ro_region(fShmobj, bi::read_only);
fMapreg.swap(ro_region);
}
return 0;
}
void BRMShmImpl::setReadOnly()
{
if (fReadOnly) return;
bi::mapped_region ro_region(fShmobj, bi::read_only);
fMapreg.swap(ro_region);
fReadOnly = true;
}
void BRMShmImpl::swap(BRMShmImpl& rhs)
{
fShmobj.swap(rhs.fShmobj);
fMapreg.swap(rhs.fMapreg);
std::swap(fKey, rhs.fKey);
std::swap(fSize, rhs.fSize);
std::swap(fReadOnly, rhs.fReadOnly);
}
void BRMShmImpl::destroy()
{
string oldName = fShmobj.get_name();
if (!oldName.empty()) bi::shared_memory_object::remove(oldName.c_str());
}
} //namespace
// vim:ts=4 sw=4: