summaryrefslogtreecommitdiff
path: root/docs/tutorials/021/page03.html
blob: 03347b633c0c87dbd02a65d29c825e1688362bbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<!-- $Id$ -->
<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%">
    The client side is a little simpler than the server.  Mainly
    because we don't try to delete the pool:
  <ul>
    <li>Create an Allocator to access the pool
    <li>Find the named region
  </ul>
<hr>
<PRE>

<font color=red>// $Id$</font>

<font color=blue>#include</font> "<font color=green>mpool.h</font>"

<font color=blue>#if defined</font>(<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
int
main (int, char *[])
{
  ACE_ERROR_RETURN ((LM_ERROR,
                     "<font color=green>System V Semaphores not available on this platform.\n</font>"),100);
}
#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
int
main (int, char *[])
{
  <font color=red>/*
    Use the same pool name used by the server when we create our
    Allocator.  This assures us that we don't create a whole new
    pool.
    */</font>
  Allocator allocator (<font color=#008888>Constants::PoolName</font>);

  <font color=red>/*
    You can put anything in the memory pool.  Not just the
    character array we want.  The find() method till, therefore,
    return a void* that we will have to cast.
    */</font>
  void *region;

  <font color=red>/*
    We use find() to locate a named region in the pool.  This is
    the counterpart to bind() used in the server.
    Here, we go try to find the region that the server has created
    and filled with data.  If there was a problem getting the pool
    or finding the region, we'll get back -1 from find().
    */</font>
  if (allocator.pool ().find (<font color=#008888>Constants::RegionName</font>,region) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>Cannot find the name '%s'\n</font>",
                       <font color=#008888>Constants::RegionName</font>),
                      100);

  <font color=red>/*
    Since find() returns us a void*, we cast it here to the char*
    that we want.
    */</font>
  char *shm = (char *) region;

  ACE_DEBUG ((LM_INFO,
              "<font color=green>Shared memory is at 0x%x\n</font>",
              shm));

  <font color=red>/*
    The same pair of semaphores as used by the server are created
    here.  We probably don't need the CREATE flag since the server
    should have already done that.  There may be some very small
    windows, however, where the server would have created the
    memory pool but not yet gotten to the semaphores.
    */</font>
  ACE_SV_Semaphore_Complex mutex;
  ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>,
                          <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>,
                          0) != -1);

  ACE_SV_Semaphore_Complex synch;
  ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>,
                          <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>,
                          0) != -1);

  <font color=red>/*
    It doesn't matter if we created 'mutex' or if the server did.
    In either case, it was created in a locked state and we will
    block here until somebody unlocks it.  In our scenario, that
    will have to be the server.
    */</font>
  if (mutex.acquire () == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>(%P) client mutex.acquire</font>"),
                      1);

  <font color=red>/*
    Now that we know it is safe to access the data, we'll run
    through and make sure that it contains what we think the server
    supplied.
    */</font>
  for (int i = 0; i &lt; <font color=#008888>Constants::SHMSZ</font>; i++)
    ACE_ASSERT (<font color=#008888>Constants::SHMDATA</font>[i] == shm[i]);

  <font color=red>/*
    Look back at the server.  After filling the region, it will
    attempt to acquire the lock on 'synch'.  It will wait there
    until we release() the semaphore.  That will allow it to remove
    the pool and cleanup.  We can simply exit once we perform the
    release. (Ok, a free() of the region would probably be polite...)
    */</font>
  if (synch.release () == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>(%P) client synch.release</font>"),
                      1);

  return 0;
}

<font color=red>/*
  Again, we have the necessary explicit template instantiations
  because I based this on an ACE example instead of creating it from scratch.
 */</font>
<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>)
template class ACE_Malloc&lt;ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple>;
template class ACE_Malloc_T&lt;ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple, ACE_Control_Block>;
template class ACE_Guard&lt;ACE_SV_Semaphore_Simple>;
template class ACE_Write_Guard&lt;ACE_SV_Semaphore_Simple>;
template class ACE_Read_Guard&lt;ACE_SV_Semaphore_Simple>;
<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>)
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Malloc&lt;ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple>
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Malloc_T&lt;ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple, ACE_Control_Block>
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Write_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Read_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font>

<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>