// // 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