1 #include "ace/OS_NS_stdio.h"
4 #include "ace/MMAP_Memory_Pool.h"
5 #include "ace/Hash_Map_With_Allocator_T.h"
6 #include "ace/Malloc_T.h"
7 #include "ace/PI_Malloc.h"
8 #include "ace/Process_Mutex.h"
9 #include "ace/Process.h"
11 #define BACKING_STORE "map.store"
12 #define MAP_NAME "records.db"
16 typedef ACE_Allocator_Adapter
<ACE_Malloc_T
<ACE_MMAP_MEMORY_POOL
,
20 typedef ACE_Hash_Map_With_Allocator
<int, Record
> HASH_MAP
;
22 ACE_Process_Mutex
coordMutex("Coord-Mutex");
25 // Listing 2 code/ch17
26 HASH_MAP
* smap (ALLOCATOR
*shmem_allocator
)
29 if (shmem_allocator
->find (MAP_NAME
, db
) == 0)
30 return (HASH_MAP
*) db
;
31 size_t hash_table_size
= sizeof (HASH_MAP
);
32 void *hash_map
= shmem_allocator
->malloc (hash_table_size
);
35 new (hash_map
) HASH_MAP (hash_table_size
, shmem_allocator
);
36 if (shmem_allocator
->bind (MAP_NAME
, hash_map
) == -1)
38 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"),
39 ACE_TEXT ("allocate_map")));
40 shmem_allocator
->remove ();
43 return (HASH_MAP
*)hash_map
;
46 // Listing 6 code/ch17
47 int processRecords (HASH_MAP
*map
, ALLOCATOR
*shmem_allocator
)
49 ACE_TRACE ("processRecords");
51 size_t mapLength
= map
->current_size ();
53 ACE_TEXT ("(%P|%t) Found %d records\n\n"),
56 int *todelete
= new int[mapLength
];
59 for (HASH_MAP::iterator iter
= map
->begin ();
63 int key
= (*iter
).ext_id_
;
65 ACE_TEXT ("(%P|%t) [%d] Preprocessing %d:%@\n"),
66 i
+1, key
, &(*iter
).ext_id_
));
68 todelete
[i
++] = key
; // Mark message for deletion.
70 // Illustrate the find feature of the map.
72 int result
= map
->find (key
, record
, shmem_allocator
);
75 ACE_TEXT ("Could not find record for %d\n"),
79 ACE_TEXT ("Record name: %C|id1:%d|id2:%d\n"),
80 record
.name (), record
.id1(), record
.id2()));
83 // Delete everything we processed.
84 for (int j
= 0; j
< i
; j
++)
86 int result
= map
->unbind (todelete
[j
],
89 ACE_ERROR_RETURN ((LM_ERROR
,
90 ACE_TEXT ("Failed on key %d: %p\n"),
96 ACE_TEXT ("Fully processed and removed %d\n"),
105 // Listing 4 code/ch17
106 int addRecords(HASH_MAP
*map
, ALLOCATOR
*shmem_allocator
)
108 ACE_TRACE ("addRecords");
111 int mapLength
= static_cast<int> (map
->current_size ());
112 ACE_DEBUG ((LM_DEBUG
,
113 ACE_TEXT ("Map has %d entries; adding 20 more\n"),
116 for (int i
= mapLength
; i
< mapLength
+ 20; i
++)
118 ACE_OS::sprintf (buf
, "%s:%d", "Record", i
);
120 // Allocate new record on stack;
121 Record
newRecord (i
, i
+1, buf
);
122 ACE_DEBUG ((LM_DEBUG
,
123 ACE_TEXT ("Adding a record for %d\n"), i
));
125 int result
= map
->bind (i
, newRecord
, shmem_allocator
);
127 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
128 ACE_TEXT ("bind failed")), -1);
134 // Listing 5 code/ch17
137 ACE_TRACE ("handle_child");
139 ACE_GUARD_RETURN (ACE_Process_Mutex
, ace_mon
, coordMutex
, -1);
141 ALLOCATOR
* shmem_allocator
= 0;
142 ACE_MMAP_Memory_Pool_Options options
143 (ACE_DEFAULT_BASE_ADDR
,
144 ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED
);
146 ACE_NEW_RETURN (shmem_allocator
,
147 ALLOCATOR (BACKING_STORE
,
152 HASH_MAP
*map
= smap (shmem_allocator
);
154 ACE_DEBUG ((LM_DEBUG
,
155 ACE_TEXT ("(%P|%t) Map has %d entries\n"),
156 map
->current_size ()));
157 ACE_DEBUG ((LM_DEBUG
,
158 ACE_TEXT ("In child, map is located at %@\n"),
161 processRecords (map
, shmem_allocator
);
162 shmem_allocator
->sync ();
163 delete shmem_allocator
;
168 // Listing 3 code/ch17
169 int handle_parent (ACE_TCHAR
*cmdLine
)
171 ACE_TRACE ("handle_parent");
173 ALLOCATOR
* shmem_allocator
= 0;
174 ACE_MMAP_Memory_Pool_Options options
175 (ACE_DEFAULT_BASE_ADDR
,
176 ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED
);
180 ALLOCATOR (BACKING_STORE
, BACKING_STORE
, &options
),
183 HASH_MAP
*map
= smap (shmem_allocator
);
185 ACE_Process processa
, processb
;
186 ACE_Process_Options poptions
;
187 const ACE_TCHAR
*args
[3];
189 args
[1] = ACE_TEXT ("a");
191 poptions
.command_line (args
);
193 ACE_GUARD_RETURN (ACE_Process_Mutex
, ace_mon
,
195 ACE_DEBUG ((LM_DEBUG
,
196 ACE_TEXT ("(%P|%t) Map has %d entries\n"),
197 map
->current_size ()));
198 ACE_DEBUG ((LM_DEBUG
,
199 ACE_TEXT ("In parent, map is located at %@\n"),
202 // Then have the child show and eat them up.
203 processa
.spawn (poptions
);
205 // First append a few records.
206 addRecords (map
, shmem_allocator
);
211 ACE_GUARD_RETURN (ACE_Process_Mutex
, ace_mon
,
214 // Add a few more records..
215 addRecords (map
, shmem_allocator
);
217 // Let's see what's left.
218 ACE_DEBUG ((LM_DEBUG
,
219 ACE_TEXT ("(%P|%t) Parent finished adding, ")
220 ACE_TEXT ("map has %d entries\n"),
221 map
->current_size ()));
223 // Have another child try to eat them up.
224 processb
.spawn (poptions
);
230 // No processes are left and we don't want to keep the data
231 // around anymore; it's now safe to remove it.
232 // !!This will remove the backing store.!!
233 shmem_allocator
->remove ();
234 delete shmem_allocator
;
238 int ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
240 if (argc
== 1) // parent
241 ACE_ASSERT (handle_parent (argv
[0]) == 0);
243 ACE_ASSERT (handle_child () == 0);
245 ACE_UNUSED_ARG (argv
);