<!-- page04.html,v 1.8 2000/03/19 20:09:34 jcej Exp --> <HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Author" CONTENT="James CE Johnson"> <TITLE>ACE Tutorial 021</TITLE> </HEAD> <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> <CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> <CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> <P> <HR WIDTH="100%"> Everything common the server & client is kept here. In particular, the Constants class where we keep the names & semaphore keys. <p> The Allocator class is just a thin wrapper around ACE_Malloc<> that moves some of the details out of the application logic. <hr> <PRE> <font color=red>// page04.html,v 1.8 2000/03/19 20:09:34 jcej Exp</font> <font color=blue>#ifndef</font> <font color=purple>MPOOL_H</font> <font color=blue>#define</font> <font color=purple>MPOOL_H</font> <font color=red>// Everything else we need is in this one header</font> <font color=blue>#include</font> "<A HREF="../../../ace/Malloc.h">ace/Malloc.h</A>" <font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_SYSV_SHMEM</font>) <font color=red>/* With this we will abstract away some of the details of the memory pool. Note that we don't treat this as a singleton because an application may need more than one pool. Each would have a different name and be used for different purposes. */</font> class Allocator { public: <font color=red>// The pool name will be used to create a unique semaphore to</font> <font color=red>// keep this pool separate from others.</font> Allocator (const char * _name = "<font color=green>MemoryPool</font>"); ~Allocator (void); typedef ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple> pool_t; <font color=red>// Provide an accessor to the pool. This will also allocate the</font> <font color=red>// pool when first invoked.</font> pool_t &pool (void); protected: <font color=red>// The name we gave to the pool</font> char *name_; pool_t *pool_; }; <font color=red>/* The client and server need to agree on a certain set of values. By placing them in the Constants class we can eliminate a bit of confusion. */</font> class Constants { public: <font color=red>// The semaphore keys are needed for the two semaphores that</font> <font color=red>// synch access to the shared memory area.</font> static const int SEM_KEY_1; static const int SEM_KEY_2; <font color=red>// How big the pool will be and what we'll put into it. A real</font> <font color=red>// app wouldn't need SHMDATA of course.</font> static const int SHMSZ; static const char *SHMDATA; <font color=red>// The name assigned to the memory pool by the server is needed</font> <font color=red>// by the client. Without it, the pool cannot be found.</font> <font color=red>// Likewise, the name the server will bind() to the region of the</font> <font color=red>// pool must be available to the client.</font> static const char *PoolName; static const char *RegionName; }; <font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font> <font color=blue>#endif</font> <font color=red>/* MPOOL_H */</font> </PRE> <HR> The really hard stuff is done by the ACE_Malloc<> template. This template takes two parameters.<sup>*</sup> The first is a memory pool class to use. ACE has several, I've choosen one that uses a memory-mapped file. The second parameter is a lock class of some sort. This is needed so that the ACE_Malloc<> can protect its internal data. Note that you still have to provide your own mutex around the data you put into the malloc'd area. <P> * Actually, some implementations may require a different number of parameters. That's why ACE uses those funky macros. ACE_MMAP_MEMORY_POOL for instance turns into ACE_MMAP_Memory_Pool on Linux but may do other things on your platform. <P><HR WIDTH="100%"> <CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>