2009-12-04 21:45:15 +03:00
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim : sw = 2 ts = 8 et :
*/
2012-05-21 15:12:37 +04:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
2009-12-04 21:45:15 +03:00
# ifndef mozilla_ipc_SharedMemory_h
# define mozilla_ipc_SharedMemory_h
# include "nsDebug.h"
2010-05-22 23:35:32 +04:00
# include "nsISupportsImpl.h" // NS_INLINE_DECL_REFCOUNTING
2012-07-06 22:15:45 +04:00
# include "mozilla/Attributes.h"
2009-12-04 21:45:15 +03:00
2016-02-18 18:56:15 +03:00
# include "base/process.h"
# include "chrome/common/ipc_message_utils.h"
2009-12-04 21:45:15 +03:00
//
// This is a low-level wrapper around platform shared memory. Don't
// use it directly; use Shmem allocated through IPDL interfaces.
//
namespace {
enum Rights {
RightsNone = 0 ,
RightsRead = 1 < < 0 ,
RightsWrite = 1 < < 1
} ;
2015-07-13 18:25:42 +03:00
} // namespace
2009-12-04 21:45:15 +03:00
namespace mozilla {
2014-06-19 06:29:00 +04:00
namespace ipc {
class SharedMemory ;
2015-07-13 18:25:42 +03:00
} // namespace ipc
2014-06-19 06:29:00 +04:00
2009-12-04 21:45:15 +03:00
namespace ipc {
2010-04-16 09:29:16 +04:00
class SharedMemory
2009-12-04 21:45:15 +03:00
{
2014-07-28 20:56:54 +04:00
protected :
2014-02-27 01:23:51 +04:00
virtual ~ SharedMemory ( )
{
Unmapped ( ) ;
Destroyed ( ) ;
}
2014-07-28 20:56:54 +04:00
public :
2010-04-16 09:29:16 +04:00
enum SharedMemoryType {
TYPE_BASIC ,
TYPE_UNKNOWN
} ;
2009-12-04 21:45:15 +03:00
2010-11-05 10:17:07 +03:00
size_t Size ( ) const { return mMappedSize ; }
2009-12-04 21:45:15 +03:00
2010-04-16 09:29:16 +04:00
virtual void * memory ( ) const = 0 ;
2009-12-04 21:45:15 +03:00
2010-04-16 09:29:16 +04:00
virtual bool Create ( size_t size ) = 0 ;
virtual bool Map ( size_t nBytes ) = 0 ;
2016-02-18 18:56:15 +03:00
virtual void CloseHandle ( ) = 0 ;
2010-04-16 09:29:16 +04:00
virtual SharedMemoryType Type ( ) const = 0 ;
2009-12-04 21:45:15 +03:00
2016-02-18 18:56:15 +03:00
virtual bool ShareHandle ( base : : ProcessId aProcessId , IPC : : Message * aMessage ) = 0 ;
virtual bool ReadHandle ( const IPC : : Message * aMessage , void * * aIter ) = 0 ;
2009-12-04 21:45:15 +03:00
void
Protect ( char * aAddr , size_t aSize , int aRights )
{
char * memStart = reinterpret_cast < char * > ( memory ( ) ) ;
if ( ! memStart )
NS_RUNTIMEABORT ( " SharedMemory region points at NULL! " ) ;
char * memEnd = memStart + Size ( ) ;
char * protStart = aAddr ;
if ( ! protStart )
NS_RUNTIMEABORT ( " trying to Protect() a NULL region! " ) ;
char * protEnd = protStart + aSize ;
if ( ! ( memStart < = protStart
& & protEnd < = memEnd ) )
NS_RUNTIMEABORT ( " attempt to Protect() a region outside this SharedMemory " ) ;
// checks alignment etc.
SystemProtect ( aAddr , aSize , aRights ) ;
}
2015-05-27 18:20:26 +03:00
// bug 1168843, compositor thread may create shared memory instances that are destroyed by main thread on shutdown, so this must use thread-safe RC to avoid hitting assertion
NS_INLINE_DECL_THREADSAFE_REFCOUNTING ( SharedMemory )
2010-05-22 23:35:32 +04:00
2009-12-04 21:45:15 +03:00
static void SystemProtect ( char * aAddr , size_t aSize , int aRights ) ;
static size_t SystemPageSize ( ) ;
2010-11-05 10:17:07 +03:00
static size_t PageAlignedSize ( size_t aSize ) ;
2010-11-05 10:17:07 +03:00
protected :
SharedMemory ( ) ;
// Implementations should call these methods on shmem usage changes,
// but *only if* the OS-specific calls are known to have succeeded.
// The methods are expected to be called in the pattern
//
// Created (Mapped Unmapped)* Destroy
//
// but this isn't checked.
2010-11-05 10:17:07 +03:00
void Created ( size_t aNBytes ) ;
void Mapped ( size_t aNBytes ) ;
void Unmapped ( ) ;
void Destroyed ( ) ;
// The size of the shmem region requested in Create(), if
2010-11-05 10:21:30 +03:00
// successful. SharedMemory instances that are opened from a
// foreign handle have an alloc size of 0, even though they have
// access to the alloc-size information.
2010-11-05 10:17:07 +03:00
size_t mAllocSize ;
// The size of the region mapped in Map(), if successful. All
// SharedMemorys that are mapped have a non-zero mapped size.
size_t mMappedSize ;
2009-12-04 21:45:15 +03:00
} ;
2016-02-18 18:56:15 +03:00
template < typename HandleImpl >
class SharedMemoryCommon : public SharedMemory
{
public :
typedef HandleImpl Handle ;
virtual bool ShareToProcess ( base : : ProcessId aProcessId , Handle * aHandle ) = 0 ;
virtual bool IsHandleValid ( const Handle & aHandle ) const = 0 ;
virtual bool SetHandle ( const Handle & aHandle ) = 0 ;
virtual bool ShareHandle ( base : : ProcessId aProcessId , IPC : : Message * aMessage ) override
{
Handle handle ;
if ( ! ShareToProcess ( aProcessId , & handle ) ) {
return false ;
}
IPC : : WriteParam ( aMessage , handle ) ;
return true ;
}
virtual bool ReadHandle ( const IPC : : Message * aMessage , void * * aIter ) override
{
Handle handle ;
return IPC : : ReadParam ( aMessage , aIter , & handle ) & &
IsHandleValid ( handle ) & &
SetHandle ( handle ) ;
}
} ;
2009-12-04 21:45:15 +03:00
} // namespace ipc
} // namespace mozilla
# endif // ifndef mozilla_ipc_SharedMemory_h