diff options
Diffstat (limited to 'indra/llplugin/llpluginsharedmemory.cpp')
-rw-r--r-- | indra/llplugin/llpluginsharedmemory.cpp | 1004 |
1 files changed, 502 insertions, 502 deletions
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp index e6c43f5fcc..a10d251069 100644 --- a/indra/llplugin/llpluginsharedmemory.cpp +++ b/indra/llplugin/llpluginsharedmemory.cpp @@ -1,502 +1,502 @@ -/**
- * @file llpluginsharedmemory.cpp
- * LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
- *
- * @cond
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-
-#include "linden_common.h"
-
-#include "llpluginsharedmemory.h"
-
-// on Mac and Linux, we use the native shm_open/mmap interface by using
-// #define USE_SHM_OPEN_SHARED_MEMORY 1
-// in the appropriate sections below.
-
-// For Windows, use:
-// #define USE_WIN32_SHARED_MEMORY 1
-
-// If we ever want to fall back to the apr implementation for a platform, use:
-// #define USE_APR_SHARED_MEMORY 1
-
-#if LL_WINDOWS
-// #define USE_APR_SHARED_MEMORY 1
- #define USE_WIN32_SHARED_MEMORY 1
-#elif LL_DARWIN
- #define USE_SHM_OPEN_SHARED_MEMORY 1
-#elif LL_LINUX
- #define USE_SHM_OPEN_SHARED_MEMORY 1
-#endif
-
-
-// FIXME: This path thing is evil and unacceptable.
-#if LL_WINDOWS
- #define APR_SHARED_MEMORY_PREFIX_STRING "C:\\LLPlugin_"
- // Apparnently using the "Global\\" prefix here only works from administrative accounts under Vista.
- // Other options I've seen referenced are "Local\\" and "Session\\".
- #define WIN32_SHARED_MEMORY_PREFIX_STRING "Local\\LL_"
-#else
- // mac and linux
- #define APR_SHARED_MEMORY_PREFIX_STRING "/tmp/LLPlugin_"
- #define SHM_OPEN_SHARED_MEMORY_PREFIX_STRING "/LL"
-#endif
-
-#if USE_APR_SHARED_MEMORY
- #include "llapr.h"
- #include "apr_shm.h"
-#elif USE_SHM_OPEN_SHARED_MEMORY
- #include <sys/fcntl.h>
- #include <sys/mman.h>
- #include <errno.h>
-#elif USE_WIN32_SHARED_MEMORY
-#include <windows.h>
-#endif // USE_APR_SHARED_MEMORY
-
-
-int LLPluginSharedMemory::sSegmentNumber = 0;
-
-std::string LLPluginSharedMemory::createName(void)
-{
- std::stringstream newname;
-
-#if LL_WINDOWS
- newname << GetCurrentProcessId();
-#else // LL_WINDOWS
- newname << getpid();
-#endif // LL_WINDOWS
-
- newname << "_" << sSegmentNumber++;
-
- return newname.str();
-}
-
-/**
- * @brief LLPluginSharedMemoryImpl is the platform-dependent implementation of LLPluginSharedMemory. TODO:DOC is this necessary/sufficient? kinda obvious.
- *
- */
-class LLPluginSharedMemoryPlatformImpl
-{
-public:
- LLPluginSharedMemoryPlatformImpl();
- ~LLPluginSharedMemoryPlatformImpl();
-
-#if USE_APR_SHARED_MEMORY
- apr_shm_t* mAprSharedMemory;
-#elif USE_SHM_OPEN_SHARED_MEMORY
- int mSharedMemoryFD;
-#elif USE_WIN32_SHARED_MEMORY
- HANDLE mMapFile;
-#endif
-
-};
-
-/**
- * Constructor. Creates a shared memory segment.
- */
-LLPluginSharedMemory::LLPluginSharedMemory()
-{
- mSize = 0;
- mMappedAddress = NULL;
- mNeedsDestroy = false;
-
- mImpl = new LLPluginSharedMemoryPlatformImpl;
-}
-
-/**
- * Destructor. Uses destroy() and detach() to ensure shared memory segment is cleaned up.
- */
-LLPluginSharedMemory::~LLPluginSharedMemory()
-{
- if(mNeedsDestroy)
- destroy();
- else
- detach();
-
- unlink();
-
- delete mImpl;
-}
-
-#if USE_APR_SHARED_MEMORY
-// MARK: apr implementation
-
-LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl()
-{
- mAprSharedMemory = NULL;
-}
-
-LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl()
-{
-
-}
-
-bool LLPluginSharedMemory::map(void)
-{
- mMappedAddress = apr_shm_baseaddr_get(mImpl->mAprSharedMemory);
- if(mMappedAddress == NULL)
- {
- return false;
- }
-
- return true;
-}
-
-bool LLPluginSharedMemory::unmap(void)
-{
- // This is a no-op under apr.
- return true;
-}
-
-bool LLPluginSharedMemory::close(void)
-{
- // This is a no-op under apr.
- return true;
-}
-
-bool LLPluginSharedMemory::unlink(void)
-{
- // This is a no-op under apr.
- return true;
-}
-
-
-bool LLPluginSharedMemory::create(size_t size)
-{
- mName = APR_SHARED_MEMORY_PREFIX_STRING;
- mName += createName();
- mSize = size;
-
- apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
-
- if(ll_apr_warn_status(status))
- {
- return false;
- }
-
- mNeedsDestroy = true;
-
- return map();
-}
-
-bool LLPluginSharedMemory::destroy(void)
-{
- if(mImpl->mAprSharedMemory)
- {
- apr_status_t status = apr_shm_destroy(mImpl->mAprSharedMemory);
- if(ll_apr_warn_status(status))
- {
- // TODO: Is this a fatal error? I think not...
- }
- mImpl->mAprSharedMemory = NULL;
- }
-
- return true;
-}
-
-bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
-{
- mName = name;
- mSize = size;
-
- apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
-
- if(ll_apr_warn_status(status))
- {
- return false;
- }
-
- return map();
-}
-
-
-bool LLPluginSharedMemory::detach(void)
-{
- if(mImpl->mAprSharedMemory)
- {
- apr_status_t status = apr_shm_detach(mImpl->mAprSharedMemory);
- if(ll_apr_warn_status(status))
- {
- // TODO: Is this a fatal error? I think not...
- }
- mImpl->mAprSharedMemory = NULL;
- }
-
- return true;
-}
-
-
-#elif USE_SHM_OPEN_SHARED_MEMORY
-// MARK: shm_open/mmap implementation
-
-LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl()
-{
- mSharedMemoryFD = -1;
-}
-
-LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl()
-{
-}
-
-bool LLPluginSharedMemory::map(void)
-{
- mMappedAddress = ::mmap(NULL, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, mImpl->mSharedMemoryFD, 0);
- if(mMappedAddress == NULL)
- {
- return false;
- }
-
- LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL;
-
- return true;
-}
-
-bool LLPluginSharedMemory::unmap(void)
-{
- if(mMappedAddress != NULL)
- {
- LL_DEBUGS("Plugin") << "calling munmap(" << mMappedAddress << ", " << mSize << ")" << LL_ENDL;
- if(::munmap(mMappedAddress, mSize) == -1)
- {
- // TODO: Is this a fatal error? I think not...
- }
-
- mMappedAddress = NULL;
- }
-
- return true;
-}
-
-bool LLPluginSharedMemory::close(void)
-{
- if(mImpl->mSharedMemoryFD != -1)
- {
- LL_DEBUGS("Plugin") << "calling close(" << mImpl->mSharedMemoryFD << ")" << LL_ENDL;
- if(::close(mImpl->mSharedMemoryFD) == -1)
- {
- // TODO: Is this a fatal error? I think not...
- }
-
- mImpl->mSharedMemoryFD = -1;
- }
- return true;
-}
-
-bool LLPluginSharedMemory::unlink(void)
-{
- if(!mName.empty())
- {
- if(::shm_unlink(mName.c_str()) == -1)
- {
- return false;
- }
- }
-
- return true;
-}
-
-
-bool LLPluginSharedMemory::create(size_t size)
-{
- mName = SHM_OPEN_SHARED_MEMORY_PREFIX_STRING;
- mName += createName();
- mSize = size;
-
- // Preemptive unlink, just in case something didn't get cleaned up.
- unlink();
-
- mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
- if(mImpl->mSharedMemoryFD == -1)
- {
- return false;
- }
-
- mNeedsDestroy = true;
-
- if(::ftruncate(mImpl->mSharedMemoryFD, mSize) == -1)
- {
- return false;
- }
-
-
- return map();
-}
-
-bool LLPluginSharedMemory::destroy(void)
-{
- unmap();
- close();
-
- return true;
-}
-
-
-bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
-{
- mName = name;
- mSize = size;
-
- mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
- if(mImpl->mSharedMemoryFD == -1)
- {
- return false;
- }
-
- // unlink here so the segment will be cleaned up automatically after the last close.
- unlink();
-
- return map();
-}
-
-bool LLPluginSharedMemory::detach(void)
-{
- unmap();
- close();
- return true;
-}
-
-#elif USE_WIN32_SHARED_MEMORY
-// MARK: Win32 CreateFileMapping-based implementation
-
-// Reference: http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx
-
-LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl()
-{
- mMapFile = NULL;
-}
-
-LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl()
-{
-
-}
-
-bool LLPluginSharedMemory::map(void)
-{
- mMappedAddress = MapViewOfFile(
- mImpl->mMapFile, // handle to map object
- FILE_MAP_ALL_ACCESS, // read/write permission
- 0,
- 0,
- mSize);
-
- if(mMappedAddress == NULL)
- {
- LL_WARNS("Plugin") << "MapViewOfFile failed: " << GetLastError() << LL_ENDL;
- return false;
- }
-
- LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL;
-
- return true;
-}
-
-bool LLPluginSharedMemory::unmap(void)
-{
- if(mMappedAddress != NULL)
- {
- UnmapViewOfFile(mMappedAddress);
- mMappedAddress = NULL;
- }
-
- return true;
-}
-
-bool LLPluginSharedMemory::close(void)
-{
- if(mImpl->mMapFile != NULL)
- {
- CloseHandle(mImpl->mMapFile);
- mImpl->mMapFile = NULL;
- }
-
- return true;
-}
-
-bool LLPluginSharedMemory::unlink(void)
-{
- // This is a no-op on Windows.
- return true;
-}
-
-
-bool LLPluginSharedMemory::create(size_t size)
-{
- mName = WIN32_SHARED_MEMORY_PREFIX_STRING;
- mName += createName();
- mSize = size;
-
- mImpl->mMapFile = CreateFileMappingA(
- INVALID_HANDLE_VALUE, // use paging file
- NULL, // default security
- PAGE_READWRITE, // read/write access
- 0, // max. object size
- mSize, // buffer size
- mName.c_str()); // name of mapping object
-
- if(mImpl->mMapFile == NULL)
- {
- LL_WARNS("Plugin") << "CreateFileMapping failed: " << GetLastError() << LL_ENDL;
- return false;
- }
-
- mNeedsDestroy = true;
-
- return map();
-}
-
-bool LLPluginSharedMemory::destroy(void)
-{
- unmap();
- close();
- return true;
-}
-
-bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
-{
- mName = name;
- mSize = size;
-
- mImpl->mMapFile = OpenFileMappingA(
- FILE_MAP_ALL_ACCESS, // read/write access
- false, // do not inherit the name
- mName.c_str()); // name of mapping object
-
- if(mImpl->mMapFile == NULL)
- {
- LL_WARNS("Plugin") << "OpenFileMapping failed: " << GetLastError() << LL_ENDL;
- return false;
- }
-
- return map();
-}
-
-bool LLPluginSharedMemory::detach(void)
-{
- unmap();
- close();
- return true;
-}
-
-
-
-#endif
+/** + * @file llpluginsharedmemory.cpp + * LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. + * + * @cond + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include "linden_common.h" + +#include "llpluginsharedmemory.h" + +// on Mac and Linux, we use the native shm_open/mmap interface by using +// #define USE_SHM_OPEN_SHARED_MEMORY 1 +// in the appropriate sections below. + +// For Windows, use: +// #define USE_WIN32_SHARED_MEMORY 1 + +// If we ever want to fall back to the apr implementation for a platform, use: +// #define USE_APR_SHARED_MEMORY 1 + +#if LL_WINDOWS +// #define USE_APR_SHARED_MEMORY 1 + #define USE_WIN32_SHARED_MEMORY 1 +#elif LL_DARWIN + #define USE_SHM_OPEN_SHARED_MEMORY 1 +#elif LL_LINUX + #define USE_SHM_OPEN_SHARED_MEMORY 1 +#endif + + +// FIXME: This path thing is evil and unacceptable. +#if LL_WINDOWS + #define APR_SHARED_MEMORY_PREFIX_STRING "C:\\LLPlugin_" + // Apparnently using the "Global\\" prefix here only works from administrative accounts under Vista. + // Other options I've seen referenced are "Local\\" and "Session\\". + #define WIN32_SHARED_MEMORY_PREFIX_STRING "Local\\LL_" +#else + // mac and linux + #define APR_SHARED_MEMORY_PREFIX_STRING "/tmp/LLPlugin_" + #define SHM_OPEN_SHARED_MEMORY_PREFIX_STRING "/LL" +#endif + +#if USE_APR_SHARED_MEMORY + #include "llapr.h" + #include "apr_shm.h" +#elif USE_SHM_OPEN_SHARED_MEMORY + #include <sys/fcntl.h> + #include <sys/mman.h> + #include <errno.h> +#elif USE_WIN32_SHARED_MEMORY +#include <windows.h> +#endif // USE_APR_SHARED_MEMORY + + +int LLPluginSharedMemory::sSegmentNumber = 0; + +std::string LLPluginSharedMemory::createName(void) +{ + std::stringstream newname; + +#if LL_WINDOWS + newname << GetCurrentProcessId(); +#else // LL_WINDOWS + newname << getpid(); +#endif // LL_WINDOWS + + newname << "_" << sSegmentNumber++; + + return newname.str(); +} + +/** + * @brief LLPluginSharedMemoryImpl is the platform-dependent implementation of LLPluginSharedMemory. TODO:DOC is this necessary/sufficient? kinda obvious. + * + */ +class LLPluginSharedMemoryPlatformImpl +{ +public: + LLPluginSharedMemoryPlatformImpl(); + ~LLPluginSharedMemoryPlatformImpl(); + +#if USE_APR_SHARED_MEMORY + apr_shm_t* mAprSharedMemory; +#elif USE_SHM_OPEN_SHARED_MEMORY + int mSharedMemoryFD; +#elif USE_WIN32_SHARED_MEMORY + HANDLE mMapFile; +#endif + +}; + +/** + * Constructor. Creates a shared memory segment. + */ +LLPluginSharedMemory::LLPluginSharedMemory() +{ + mSize = 0; + mMappedAddress = NULL; + mNeedsDestroy = false; + + mImpl = new LLPluginSharedMemoryPlatformImpl; +} + +/** + * Destructor. Uses destroy() and detach() to ensure shared memory segment is cleaned up. + */ +LLPluginSharedMemory::~LLPluginSharedMemory() +{ + if(mNeedsDestroy) + destroy(); + else + detach(); + + unlink(); + + delete mImpl; +} + +#if USE_APR_SHARED_MEMORY +// MARK: apr implementation + +LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl() +{ + mAprSharedMemory = NULL; +} + +LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl() +{ + +} + +bool LLPluginSharedMemory::map(void) +{ + mMappedAddress = apr_shm_baseaddr_get(mImpl->mAprSharedMemory); + if(mMappedAddress == NULL) + { + return false; + } + + return true; +} + +bool LLPluginSharedMemory::unmap(void) +{ + // This is a no-op under apr. + return true; +} + +bool LLPluginSharedMemory::close(void) +{ + // This is a no-op under apr. + return true; +} + +bool LLPluginSharedMemory::unlink(void) +{ + // This is a no-op under apr. + return true; +} + + +bool LLPluginSharedMemory::create(size_t size) +{ + mName = APR_SHARED_MEMORY_PREFIX_STRING; + mName += createName(); + mSize = size; + + apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); + + if(ll_apr_warn_status(status)) + { + return false; + } + + mNeedsDestroy = true; + + return map(); +} + +bool LLPluginSharedMemory::destroy(void) +{ + if(mImpl->mAprSharedMemory) + { + apr_status_t status = apr_shm_destroy(mImpl->mAprSharedMemory); + if(ll_apr_warn_status(status)) + { + // TODO: Is this a fatal error? I think not... + } + mImpl->mAprSharedMemory = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::attach(const std::string &name, size_t size) +{ + mName = name; + mSize = size; + + apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); + + if(ll_apr_warn_status(status)) + { + return false; + } + + return map(); +} + + +bool LLPluginSharedMemory::detach(void) +{ + if(mImpl->mAprSharedMemory) + { + apr_status_t status = apr_shm_detach(mImpl->mAprSharedMemory); + if(ll_apr_warn_status(status)) + { + // TODO: Is this a fatal error? I think not... + } + mImpl->mAprSharedMemory = NULL; + } + + return true; +} + + +#elif USE_SHM_OPEN_SHARED_MEMORY +// MARK: shm_open/mmap implementation + +LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl() +{ + mSharedMemoryFD = -1; +} + +LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl() +{ +} + +bool LLPluginSharedMemory::map(void) +{ + mMappedAddress = ::mmap(NULL, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, mImpl->mSharedMemoryFD, 0); + if(mMappedAddress == NULL) + { + return false; + } + + LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL; + + return true; +} + +bool LLPluginSharedMemory::unmap(void) +{ + if(mMappedAddress != NULL) + { + LL_DEBUGS("Plugin") << "calling munmap(" << mMappedAddress << ", " << mSize << ")" << LL_ENDL; + if(::munmap(mMappedAddress, mSize) == -1) + { + // TODO: Is this a fatal error? I think not... + } + + mMappedAddress = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::close(void) +{ + if(mImpl->mSharedMemoryFD != -1) + { + LL_DEBUGS("Plugin") << "calling close(" << mImpl->mSharedMemoryFD << ")" << LL_ENDL; + if(::close(mImpl->mSharedMemoryFD) == -1) + { + // TODO: Is this a fatal error? I think not... + } + + mImpl->mSharedMemoryFD = -1; + } + return true; +} + +bool LLPluginSharedMemory::unlink(void) +{ + if(!mName.empty()) + { + if(::shm_unlink(mName.c_str()) == -1) + { + return false; + } + } + + return true; +} + + +bool LLPluginSharedMemory::create(size_t size) +{ + mName = SHM_OPEN_SHARED_MEMORY_PREFIX_STRING; + mName += createName(); + mSize = size; + + // Preemptive unlink, just in case something didn't get cleaned up. + unlink(); + + mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if(mImpl->mSharedMemoryFD == -1) + { + return false; + } + + mNeedsDestroy = true; + + if(::ftruncate(mImpl->mSharedMemoryFD, mSize) == -1) + { + return false; + } + + + return map(); +} + +bool LLPluginSharedMemory::destroy(void) +{ + unmap(); + close(); + + return true; +} + + +bool LLPluginSharedMemory::attach(const std::string &name, size_t size) +{ + mName = name; + mSize = size; + + mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_RDWR, S_IRUSR | S_IWUSR); + if(mImpl->mSharedMemoryFD == -1) + { + return false; + } + + // unlink here so the segment will be cleaned up automatically after the last close. + unlink(); + + return map(); +} + +bool LLPluginSharedMemory::detach(void) +{ + unmap(); + close(); + return true; +} + +#elif USE_WIN32_SHARED_MEMORY +// MARK: Win32 CreateFileMapping-based implementation + +// Reference: http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx + +LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl() +{ + mMapFile = NULL; +} + +LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl() +{ + +} + +bool LLPluginSharedMemory::map(void) +{ + mMappedAddress = MapViewOfFile( + mImpl->mMapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + mSize); + + if(mMappedAddress == NULL) + { + LL_WARNS("Plugin") << "MapViewOfFile failed: " << GetLastError() << LL_ENDL; + return false; + } + + LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL; + + return true; +} + +bool LLPluginSharedMemory::unmap(void) +{ + if(mMappedAddress != NULL) + { + UnmapViewOfFile(mMappedAddress); + mMappedAddress = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::close(void) +{ + if(mImpl->mMapFile != NULL) + { + CloseHandle(mImpl->mMapFile); + mImpl->mMapFile = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::unlink(void) +{ + // This is a no-op on Windows. + return true; +} + + +bool LLPluginSharedMemory::create(size_t size) +{ + mName = WIN32_SHARED_MEMORY_PREFIX_STRING; + mName += createName(); + mSize = size; + + mImpl->mMapFile = CreateFileMappingA( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // max. object size + mSize, // buffer size + mName.c_str()); // name of mapping object + + if(mImpl->mMapFile == NULL) + { + LL_WARNS("Plugin") << "CreateFileMapping failed: " << GetLastError() << LL_ENDL; + return false; + } + + mNeedsDestroy = true; + + return map(); +} + +bool LLPluginSharedMemory::destroy(void) +{ + unmap(); + close(); + return true; +} + +bool LLPluginSharedMemory::attach(const std::string &name, size_t size) +{ + mName = name; + mSize = size; + + mImpl->mMapFile = OpenFileMappingA( + FILE_MAP_ALL_ACCESS, // read/write access + false, // do not inherit the name + mName.c_str()); // name of mapping object + + if(mImpl->mMapFile == NULL) + { + LL_WARNS("Plugin") << "OpenFileMapping failed: " << GetLastError() << LL_ENDL; + return false; + } + + return map(); +} + +bool LLPluginSharedMemory::detach(void) +{ + unmap(); + close(); + return true; +} + + + +#endif |