summaryrefslogtreecommitdiff
path: root/docs/tutorials/019/page04.html
blob: 79f00aefbb7f3017e57f5718ca1672c3e28d32b7 (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
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="James CE Johnson">
   <TITLE>ACE Tutorial 019</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">

<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER>

<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER>

<P>
<HR WIDTH="100%">
      Before we move on to shmem.h, I want to show a different approach.  In 
      this new client/server pair, I use placement new to stuff an object
      (instead of a blob of bytes) into the shared memory segment.
    <P>
      There are a few caveats to putting objects into shared memory.  The
      most important ones all deal with pointers:
    <ul>
      <li>Be sure your pointers point into the shared memory and not
        local process memory.
      <li>Only in very special cases will objects with virtual methods 
        work (because of the VTable pointers).
    </ul>
<P>
That's not to say you shouldn't try...  Just try carefully and test a lot!
    <HR>
<HR width=50%><P><center>server2.cpp</center><HR width=50%>
<PRE>
<font color=red>// $Id$</font>

<font color=blue>#include</font> "<font color=green>shmem.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 Shared Memory not available on this platform\n</font>"),
                    100);
}
#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
int 
main (int, char *argv[])
{
  <font color=red>// Be sure the segment is sized to hold our object.</font>
  ACE_Shared_Memory_SV shm_server (SHM_KEY,
                                   sizeof (SharedData), 
                                   <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>);
  char *shm = (char *) shm_server.malloc ();

  if (shm == 0)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>%p\n\t(%P|%t) Cannot create shared memory segment.\n</font>"
                       "<font color=green>\tUse 'ipcs' to see if it already exists\n</font>", 
                       argv[0]),
                      100);

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

  <font color=red>/*
    Use the placement new syntax to stuff the object into the
    correct location.  I think they generally reserve this for
    the advanced class...
    */</font>
  SharedData *sd = new (shm) SharedData;

  <font color=red>// Use the set() method to put some data into the object</font>
  sd->set ();

  <font color=red>// Set the 'available' flag to zero so that we can wait on it</font>
  sd->available (0);

  <font color=red>/*
    Another cheesy busy loop while we wait for the object to
    become available.  The cool way would be to hide a semaphore 
    or two behind this method call & eliminate the sleep.
    */</font>
  while (sd->available () == 0)
    <font color=#008888>ACE_OS::sleep</font> (1);

  <font color=red>// Show the user what's in the segment</font>
  sd->show ();

  <font color=red>// All done.</font>
  if (shm_server.remove () &lt; 0)
    ACE_ERROR ((LM_ERROR,
                "<font color=green>%p\n</font>",
                "<font color=green>remove</font>"));
  return 0;
}

<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<HR width=50%><P><center>client2.cpp</center><HR width=50%>
<PRE>
<font color=red>// $Id$</font>

<font color=blue>#include</font> "<font color=green>shmem.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 Shared Memory not available on this platform\n</font>"),
                    100);
}
#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
int 
main (int, char *[])
{
  ACE_Shared_Memory_SV shm_client (SHM_KEY,
                                   sizeof (SharedData));
    
  char *shm = (char *) shm_client.malloc ();

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

  <font color=red>/*
    More placement new.  The constructor parameter prevents
    clobbering what the server may have written with it's show() 
    method.
    */</font>
  SharedData *sd = new (shm) SharedData (0);

  <font color=red>// Show it</font>
  sd->show ();

  <font color=red>// Change it</font>
  sd->set ();

  <font color=red>// Advertise it</font>
  sd->available (1);

  shm_client.close ();
        
  return 0;
}

<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="page05.html">Continue This Tutorial</A>]</CENTER>