summaryrefslogtreecommitdiff
path: root/packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch
diff options
context:
space:
mode:
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>2018-04-26 17:34:58 +0300
committerwoongsuk cho <ws77.cho@samsung.com>2018-04-27 01:08:53 +0000
commit731adf2e8aba9b7a45e7671d313c2628f4ec5414 (patch)
tree5887ab6bba5604ec898d765f08cd2c89edc5ba1d /packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch
parentbf88f670189b7baae58b538ae3b77052f8ec7e08 (diff)
downloadcoreclr-731adf2e8aba9b7a45e7671d313c2628f4ec5414.tar.gz
coreclr-731adf2e8aba9b7a45e7671d313c2628f4ec5414.tar.bz2
coreclr-731adf2e8aba9b7a45e7671d313c2628f4ec5414.zip
Add memory optimization patches from upstream
Change-Id: Ie8ea75fa60184b77135289c8fdc0f49d40b49d87 (cherry picked from commit 371df401e4d8c9639035d164710d1246e0cb8548)
Diffstat (limited to 'packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch')
-rw-r--r--packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch1606
1 files changed, 1606 insertions, 0 deletions
diff --git a/packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch b/packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch
new file mode 100644
index 0000000000..0d51058234
--- /dev/null
+++ b/packaging/0029-Allocate-FileMappingImmutableData-szFileName-and-CFi.patch
@@ -0,0 +1,1606 @@
+From ed41e9b578a7e888031896562ac0ce5657dc58f7 Mon Sep 17 00:00:00 2001
+From: gbalykov <g.balykov@samsung.com>
+Date: Tue, 15 Aug 2017 19:15:47 +0300
+Subject: [PATCH 29/32] Allocate FileMappingImmutableData::szFileName and
+ CFileProcessLocalData::unix_filename strings dynamically (#13374)
+
+---
+ src/pal/inc/pal.h | 13 --
+ src/pal/src/cruntime/filecrt.cpp | 2 +-
+ src/pal/src/file/file.cpp | 45 ++++-
+ src/pal/src/include/pal/corunix.hpp | 60 +++++-
+ src/pal/src/include/pal/event.hpp | 9 -
+ src/pal/src/include/pal/file.hpp | 2 +-
+ src/pal/src/include/pal/map.hpp | 11 +-
+ src/pal/src/include/pal/semaphore.hpp | 9 -
+ src/pal/src/map/map.cpp | 122 ++++++------
+ src/pal/src/objmgr/palobjbase.cpp | 10 +
+ src/pal/src/objmgr/shmobject.cpp | 294 ++--------------------------
+ src/pal/src/objmgr/shmobject.hpp | 21 +-
+ src/pal/src/objmgr/shmobjectmanager.cpp | 337 +-------------------------------
+ src/pal/src/objmgr/shmobjectmanager.hpp | 7 -
+ src/pal/src/synchobj/event.cpp | 88 +--------
+ src/pal/src/synchobj/mutex.cpp | 6 +
+ src/pal/src/synchobj/semaphore.cpp | 85 +-------
+ src/pal/src/thread/process.cpp | 11 +-
+ src/pal/src/thread/thread.cpp | 9 +-
+ 19 files changed, 231 insertions(+), 910 deletions(-)
+
+diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
+index 0f470d9..0a00b67 100644
+--- a/src/pal/inc/pal.h
++++ b/src/pal/inc/pal.h
+@@ -1601,19 +1601,6 @@ WaitForMultipleObjectsEx(
+ IN DWORD dwMilliseconds,
+ IN BOOL bAlertable);
+
+-PALIMPORT
+-RHANDLE
+-PALAPI
+-PAL_LocalHandleToRemote(
+- IN HANDLE hLocal);
+-
+-PALIMPORT
+-HANDLE
+-PALAPI
+-PAL_RemoteHandleToLocal(
+- IN RHANDLE hRemote);
+-
+-
+ #define DUPLICATE_CLOSE_SOURCE 0x00000001
+ #define DUPLICATE_SAME_ACCESS 0x00000002
+
+diff --git a/src/pal/src/cruntime/filecrt.cpp b/src/pal/src/cruntime/filecrt.cpp
+index 48079b3..182a42d 100644
+--- a/src/pal/src/cruntime/filecrt.cpp
++++ b/src/pal/src/cruntime/filecrt.cpp
+@@ -93,7 +93,7 @@ _open_osfhandle( INT_PTR osfhandle, int flags )
+
+ if (NO_ERROR == palError)
+ {
+- if ('\0' != pLocalData->unix_filename[0])
++ if (NULL != pLocalData->unix_filename)
+ {
+ nRetVal = InternalOpen(pLocalData->unix_filename, openFlags);
+ }
+diff --git a/src/pal/src/file/file.cpp b/src/pal/src/file/file.cpp
+index feec655..e7003c0 100644
+--- a/src/pal/src/file/file.cpp
++++ b/src/pal/src/file/file.cpp
+@@ -56,6 +56,12 @@ InternalSetFilePointerForUnixFd(
+ );
+
+ void
++CFileProcessLocalDataCleanupRoutine(
++ CPalThread *pThread,
++ IPalObject *pObjectToCleanup
++ );
++
++void
+ FileCleanupRoutine(
+ CPalThread *pThread,
+ IPalObject *pObjectToCleanup,
+@@ -68,7 +74,10 @@ CObjectType CorUnix::otFile(
+ FileCleanupRoutine,
+ NULL, // No initialization routine
+ 0, // No immutable data
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ sizeof(CFileProcessLocalData),
++ CFileProcessLocalDataCleanupRoutine,
+ 0, // No shared data
+ GENERIC_READ|GENERIC_WRITE, // Ignored -- no Win32 object security support
+ CObjectType::SecuritySupported,
+@@ -86,6 +95,34 @@ static CSharedMemoryFileLockMgr _FileLockManager;
+ IFileLockManager *CorUnix::g_pFileLockManager = &_FileLockManager;
+
+ void
++CFileProcessLocalDataCleanupRoutine(
++ CPalThread *pThread,
++ IPalObject *pObjectToCleanup
++ )
++{
++ PAL_ERROR palError;
++ CFileProcessLocalData *pLocalData = NULL;
++ IDataLock *pLocalDataLock = NULL;
++
++ palError = pObjectToCleanup->GetProcessLocalData(
++ pThread,
++ ReadLock,
++ &pLocalDataLock,
++ reinterpret_cast<void**>(&pLocalData)
++ );
++
++ if (NO_ERROR != palError)
++ {
++ ASSERT("Unable to obtain data to cleanup file object");
++ return;
++ }
++
++ free(pLocalData->unix_filename);
++
++ pLocalDataLock->ReleaseLock(pThread, FALSE);
++}
++
++void
+ FileCleanupRoutine(
+ CPalThread *pThread,
+ IPalObject *pObjectToCleanup,
+@@ -738,10 +775,12 @@ CorUnix::InternalCreateFile(
+ goto done;
+ }
+
+- if (strcpy_s(pLocalData->unix_filename, sizeof(pLocalData->unix_filename), lpUnixPath) != SAFECRT_SUCCESS)
++ _ASSERTE(pLocalData->unix_filename == NULL);
++ pLocalData->unix_filename = strdup(lpUnixPath);
++ if (pLocalData->unix_filename == NULL)
+ {
+- palError = ERROR_INSUFFICIENT_BUFFER;
+- TRACE("strcpy_s failed!\n");
++ ASSERT("Unable to copy string\n");
++ palError = ERROR_INTERNAL_ERROR;
+ goto done;
+ }
+
+diff --git a/src/pal/src/include/pal/corunix.hpp b/src/pal/src/include/pal/corunix.hpp
+index e9e9503..bfdfb6c 100644
+--- a/src/pal/src/include/pal/corunix.hpp
++++ b/src/pal/src/include/pal/corunix.hpp
+@@ -173,6 +173,15 @@ namespace CorUnix
+ void * // pProcessLocalData
+ );
+
++ typedef void (*OBJECT_IMMUTABLE_DATA_COPY_ROUTINE) (
++ void *,
++ void *);
++ typedef void (*OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE) (
++ void *);
++ typedef void (*OBJECT_PROCESS_LOCAL_DATA_CLEANUP_ROUTINE) (
++ CPalThread *, // pThread
++ IPalObject *);
++
+ enum PalObjectTypeId
+ {
+ otiAutoResetEvent = 0,
+@@ -315,7 +324,10 @@ namespace CorUnix
+ OBJECTCLEANUPROUTINE m_pCleanupRoutine;
+ OBJECTINITROUTINE m_pInitRoutine;
+ DWORD m_dwImmutableDataSize;
++ OBJECT_IMMUTABLE_DATA_COPY_ROUTINE m_pImmutableDataCopyRoutine;
++ OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE m_pImmutableDataCleanupRoutine;
+ DWORD m_dwProcessLocalDataSize;
++ OBJECT_PROCESS_LOCAL_DATA_CLEANUP_ROUTINE m_pProcessLocalDataCleanupRoutine;
+ DWORD m_dwSharedDataSize;
+ DWORD m_dwSupportedAccessRights;
+ // Generic access rights mapping
+@@ -335,7 +347,10 @@ namespace CorUnix
+ OBJECTCLEANUPROUTINE pCleanupRoutine,
+ OBJECTINITROUTINE pInitRoutine,
+ DWORD dwImmutableDataSize,
++ OBJECT_IMMUTABLE_DATA_COPY_ROUTINE pImmutableDataCopyRoutine,
++ OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE pImmutableDataCleanupRoutine,
+ DWORD dwProcessLocalDataSize,
++ OBJECT_PROCESS_LOCAL_DATA_CLEANUP_ROUTINE pProcessLocalDataCleanupRoutine,
+ DWORD dwSharedDataSize,
+ DWORD dwSupportedAccessRights,
+ SecuritySupport eSecuritySupport,
+@@ -352,7 +367,10 @@ namespace CorUnix
+ m_pCleanupRoutine(pCleanupRoutine),
+ m_pInitRoutine(pInitRoutine),
+ m_dwImmutableDataSize(dwImmutableDataSize),
++ m_pImmutableDataCopyRoutine(pImmutableDataCopyRoutine),
++ m_pImmutableDataCleanupRoutine(pImmutableDataCleanupRoutine),
+ m_dwProcessLocalDataSize(dwProcessLocalDataSize),
++ m_pProcessLocalDataCleanupRoutine(pProcessLocalDataCleanupRoutine),
+ m_dwSharedDataSize(dwSharedDataSize),
+ m_dwSupportedAccessRights(dwSupportedAccessRights),
+ m_eSecuritySupport(eSecuritySupport),
+@@ -408,6 +426,38 @@ namespace CorUnix
+ return m_dwImmutableDataSize;
+ };
+
++ void
++ SetImmutableDataCopyRoutine(
++ OBJECT_IMMUTABLE_DATA_COPY_ROUTINE ptr
++ )
++ {
++ m_pImmutableDataCopyRoutine = ptr;
++ };
++
++ OBJECT_IMMUTABLE_DATA_COPY_ROUTINE
++ GetImmutableDataCopyRoutine(
++ void
++ )
++ {
++ return m_pImmutableDataCopyRoutine;
++ };
++
++ void
++ SetImmutableDataCleanupRoutine(
++ OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE ptr
++ )
++ {
++ m_pImmutableDataCleanupRoutine = ptr;
++ };
++
++ OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE
++ GetImmutableDataCleanupRoutine(
++ void
++ )
++ {
++ return m_pImmutableDataCleanupRoutine;
++ }
++
+ DWORD
+ GetProcessLocalDataSize(
+ void
+@@ -415,7 +465,15 @@ namespace CorUnix
+ {
+ return m_dwProcessLocalDataSize;
+ };
+-
++
++ OBJECT_PROCESS_LOCAL_DATA_CLEANUP_ROUTINE
++ GetProcessLocalDataCleanupRoutine(
++ void
++ )
++ {
++ return m_pProcessLocalDataCleanupRoutine;
++ }
++
+ DWORD
+ GetSharedDataSize(
+ void
+diff --git a/src/pal/src/include/pal/event.hpp b/src/pal/src/include/pal/event.hpp
+index 98eeaee..21dc478 100644
+--- a/src/pal/src/include/pal/event.hpp
++++ b/src/pal/src/include/pal/event.hpp
+@@ -44,15 +44,6 @@ namespace CorUnix
+ HANDLE hEvent,
+ BOOL fSetEvent
+ );
+-
+- PAL_ERROR
+- InternalOpenEvent(
+- CPalThread *pThread,
+- DWORD dwDesiredAccess,
+- BOOL bInheritHandle,
+- LPCWSTR lpName,
+- HANDLE *phEvent
+- );
+
+ }
+
+diff --git a/src/pal/src/include/pal/file.hpp b/src/pal/src/include/pal/file.hpp
+index 5acccb0..22e4187 100644
+--- a/src/pal/src/include/pal/file.hpp
++++ b/src/pal/src/include/pal/file.hpp
+@@ -44,7 +44,7 @@ namespace CorUnix
+ In Windows we can open a file for writing only */
+ int open_flags; /* stores Unix file creation flags */
+ BOOL open_flags_deviceaccessonly;
+- char unix_filename[MAXPATHLEN];
++ CHAR *unix_filename;
+ BOOL inheritable;
+ };
+
+diff --git a/src/pal/src/include/pal/map.hpp b/src/pal/src/include/pal/map.hpp
+index 854e6c5..7bcb20a 100644
+--- a/src/pal/src/include/pal/map.hpp
++++ b/src/pal/src/include/pal/map.hpp
+@@ -144,7 +144,7 @@ namespace CorUnix
+ class CFileMappingImmutableData
+ {
+ public:
+- CHAR szFileName[MAXPATHLEN];
++ CHAR *lpFileName;
+ UINT MaxSize; // The max size of the file mapping object
+ DWORD flProtect; // Protection desired for the file view
+ BOOL bPALCreatedTempFile; // TRUE if it's a PAL created file
+@@ -179,15 +179,6 @@ namespace CorUnix
+ );
+
+ PAL_ERROR
+- InternalOpenFileMapping(
+- CPalThread *pThread,
+- DWORD dwDesiredAccess,
+- BOOL bInheritHandle,
+- LPCWSTR lpName,
+- HANDLE *phMapping
+- );
+-
+- PAL_ERROR
+ InternalMapViewOfFile(
+ CPalThread *pThread,
+ HANDLE hFileMappingObject,
+diff --git a/src/pal/src/include/pal/semaphore.hpp b/src/pal/src/include/pal/semaphore.hpp
+index 2943d61..33cf35b 100644
+--- a/src/pal/src/include/pal/semaphore.hpp
++++ b/src/pal/src/include/pal/semaphore.hpp
+@@ -49,15 +49,6 @@ namespace CorUnix
+ LONG lReleaseCount,
+ LPLONG lpPreviousCount
+ );
+-
+- PAL_ERROR
+- InternalOpenSemaphore(
+- CPalThread *pThread,
+- DWORD dwDesiredAccess,
+- BOOL bInheritHandle,
+- LPCWSTR lpName,
+- HANDLE *phSemaphore
+- );
+
+ }
+
+diff --git a/src/pal/src/map/map.cpp b/src/pal/src/map/map.cpp
+index b8ffc84..f99e330 100644
+--- a/src/pal/src/map/map.cpp
++++ b/src/pal/src/map/map.cpp
+@@ -131,12 +131,26 @@ FileMappingInitializationRoutine(
+ void *pProcessLocalData
+ );
+
++void
++CFileMappingImmutableDataCopyRoutine(
++ void *pImmData,
++ void *pImmDataTarget
++ );
++
++void
++CFileMappingImmutableDataCleanupRoutine(
++ void *pImmData
++ );
++
+ CObjectType CorUnix::otFileMapping(
+ otiFileMapping,
+ FileMappingCleanupRoutine,
+ FileMappingInitializationRoutine,
+ sizeof(CFileMappingImmutableData),
++ CFileMappingImmutableDataCopyRoutine,
++ CFileMappingImmutableDataCleanupRoutine,
+ sizeof(CFileMappingProcessLocalData),
++ NULL, // No process local data cleanup routine
+ 0,
+ PAGE_READWRITE | PAGE_READONLY | PAGE_WRITECOPY,
+ CObjectType::SecuritySupported,
+@@ -152,6 +166,33 @@ CObjectType CorUnix::otFileMapping(
+ CAllowedObjectTypes aotFileMapping(otiFileMapping);
+
+ void
++CFileMappingImmutableDataCopyRoutine(
++ void *pImmData,
++ void *pImmDataTarget
++ )
++{
++ PAL_ERROR palError = NO_ERROR;
++ CFileMappingImmutableData *pImmutableData = (CFileMappingImmutableData *) pImmData;
++ CFileMappingImmutableData *pImmutableDataTarget = (CFileMappingImmutableData *) pImmDataTarget;
++
++ if (NULL != pImmutableData->lpFileName)
++ {
++ pImmutableDataTarget->lpFileName = strdup(pImmutableData->lpFileName);
++ }
++}
++
++void
++CFileMappingImmutableDataCleanupRoutine(
++ void *pImmData
++ )
++{
++ PAL_ERROR palError = NO_ERROR;
++ CFileMappingImmutableData *pImmutableData = (CFileMappingImmutableData *) pImmData;
++
++ free(pImmutableData->lpFileName);
++}
++
++void
+ FileMappingCleanupRoutine(
+ CPalThread *pThread,
+ IPalObject *pObjectToCleanup,
+@@ -184,7 +225,7 @@ FileMappingCleanupRoutine(
+
+ if (pImmutableData->bPALCreatedTempFile)
+ {
+- unlink(pImmutableData->szFileName);
++ unlink(pImmutableData->lpFileName);
+ }
+ }
+
+@@ -245,7 +286,7 @@ FileMappingInitializationRoutine(
+ reinterpret_cast<CFileMappingProcessLocalData *>(pvProcessLocalData);
+
+ pProcessLocalData->UnixFd = InternalOpen(
+- pImmutableData->szFileName,
++ pImmutableData->lpFileName,
+ MAPProtectionToFileOpenFlags(pImmutableData->flProtect) | O_CLOEXEC
+ );
+
+@@ -501,16 +542,18 @@ CorUnix::InternalCreateFileMapping(
+ //
+
+ /* Anonymous mapped files. */
+- if (strcpy_s(pImmutableData->szFileName, sizeof(pImmutableData->szFileName), "/dev/zero") != SAFECRT_SUCCESS)
++ _ASSERTE(pImmutableData->lpFileName == NULL);
++ pImmutableData->lpFileName = strdup("/dev/zero");
++ if (pImmutableData->lpFileName == NULL)
+ {
+- ERROR( "strcpy_s failed!\n" );
++ ASSERT("Unable to copy string\n");
+ palError = ERROR_INTERNAL_ERROR;
+ goto ExitInternalCreateFileMapping;
+ }
+
+ #if HAVE_MMAP_DEV_ZERO
+
+- UnixFd = InternalOpen(pImmutableData->szFileName, O_RDWR | O_CLOEXEC);
++ UnixFd = InternalOpen(pImmutableData->lpFileName, O_RDWR | O_CLOEXEC);
+ if ( -1 == UnixFd )
+ {
+ ERROR( "Unable to open the file.\n");
+@@ -598,10 +641,12 @@ CorUnix::InternalCreateFileMapping(
+ }
+ goto ExitInternalCreateFileMapping;
+ }
+-
+- if (strcpy_s(pImmutableData->szFileName, sizeof(pImmutableData->szFileName), pFileLocalData->unix_filename) != SAFECRT_SUCCESS)
++
++ _ASSERTE(pImmutableData->lpFileName == NULL);
++ pImmutableData->lpFileName = strdup(pFileLocalData->unix_filename);
++ if (pImmutableData->lpFileName == NULL)
+ {
+- ERROR( "strcpy_s failed!\n" );
++ ASSERT("Unable to copy string\n");
+ palError = ERROR_INTERNAL_ERROR;
+ if (NULL != pFileLocalDataLock)
+ {
+@@ -623,7 +668,7 @@ CorUnix::InternalCreateFileMapping(
+
+ /* Create a temporary file on the filesystem in order to be
+ shared across processes. */
+- palError = MAPCreateTempFile(pThread, &UnixFd, pImmutableData->szFileName);
++ palError = MAPCreateTempFile(pThread, &UnixFd, pImmutableData->lpFileName);
+ if (NO_ERROR != palError)
+ {
+ ERROR("Unable to create the temporary file.\n");
+@@ -771,7 +816,7 @@ ExitInternalCreateFileMapping:
+
+ if (bPALCreatedTempFile)
+ {
+- unlink(pImmutableData->szFileName);
++ unlink(pImmutableData->lpFileName);
+ }
+
+ if (-1 != UnixFd)
+@@ -881,63 +926,6 @@ OpenFileMappingW(
+ return hFileMapping;
+ }
+
+-PAL_ERROR
+-CorUnix::InternalOpenFileMapping(
+- CPalThread *pThread,
+- DWORD dwDesiredAccess,
+- BOOL bInheritHandle,
+- LPCWSTR lpName,
+- HANDLE *phMapping
+- )
+-{
+- PAL_ERROR palError = NO_ERROR;
+- IPalObject *pFileMapping = NULL;
+- CPalString sObjectName(lpName);
+-
+- if ( MAPContainsInvalidFlags( dwDesiredAccess ) )
+- {
+- ASSERT( "dwDesiredAccess can be one or more of FILE_MAP_READ, "
+- "FILE_MAP_WRITE, FILE_MAP_COPY or FILE_MAP_ALL_ACCESS.\n" );
+- palError = ERROR_INVALID_PARAMETER;
+- goto ExitInternalOpenFileMapping;
+- }
+-
+- palError = g_pObjectManager->LocateObject(
+- pThread,
+- &sObjectName,
+- &aotFileMapping,
+- &pFileMapping
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto ExitInternalOpenFileMapping;
+- }
+-
+- palError = g_pObjectManager->ObtainHandleForObject(
+- pThread,
+- pFileMapping,
+- dwDesiredAccess,
+- bInheritHandle,
+- NULL,
+- phMapping
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto ExitInternalOpenFileMapping;
+- }
+-
+-ExitInternalOpenFileMapping:
+-
+- if (NULL != pFileMapping)
+- {
+- pFileMapping->ReleaseReference(pThread);
+- }
+-
+- return palError;
+-}
+-
+ /*++
+ Function:
+ MapViewOfFile
+diff --git a/src/pal/src/objmgr/palobjbase.cpp b/src/pal/src/objmgr/palobjbase.cpp
+index 27842f6..0f226b9 100644
+--- a/src/pal/src/objmgr/palobjbase.cpp
++++ b/src/pal/src/objmgr/palobjbase.cpp
+@@ -314,6 +314,16 @@ CPalObjectBase::ReleaseReference(
+ );
+ }
+
++ if (NULL != m_pot->GetImmutableDataCleanupRoutine())
++ {
++ (*m_pot->GetImmutableDataCleanupRoutine())(m_pvImmutableData);
++ }
++
++ if (NULL != m_pot->GetProcessLocalDataCleanupRoutine())
++ {
++ (*m_pot->GetProcessLocalDataCleanupRoutine())(pthr, static_cast<IPalObject*>(this));
++ }
++
+ InternalDelete(this);
+
+ pthr->ReleaseThreadReference();
+diff --git a/src/pal/src/objmgr/shmobject.cpp b/src/pal/src/objmgr/shmobject.cpp
+index 2692554..17ef3e4 100644
+--- a/src/pal/src/objmgr/shmobject.cpp
++++ b/src/pal/src/objmgr/shmobject.cpp
+@@ -242,6 +242,13 @@ CSharedMemoryObject::InitializeFromExistingSharedData(
+ if (NULL != pv)
+ {
+ memcpy(m_pvImmutableData, pv, m_pot->GetImmutableDataSize());
++ if (NULL != psmod->pCopyRoutine)
++ {
++ (*psmod->pCopyRoutine)(pv, m_pvImmutableData);
++ }
++
++ m_pot->SetImmutableDataCopyRoutine(psmod->pCopyRoutine);
++ m_pot->SetImmutableDataCleanupRoutine(psmod->pCleanupRoutine);
+ }
+ else
+ {
+@@ -436,6 +443,10 @@ CSharedMemoryObject::FreeSharedDataAreas(
+
+ if (NULL != psmod->shmObjImmutableData)
+ {
++ if (NULL != psmod->pCleanupRoutine)
++ {
++ (*psmod->pCleanupRoutine)(psmod->shmObjImmutableData);
++ }
+ free(psmod->shmObjImmutableData);
+ }
+
+@@ -458,159 +469,6 @@ CSharedMemoryObject::FreeSharedDataAreas(
+
+ /*++
+ Function:
+- CSharedMemoryObject::PromoteShjaredData
+-
+- Copies the object's state into the passed-in shared data structures
+-
+-Parameters:
+- shmObjData -- shared memory pointer for the shared memory object data
+- psmod -- locally-mapped pointer for the shared memory object data
+---*/
+-
+-void
+-CSharedMemoryObject::PromoteSharedData(
+- SHMPTR shmObjData,
+- SHMObjData *psmod
+- )
+-{
+- _ASSERTE(NULL != shmObjData);
+- _ASSERTE(NULL != psmod);
+-
+- ENTRY("CSharedMemoryObject::PromoteSharedData"
+- "(this = %p, shmObjData = %p, psmod = %p)\n",
+- this,
+- shmObjData,
+- psmod);
+-
+- //
+- // psmod has been zero-inited, so we don't need to worry about
+- // shmPrevObj, shmNextObj, fAddedToList, shmObjName, dwNameLength,
+- // or pvSynchData
+- //
+-
+- psmod->lProcessRefCount = 1;
+- psmod->eTypeId = m_pot->GetId();
+-
+- if (0 != m_pot->GetImmutableDataSize())
+- {
+- void *pvImmutableData;
+-
+- pvImmutableData = SHMPTR_TO_TYPED_PTR(void, psmod->shmObjImmutableData);
+- _ASSERTE(NULL != pvImmutableData);
+-
+- CopyMemory(
+- pvImmutableData,
+- m_pvImmutableData,
+- m_pot->GetImmutableDataSize()
+- );
+- }
+-
+- if (0 != m_pot->GetSharedDataSize())
+- {
+- void *pvSharedData;
+-
+- pvSharedData = SHMPTR_TO_TYPED_PTR(void, psmod->shmObjSharedData);
+- _ASSERTE(NULL != pvSharedData);
+-
+- CopyMemory(
+- pvSharedData,
+- m_pvSharedData,
+- m_pot->GetSharedDataSize()
+- );
+-
+- free(m_pvSharedData);
+- m_pvSharedData = pvSharedData;
+- }
+-
+- m_shmod = shmObjData;
+-
+- LOGEXIT("CSharedMemoryObject::PromoteSharedData\n");
+-}
+-
+-/*++
+-Function:
+- CSharedMemoryObject::EnsureObjectIsShared
+-
+- If this object is not yet in the shared domain allocate the necessary
+- shared memory structures for it and copy the object's data into those
+- structures
+-
+-Parameters:
+- pthr -- thread data for the calling thread
+---*/
+-
+-PAL_ERROR
+-CSharedMemoryObject::EnsureObjectIsShared(
+- CPalThread *pthr
+- )
+-{
+- PAL_ERROR palError = NO_ERROR;
+- IDataLock *pDataLock = NULL;
+- SHMPTR shmObjData;
+- SHMObjData *psmod;
+-
+- _ASSERTE(NULL != pthr);
+-
+- ENTRY("CSharedMemoryObject::EnsureObjectIsShared"
+- "(this = %p, pthr = %p)\n",
+- this,
+- pthr
+- );
+-
+- //
+- // Grab the shared memory lock and check if the object is already
+- // shared
+- //
+-
+- SHMLock();
+-
+- if (SharedObject == m_ObjectDomain)
+- {
+- goto EnsureObjectIsSharedExit;
+- }
+-
+- //
+- // Grab the local shared data lock, if necessary
+- //
+-
+- if (0 != m_pot->GetSharedDataSize())
+- {
+- m_sdlSharedData.AcquireLock(pthr, &pDataLock);
+- }
+-
+- //
+- // Allocate the necessary shared data areas
+- //
+-
+- palError = AllocateSharedDataItems(&shmObjData, &psmod);
+- if (NO_ERROR != palError)
+- {
+- goto EnsureObjectIsSharedExit;
+- }
+-
+- //
+- // Promote the object's data and set the domain to shared
+- //
+-
+- PromoteSharedData(shmObjData, psmod);
+- m_ObjectDomain = SharedObject;
+-
+-EnsureObjectIsSharedExit:
+-
+- if (NULL != pDataLock)
+- {
+- pDataLock->ReleaseLock(pthr, TRUE);
+- }
+-
+- SHMRelease();
+-
+- LOGEXIT("CSharedMemoryObject::EnsureObjectIsShared returns %d\n", palError);
+-
+- return palError;
+-}
+-
+-/*++
+-Function:
+ CSharedMemoryObject::CleanupForProcessShutdown
+
+ Cleanup routine called by the object manager when shutting down
+@@ -646,6 +504,16 @@ CSharedMemoryObject::CleanupForProcessShutdown(
+ );
+ }
+
++ if (NULL != m_pot->GetImmutableDataCleanupRoutine())
++ {
++ (*m_pot->GetImmutableDataCleanupRoutine())(m_pvImmutableData);
++ }
++
++ if (NULL != m_pot->GetProcessLocalDataCleanupRoutine())
++ {
++ (*m_pot->GetProcessLocalDataCleanupRoutine())(pthr, static_cast<IPalObject*>(this));
++ }
++
+ //
+ // We need to do two things with the calling thread data here:
+ // 1) store it in m_pthrCleanup so it is available to the destructors
+@@ -1188,126 +1056,6 @@ InitializeExit:
+
+ /*++
+ Function:
+- CSharedMemoryWaitableObject::EnsureObjectIsShared
+-
+- If this object is not yet in the shared domain allocate the necessary
+- shared memory structures for it and copy the object's data into those
+- structures
+-
+-Parameters:
+- pthr -- thread data for the calling thread
+---*/
+-
+-PAL_ERROR
+-CSharedMemoryWaitableObject::EnsureObjectIsShared(
+- CPalThread *pthr
+- )
+-{
+- PAL_ERROR palError = NO_ERROR;
+- IDataLock *pDataLock = NULL;
+- SHMPTR shmObjData = NULL;
+- SHMObjData *psmod;
+- VOID *pvSharedSynchData;
+-
+- _ASSERTE(NULL != pthr);
+-
+- ENTRY("CSharedMemoryWaitableObject::EnsureObjectIsShared"
+- "(this = %p, pthr = %p)\n",
+- this,
+- pthr
+- );
+-
+- //
+- // First, grab the process synchronization lock and check
+- // if the object is already shared
+- //
+-
+- g_pSynchronizationManager->AcquireProcessLock(pthr);
+-
+- if (SharedObject == m_ObjectDomain)
+- {
+- goto EnsureObjectIsSharedExitNoSHMLockRelease;
+- }
+-
+- //
+- // Grab the necessary locks
+- //
+-
+- SHMLock();
+-
+- if (0 != m_pot->GetSharedDataSize())
+- {
+- m_sdlSharedData.AcquireLock(pthr, &pDataLock);
+- }
+-
+- //
+- // Allocate the necessary shared data areas
+- //
+-
+- palError = AllocateSharedDataItems(&shmObjData, &psmod);
+- if (NO_ERROR != palError)
+- {
+- goto EnsureObjectIsSharedExit;
+- }
+-
+- //
+- // Promote the object's synchronization data
+- //
+-
+- palError = g_pSynchronizationManager->PromoteObjectSynchData(
+- pthr,
+- m_pvSynchData,
+- &pvSharedSynchData
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto EnsureObjectIsSharedExit;
+- }
+-
+- m_pvSynchData = pvSharedSynchData;
+- psmod->pvSynchData = pvSharedSynchData;
+-
+- //
+- // Promote the object's data and set the domain to shared
+- //
+-
+- PromoteSharedData(shmObjData, psmod);
+- m_ObjectDomain = SharedObject;
+-
+-EnsureObjectIsSharedExit:
+-
+- if (NULL != pDataLock)
+- {
+- pDataLock->ReleaseLock(pthr, TRUE);
+- }
+-
+- SHMRelease();
+-
+-EnsureObjectIsSharedExitNoSHMLockRelease:
+-
+- g_pSynchronizationManager->ReleaseProcessLock(pthr);
+-
+- if (NO_ERROR != palError && NULL != shmObjData)
+- {
+- //
+- // Since shmObjdData is local to this function there's no
+- // need to continue to hold the promotion locks when
+- // freeing the allocated data on error
+- //
+-
+- FreeSharedDataAreas(shmObjData);
+- }
+-
+- LOGEXIT("CSharedMemoryWaitableObject::EnsureObjectIsShared returns %d\n",
+- palError
+- );
+-
+- return palError;
+-}
+-
+-/*++
+-Function:
+ CSharedMemoryWaitableObject::~CSharedMemoryWaitableObject
+
+ Destructor; should only be called from ReleaseReference
+diff --git a/src/pal/src/objmgr/shmobject.hpp b/src/pal/src/objmgr/shmobject.hpp
+index 66b9ea9..9d55f90 100644
+--- a/src/pal/src/objmgr/shmobject.hpp
++++ b/src/pal/src/objmgr/shmobject.hpp
+@@ -65,6 +65,9 @@ namespace CorUnix
+ SHMPTR shmObjImmutableData;
+ SHMPTR shmObjSharedData;
+
++ OBJECT_IMMUTABLE_DATA_COPY_ROUTINE pCopyRoutine;
++ OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE pCleanupRoutine;
++
+ LONG lProcessRefCount;
+ DWORD dwNameLength;
+
+@@ -140,12 +143,6 @@ namespace CorUnix
+ SHMPTR shmObjData
+ );
+
+- void
+- PromoteSharedData(
+- SHMPTR shmObjData,
+- SHMObjData *psmod
+- );
+-
+ bool
+ DereferenceSharedData();
+
+@@ -228,12 +225,6 @@ namespace CorUnix
+ CObjectAttributes *poa
+ );
+
+- virtual
+- PAL_ERROR
+- EnsureObjectIsShared(
+- CPalThread *pthr
+- );
+-
+ void
+ CleanupForProcessShutdown(
+ CPalThread *pthr
+@@ -353,12 +344,6 @@ namespace CorUnix
+ CObjectAttributes *poa
+ );
+
+- virtual
+- PAL_ERROR
+- EnsureObjectIsShared(
+- CPalThread *pthr
+- );
+-
+ //
+ // IPalObject routines
+ //
+diff --git a/src/pal/src/objmgr/shmobjectmanager.cpp b/src/pal/src/objmgr/shmobjectmanager.cpp
+index 755fa46..90caa65 100644
+--- a/src/pal/src/objmgr/shmobjectmanager.cpp
++++ b/src/pal/src/objmgr/shmobjectmanager.cpp
+@@ -418,6 +418,14 @@ CSharedMemoryObjectManager::RegisterObject(
+ pvImmutableData,
+ potObj->GetImmutableDataSize()
+ );
++
++ if (NULL != potObj->GetImmutableDataCopyRoutine())
++ {
++ (*potObj->GetImmutableDataCopyRoutine())(pvImmutableData, pvSharedImmutableData);
++ }
++
++ psmod->pCopyRoutine = potObj->GetImmutableDataCopyRoutine();
++ psmod->pCleanupRoutine = potObj->GetImmutableDataCleanupRoutine();
+ }
+ else
+ {
+@@ -1174,335 +1182,6 @@ static CAllowedObjectTypes aotRemotable(
+
+ /*++
+ Function:
+- PAL_LocalHandleToRemote
+-
+- Returns a "remote handle" that may be passed to another process.
+-
+-Parameters:
+- hLocal -- the handle to generate a "remote handle" for
+---*/
+-
+-PALIMPORT
+-RHANDLE
+-PALAPI
+-PAL_LocalHandleToRemote(IN HANDLE hLocal)
+-{
+- PAL_ERROR palError = NO_ERROR;
+- CPalThread *pthr;
+- IPalObject *pobj = NULL;
+- CSharedMemoryObject *pshmobj;
+- SHMObjData *psmod = NULL;
+- RHANDLE hRemote = reinterpret_cast<RHANDLE>(INVALID_HANDLE_VALUE);
+-
+- PERF_ENTRY(PAL_LocalHandleToRemote);
+- ENTRY("PAL_LocalHandleToRemote( hLocal=0x%lx )\n", hLocal);
+-
+- pthr = InternalGetCurrentThread();
+-
+- if (!HandleIsSpecial(hLocal))
+- {
+- palError = g_pObjectManager->ReferenceObjectByHandle(
+- pthr,
+- hLocal,
+- &aotRemotable,
+- 0,
+- &pobj
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto PAL_LocalHandleToRemoteExitNoLockRelease;
+- }
+- }
+- else if (hPseudoCurrentProcess == hLocal)
+- {
+- pobj = g_pobjProcess;
+- pobj->AddReference();
+- }
+- else
+- {
+- ASSERT("Invalid special handle type passed to PAL_LocalHandleToRemote\n");
+- palError = ERROR_INVALID_HANDLE;
+- goto PAL_LocalHandleToRemoteExitNoLockRelease;
+- }
+-
+- pshmobj = static_cast<CSharedMemoryObject*>(pobj);
+-
+- //
+- // Make sure that the object is shared
+- //
+-
+- palError = pshmobj->EnsureObjectIsShared(pthr);
+- if (NO_ERROR != palError)
+- {
+- ERROR("Failure %d promoting object\n", palError);
+- goto PAL_LocalHandleToRemoteExitNoLockRelease;
+- }
+-
+- SHMLock();
+-
+- psmod = SHMPTR_TO_TYPED_PTR(SHMObjData, pshmobj->GetShmObjData());
+- if (NULL != psmod)
+- {
+- //
+- // Bump up the process ref count by 1. The receiving process will not
+- // increase the ref count when it converts the remote handle to
+- // local.
+- //
+-
+- psmod->lProcessRefCount += 1;
+-
+- //
+- // The remote handle is simply the SHMPTR for the SHMObjData
+- //
+-
+- hRemote = reinterpret_cast<RHANDLE>(pshmobj->GetShmObjData());
+- }
+- else
+- {
+- ASSERT("Unable to map shared object data\n");
+- palError = ERROR_INTERNAL_ERROR;
+- goto PAL_LocalHandleToRemoteExit;
+- }
+-
+-PAL_LocalHandleToRemoteExit:
+-
+- SHMRelease();
+-
+-PAL_LocalHandleToRemoteExitNoLockRelease:
+-
+- if (NULL != pobj)
+- {
+- pobj->ReleaseReference(pthr);
+- }
+-
+- if (NO_ERROR != palError)
+- {
+- pthr->SetLastError(palError);
+- }
+-
+- LOGEXIT("PAL_LocalHandleToRemote returns RHANDLE 0x%lx\n", hRemote);
+- PERF_EXIT(PAL_LocalHandleToRemote);
+- return hRemote;
+-}
+-
+-/*++
+-Function:
+- CSharedMemoryObjectManager::ConvertRemoteHandleToLocal
+-
+- Given a "remote handle" creates a local handle that refers
+- to the desired object. (Unlike PAL_RemoteHandleToLocal this method
+- needs to access internal object manager state, so it's a member function.)
+-
+-Parameters:
+- pthr -- thread data for calling thread
+- rhRemote -- the remote handle
+- phLocal -- on success, receives the local handle
+---*/
+-
+-PAL_ERROR
+-CSharedMemoryObjectManager::ConvertRemoteHandleToLocal(
+- CPalThread *pthr,
+- RHANDLE rhRemote,
+- HANDLE *phLocal
+- )
+-{
+- PAL_ERROR palError = NO_ERROR;
+- SHMObjData *psmod;
+- CSharedMemoryObject *pshmobj = NULL;
+- PLIST_ENTRY pleObjectList;
+-
+- _ASSERTE(NULL != pthr);
+- _ASSERTE(NULL != phLocal);
+-
+- ENTRY("CSharedMemoryObjectManager::ConvertRemoteHandleToLocal "
+- "(this=%p, pthr=%p, rhRemote=%p, phLocal=%p)\n",
+- this,
+- pthr,
+- rhRemote,
+- phLocal
+- );
+-
+- if (rhRemote == NULL || rhRemote == INVALID_HANDLE_VALUE)
+- {
+- palError = ERROR_INVALID_HANDLE;
+- goto ConvertRemoteHandleToLocalExitNoLockRelease;
+- }
+-
+- InternalEnterCriticalSection(pthr, &m_csListLock);
+- SHMLock();
+-
+- //
+- // The remote handle is really a shared memory pointer to the
+- // SHMObjData for the object.
+- //
+-
+- psmod = SHMPTR_TO_TYPED_PTR(SHMObjData, reinterpret_cast<SHMPTR>(rhRemote));
+- if (NULL == psmod)
+- {
+- ERROR("Invalid remote handle\n");
+- palError = ERROR_INVALID_HANDLE;
+- goto ConvertRemoteHandleToLocalExit;
+- }
+-
+- //
+- // Check to see if a local reference for this object already
+- // exists
+- //
+-
+- if (0 != psmod->dwNameLength)
+- {
+- pleObjectList = &m_leNamedObjects;
+- }
+- else
+- {
+- pleObjectList = &m_leAnonymousObjects;
+- }
+-
+- for (PLIST_ENTRY ple = pleObjectList->Flink;
+- ple != pleObjectList;
+- ple = ple->Flink)
+- {
+- pshmobj = CSharedMemoryObject::GetObjectFromListLink(ple);
+-
+- if (SharedObject == pshmobj->GetObjectDomain()
+- && reinterpret_cast<SHMPTR>(rhRemote) == pshmobj->GetShmObjData())
+- {
+- TRACE("Object for remote handle already present in this process\n");
+-
+- //
+- // PAL_LocalHandleToRemote bumped up the process refcount on the
+- // object. Since this process already had a reference to the object
+- // we need to decrement that reference now...
+- //
+-
+- psmod->lProcessRefCount -= 1;
+- _ASSERTE(0 < psmod->lProcessRefCount);
+-
+- //
+- // We also need to add a reference to the object (since ReleaseReference
+- // gets called below)
+- //
+-
+- pshmobj->AddReference();
+-
+- break;
+- }
+-
+- pshmobj = NULL;
+- }
+-
+- if (NULL == pshmobj)
+- {
+- CObjectType *pot;
+- CObjectAttributes oa;
+-
+- //
+- // Get the local instance of the CObjectType
+- //
+-
+- pot = CObjectType::GetObjectTypeById(psmod->eTypeId);
+- if (NULL == pot)
+- {
+- ASSERT("Invalid object type ID in shared memory info\n");
+- goto ConvertRemoteHandleToLocalExit;
+- }
+-
+- //
+- // Create the local state for the shared object
+- //
+-
+- palError = ImportSharedObjectIntoProcess(
+- pthr,
+- pot,
+- &oa,
+- reinterpret_cast<SHMPTR>(rhRemote),
+- psmod,
+- FALSE,
+- &pshmobj
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto ConvertRemoteHandleToLocalExit;
+- }
+- }
+-
+- //
+- // Finally, allocate a local handle for the object
+- //
+-
+- palError = ObtainHandleForObject(
+- pthr,
+- pshmobj,
+- 0,
+- FALSE,
+- NULL,
+- phLocal
+- );
+-
+-ConvertRemoteHandleToLocalExit:
+-
+- SHMRelease();
+- InternalLeaveCriticalSection(pthr, &m_csListLock);
+-
+-ConvertRemoteHandleToLocalExitNoLockRelease:
+-
+- if (NULL != pshmobj)
+- {
+- pshmobj->ReleaseReference(pthr);
+- }
+-
+- LOGEXIT("CSharedMemoryObjectManager::ConvertRemoteHandleToLocal returns %d\n", palError);
+-
+- return palError;
+-}
+-
+-/*++
+-Function:
+- PAL_RemoteHandleToLocal
+-
+- Given a "remote handle", return a local handle that refers to the
+- specified process. Calls
+- SharedMemoryObjectManager::ConvertRemoteHandleToLocal to do the actual
+- work
+-
+-Parameters:
+- rhRemote -- the "remote handle" to convert to a local handle
+---*/
+-
+-PALIMPORT
+-HANDLE
+-PALAPI
+-PAL_RemoteHandleToLocal(IN RHANDLE rhRemote)
+-{
+- PAL_ERROR palError = NO_ERROR;
+- CPalThread *pthr;
+- HANDLE hLocal = INVALID_HANDLE_VALUE;
+-
+- PERF_ENTRY(PAL_RemoteHandleToLocal);
+- ENTRY("PAL_RemoteHandleToLocal( hRemote=0x%lx )\n", rhRemote);
+-
+- pthr = InternalGetCurrentThread();
+-
+- palError = static_cast<CSharedMemoryObjectManager*>(g_pObjectManager)->ConvertRemoteHandleToLocal(
+- pthr,
+- rhRemote,
+- &hLocal
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- pthr->SetLastError(palError);
+- }
+-
+- LOGEXIT("PAL_RemoteHandleToLocal returns HANDLE 0x%lx\n", hLocal);
+- PERF_EXIT(PAL_RemoteHandleToLocal);
+- return hLocal;
+-}
+-
+-/*++
+-Function:
+ CheckObjectTypeAndRights
+
+ Helper routine that determines if:
+diff --git a/src/pal/src/objmgr/shmobjectmanager.hpp b/src/pal/src/objmgr/shmobjectmanager.hpp
+index fbde872..6e11b20 100644
+--- a/src/pal/src/objmgr/shmobjectmanager.hpp
++++ b/src/pal/src/objmgr/shmobjectmanager.hpp
+@@ -71,13 +71,6 @@ namespace CorUnix
+ CPalThread *pthr
+ );
+
+- PAL_ERROR
+- ConvertRemoteHandleToLocal(
+- CPalThread *pthr,
+- RHANDLE rhRemote,
+- HANDLE *phLocal
+- );
+-
+ //
+ // IPalObjectManager routines
+ //
+diff --git a/src/pal/src/synchobj/event.cpp b/src/pal/src/synchobj/event.cpp
+index 54addad..3d15917 100644
+--- a/src/pal/src/synchobj/event.cpp
++++ b/src/pal/src/synchobj/event.cpp
+@@ -35,7 +35,10 @@ CObjectType CorUnix::otManualResetEvent(
+ NULL, // No cleanup routine
+ NULL, // No initialization routine
+ 0, // No immutable data
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ 0, // No process local data
++ NULL, // No process local data cleanup routine
+ 0, // No shared data
+ EVENT_ALL_ACCESS, // Currently ignored (no Win32 security)
+ CObjectType::SecuritySupported,
+@@ -53,7 +56,10 @@ CObjectType CorUnix::otAutoResetEvent(
+ NULL, // No cleanup routine
+ NULL, // No initialization routine
+ 0, // No immutable data
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ 0, // No process local data
++ NULL, // No process local data cleanup routine
+ 0, // No shared data
+ EVENT_ALL_ACCESS, // Currently ignored (no Win32 security)
+ CObjectType::SecuritySupported,
+@@ -506,84 +512,4 @@ OpenEventWExit:
+ PERF_EXIT(OpenEventW);
+
+ return hEvent;
+-}
+-
+-/*++
+-Function:
+- InternalOpenEvent
+-
+-Note:
+- dwDesiredAccess is currently ignored (no Win32 object security support)
+- bInheritHandle is currently ignored (handles to events are not inheritable)
+-
+-Parameters:
+- pthr -- thread data for calling thread
+- phEvent -- on success, receives the allocated event handle
+-
+- See MSDN docs on OpenEvent for all other parameters.
+---*/
+-
+-PAL_ERROR
+-CorUnix::InternalOpenEvent(
+- CPalThread *pthr,
+- DWORD dwDesiredAccess,
+- BOOL bInheritHandle,
+- LPCWSTR lpName,
+- HANDLE *phEvent
+- )
+-{
+- PAL_ERROR palError = NO_ERROR;
+- IPalObject *pobjEvent = NULL;
+- CPalString sObjectName(lpName);
+-
+- _ASSERTE(NULL != pthr);
+- _ASSERTE(NULL != lpName);
+- _ASSERTE(NULL != phEvent);
+-
+- ENTRY("InternalOpenEvent(pthr=%p, dwDesiredAccess=%#x, bInheritHandle=%d, "
+- "lpName=%p, phEvent=%p)\n",
+- pthr,
+- dwDesiredAccess,
+- bInheritHandle,
+- lpName,
+- phEvent
+- );
+-
+- palError = g_pObjectManager->LocateObject(
+- pthr,
+- &sObjectName,
+- &aotEvent,
+- &pobjEvent
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto InternalOpenEventExit;
+- }
+-
+- palError = g_pObjectManager->ObtainHandleForObject(
+- pthr,
+- pobjEvent,
+- dwDesiredAccess,
+- bInheritHandle,
+- NULL,
+- phEvent
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto InternalOpenEventExit;
+- }
+-
+-InternalOpenEventExit:
+-
+- if (NULL != pobjEvent)
+- {
+- pobjEvent->ReleaseReference(pthr);
+- }
+-
+- LOGEXIT("InternalOpenEvent returns %d\n", palError);
+-
+- return palError;
+-}
+-
++}
+\ No newline at end of file
+diff --git a/src/pal/src/synchobj/mutex.cpp b/src/pal/src/synchobj/mutex.cpp
+index 692f5e2..fbbaf17 100644
+--- a/src/pal/src/synchobj/mutex.cpp
++++ b/src/pal/src/synchobj/mutex.cpp
+@@ -49,7 +49,10 @@ CObjectType CorUnix::otMutex(
+ NULL, // No cleanup routine
+ NULL, // No initialization routine
+ 0, // No immutable data
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ 0, // No process local data
++ NULL, // No process local data cleanup routine
+ 0, // No shared data
+ 0, // Should be MUTEX_ALL_ACCESS; currently ignored (no Win32 security)
+ CObjectType::SecuritySupported,
+@@ -69,7 +72,10 @@ CObjectType CorUnix::otNamedMutex(
+ &SharedMemoryProcessDataHeader::PalObject_Close, // Cleanup routine
+ NULL, // No initialization routine
+ sizeof(SharedMemoryProcessDataHeader *), // Immutable data
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ 0, // No process local data
++ NULL, // No process local data cleanup routine
+ 0, // No shared data
+ 0, // Should be MUTEX_ALL_ACCESS; currently ignored (no Win32 security)
+ CObjectType::SecuritySupported,
+diff --git a/src/pal/src/synchobj/semaphore.cpp b/src/pal/src/synchobj/semaphore.cpp
+index b224018..5f8cf72 100644
+--- a/src/pal/src/synchobj/semaphore.cpp
++++ b/src/pal/src/synchobj/semaphore.cpp
+@@ -35,7 +35,10 @@ CObjectType CorUnix::otSemaphore(
+ NULL, // No cleanup routine
+ NULL, // No initialization routine
+ sizeof(SemaphoreImmutableData),
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ 0, // No process local data
++ NULL, // No process local data cleanup routine
+ 0, // No shared data
+ 0, // Should be SEMAPHORE_ALL_ACCESS; currently ignored (no Win32 security)
+ CObjectType::SecuritySupported,
+@@ -597,84 +600,4 @@ OpenSemaphoreW(
+ PERF_EXIT(OpenSemaphoreW);
+
+ return hSemaphore;
+-}
+-
+-/*++
+-Function:
+- InternalOpenSemaphore
+-
+-Note:
+- dwDesiredAccess is currently ignored (no Win32 object security support)
+- bInheritHandle is currently ignored (handles to semaphores are not inheritable)
+-
+-Parameters:
+- pthr -- thread data for calling thread
+- phEvent -- on success, receives the allocated semaphore handle
+-
+- See MSDN docs on OpenSemaphore for all other parameters.
+---*/
+-
+-PAL_ERROR
+-CorUnix::InternalOpenSemaphore(
+- CPalThread *pthr,
+- DWORD dwDesiredAccess,
+- BOOL bInheritHandle,
+- LPCWSTR lpName,
+- HANDLE *phSemaphore
+- )
+-{
+- PAL_ERROR palError = NO_ERROR;
+- IPalObject *pobjSemaphore = NULL;
+- CPalString sObjectName(lpName);
+-
+- _ASSERTE(NULL != pthr);
+- _ASSERTE(NULL != lpName);
+- _ASSERTE(NULL != phSemaphore);
+-
+- ENTRY("InternalOpenSemaphore(pthr=%p, dwDesiredAccess=%d, bInheritHandle=%d, "
+- "lpName=%p, phSemaphore=%p)\n",
+- pthr,
+- dwDesiredAccess,
+- bInheritHandle,
+- phSemaphore
+- );
+-
+- palError = g_pObjectManager->LocateObject(
+- pthr,
+- &sObjectName,
+- &aotSempahore,
+- &pobjSemaphore
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto InternalOpenSemaphoreExit;
+- }
+-
+- palError = g_pObjectManager->ObtainHandleForObject(
+- pthr,
+- pobjSemaphore,
+- dwDesiredAccess,
+- bInheritHandle,
+- NULL,
+- phSemaphore
+- );
+-
+- if (NO_ERROR != palError)
+- {
+- goto InternalOpenSemaphoreExit;
+- }
+-
+-InternalOpenSemaphoreExit:
+-
+- if (NULL != pobjSemaphore)
+- {
+- pobjSemaphore->ReleaseReference(pthr);
+- }
+-
+- LOGEXIT("InternalOpenSemaphore returns %d\n", palError);
+-
+- return palError;
+-}
+-
+-
++}
+\ No newline at end of file
+diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp
+index e22d268..e882cba 100644
+--- a/src/pal/src/thread/process.cpp
++++ b/src/pal/src/thread/process.cpp
+@@ -78,11 +78,14 @@ using namespace CorUnix;
+
+ CObjectType CorUnix::otProcess(
+ otiProcess,
+- NULL,
+- NULL,
+- 0,
++ NULL, // No cleanup routine
++ NULL, // No initialization routine
++ 0, // No immutable data
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ sizeof(CProcProcessLocalData),
+- 0,
++ NULL, // No process local data cleanup routine
++ 0, // No shared data
+ PROCESS_ALL_ACCESS,
+ CObjectType::SecuritySupported,
+ CObjectType::SecurityInfoNotPersisted,
+diff --git a/src/pal/src/thread/thread.cpp b/src/pal/src/thread/thread.cpp
+index df42ebc..15de659 100644
+--- a/src/pal/src/thread/thread.cpp
++++ b/src/pal/src/thread/thread.cpp
+@@ -130,10 +130,13 @@ CObjectType CorUnix::otThread(
+ otiThread,
+ ThreadCleanupRoutine,
+ ThreadInitializationRoutine,
+- 0, //sizeof(CThreadImmutableData),
++ 0, // sizeof(CThreadImmutableData),
++ NULL, // No immutable data copy routine
++ NULL, // No immutable data cleanup routine
+ sizeof(CThreadProcessLocalData),
+- 0, //sizeof(CThreadSharedData),
+- 0, // THREAD_ALL_ACCESS,
++ NULL, // No process local data cleanup routine
++ 0, // sizeof(CThreadSharedData),
++ 0, // THREAD_ALL_ACCESS,
+ CObjectType::SecuritySupported,
+ CObjectType::SecurityInfoNotPersisted,
+ CObjectType::UnnamedObject,
+--
+2.7.4
+