summaryrefslogtreecommitdiff
path: root/indra/llplugin/llpluginsharedmemory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llplugin/llpluginsharedmemory.cpp')
-rw-r--r--indra/llplugin/llpluginsharedmemory.cpp1004
1 files changed, 502 insertions, 502 deletions
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp
index 3fc9cbd973..e6c43f5fcc 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