Update copyright to LGPL on all files
[dyninst.git] / valueAdded / sharedMem / src / shmSegment-nt.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 //----------------------------------------------------------------------------
32 // $Id: shmSegment-nt.C,v 1.1 2006/11/22 21:45:01 bernat Exp $
33 //----------------------------------------------------------------------------
34 //
35 // Definition of the ShmSegment class.
36 // A ShmSegment object represents a shared memory segment, providing an
37 // OS-independent interface to management of shared memory segments to 
38 // paradynd.
39 //
40 //----------------------------------------------------------------------------
41 #include "common/h/headers.h"
42 #include "common/h/std_namesp.h"
43 #include "shmSegment.h"
44
45
46 //----------------------------------------------------------------------------
47 // Prototypes of local functions
48 //----------------------------------------------------------------------------
49 static  BuildSegmentName( key_t key, unsigned int size, char* buffer );
50
51
52
53
54 //
55 // ShmSegment::~ShmSegment
56 //
57 // Release shared memory segment.
58 // 
59 ShmSegment::~ShmSegment( void )
60 {
61     assert( seg_addr != NULL );
62     assert( seg_id != NULL );
63
64     // unmap the segment from our address space
65     if( !UnmapViewOfFile( seg_addr ) )
66     {
67 #if READY
68         indicate error to user?  how?
69 #endif // READY
70     }
71
72     if(! leaveSegmentAroundOnExit) {  
73        // release the segment
74        if( !CloseHandle( seg_id ) )
75        {
76 #if READY
77        // indicate error to user? how?
78 #endif // READY
79        }
80     }
81 }
82
83
84
85 //
86 // ShmSegment::Create
87 //
88 // Access a shared memory segment whose name is based on the value
89 // of the given key, of at least the indicated size, and mapped into
90 // our address space at the indicated address (if specified).
91 // 
92 ShmSegment*
93 ShmSegment::Create( key_t& key, unsigned int size, void* addr )
94 {
95     ShmSegment* seg = NULL;
96     key_t curr_key = key;
97     HANDLE hMapping = NULL;
98
99
100     while( true )
101     {
102         // attempt to create a shared memory segment
103         // with a name based on "key"
104         char segName[32];
105
106         BuildSegmentName( curr_key, size, segName );
107         hMapping = CreateFileMapping( INVALID_HANDLE_VALUE,  // shared memory
108             NULL,
109             PAGE_READWRITE,
110             0, size,
111             segName );
112         if( hMapping == NULL )
113         {
114             // unable to create segment
115 #if READY
116             indicate error to user?
117 #else
118         cerr << "Failed to create file mapping object : " << GetLastError() << endl;
119 #endif // READY
120         }
121         else if( GetLastError() == ERROR_ALREADY_EXISTS )
122         {
123             // we were trying to create a new segment,
124             // but we found an existing one
125             CloseHandle( hMapping );
126             hMapping = NULL;
127         }
128         else
129         {
130             // we created the new mapping successfully
131             key = curr_key;
132             break;
133         }
134
135         // try the next key
136         curr_key++;
137     }
138
139     // we have a mapping object, now map it into our address space
140     assert( hMapping != NULL );
141     void* mapAddr = MapViewOfFile( hMapping,
142                                     FILE_MAP_ALL_ACCESS,
143                                     0, 0,
144                                     0 );
145     if( mapAddr != NULL )
146     {
147         // we mapped the object successfully
148         // build an object to represent the segment
149         seg = new ShmSegment( hMapping, curr_key, size, mapAddr );
150     }
151     else
152     {
153 #if READY
154         indicate failure to user
155 #else
156         cerr << "Failed to map shared memory into address space : " << GetLastError() << endl;
157 #endif // READY
158         CloseHandle( hMapping );
159     }
160     
161     return seg;
162 }
163
164
165
166 //
167 // ShmSegment::Open
168 //
169 // Open and attach to an existing shared memory segment, whose name
170 // is based on the given key, of at least the indicated size, and 
171 // map it into our address space at the indcated address (if given).
172 //
173 ShmSegment*
174 ShmSegment::Open( key_t key, unsigned int size, void* addr )
175 {
176     HANDLE hMapping = NULL;
177     ShmSegment* shm = NULL;
178     char segName[32];
179
180
181     BuildSegmentName( key, size, segName );
182     hMapping = OpenFileMapping( PAGE_READWRITE, FALSE, segName );
183     if( hMapping != NULL )
184     {
185         // we opened the existing mapping object,
186         // now we need to map it into our address space
187         void* mapAddr = MapViewOfFile( hMapping,      // map object
188                                         FILE_MAP_ALL_ACCESS,    // permissions
189                                         0, 0,                   // high and low offsets of map start address
190                                         0 );                    // map entire file
191         if( mapAddr != NULL )
192         {
193             // build an object to represent the segment
194             shm = new ShmSegment( hMapping, key, size, mapAddr );
195         }
196         else
197         {
198 #if READY
199             indicate failure to user?
200 #else
201             cerr << "Failed to map shared memory into address space : " << GetLastError() << endl;
202 #endif // READY
203             CloseHandle( hMapping );
204             hMapping = NULL;
205         }
206     }
207     else
208     {
209 #if READY
210         indicate failure to user?
211 #else
212         cerr << "Failed to create file mapping object : " << GetLastError() << endl;
213 #endif // READY
214     }
215
216     return shm;
217 }
218
219
220
221 //
222 // BuildSegmentName
223 //
224 // Build a name for a named shared memory semgent based on the 
225 // given key value and size.
226 //
227 static
228 BuildSegmentName( key_t key, unsigned int size, char* buffer )
229 {
230     sprintf( buffer, "ParadynD_%d_%d", key, size );
231 }
232
233
234