//
// Copyright 2005 The Android Open Source Project
//
// Inter-process shared memory.
//
#ifndef __LIBS_SHMEM_H
#define __LIBS_SHMEM_H
#ifdef HAVE_ANDROID_OS
#error DO NOT USE THIS FILE IN THE DEVICE BUILD
#endif
#include "Semaphore.h"
namespace android {
/*
* Platform-independent shared memory. Each object can be used to
* create a chunk of memory that is shared between processes.
*
* For convenience, a semaphore is associated with each segment.
* (Whether this should have been done in a subclass is debatable.)
*
* The "key" is usually the process ID of the process that created the
* segment. The goal is to avoid clashing with other processes that are
* trying to do the same thing. It's a little awkward to use when you
* want to have multiple shared segments created in one process. In
* SysV you can work around this by using a "private" key and sharing
* the shmid with your friends, in Win32 you can use a string, but we're
* in lowest-common-denominator mode here. Assuming we have 16-bit PIDs,
* the upper 16 bits can be used to serialize keys.
*
* When the object goes out of scope, the shared memory segment is
* detached from the process. If the object was responsible for creating
* the segment, it is also marked for destruction on SysV systems. This
* will make it impossible for others to attach to.
*
* On some systems, the length returned by getLength() may be different
* for parent and child due to page size rounding.
*/
class Shmem {
public:
Shmem(void);
virtual ~Shmem(void);
/*
* Create a new shared memory segment, with the specified size. If
* "deleteExisting" is set, any existing segment will be deleted first
* (useful for SysV IPC).
*
* Returns "true" on success, "false" on failure.
*/
bool create(int key, long size, bool deleteExisting);
/*
* Attach to a shared memory segment. Use this from the process that
* didn't create the segment.
*
* Returns "true" on success, "false" on failure.
*/
bool attach(int key);
/*
* Get the memory segment address and length. These will not change
* for the lifetime of the object, so it's okay to cache the results.
*
* On failure, getAddr() returns NULL and getLength() returns -1.
*/
void* getAddr(void);
long getLength(void);
/*
* Lock or unlock the shared memory segment. This is useful if you
* are updating pieces of shared data. The segment is initially
* "unlocked".
*
* This does *not* lock down the segment in the virtual paging system.
* It's just a mutex.
*/
void lock(void);
void unlock(void);
bool tryLock(void);
private:
Semaphore mSem; // uses the same value for "key"
unsigned long mHandle; // shmid(int) or HANDLE
void* mAddr; // address
long mLength; // length of segment (cached)
bool mCreator; // true if we created the segment
int mKey; // key passed in as arg
};
}; // namespace android
#endif // __LIBS_SHMEM_H