39
39
#include " shared_memory.h"
40
40
#include " shared_memory_handle.h"
41
41
42
+ #define TRITON_SHM_FILE_ROOT " C:\\ triton_shm\\ "
43
+
42
44
// ==============================================================================
43
45
// SharedMemoryControlContext
44
46
namespace {
45
47
46
48
void *
47
49
SharedMemoryHandleCreate (
48
50
std::string triton_shm_name, void * shm_addr, std::string shm_key,
49
- ShmFile* shm_file, size_t offset, size_t byte_size)
51
+ std::unique_ptr< ShmFile>&& shm_file, size_t offset, size_t byte_size)
50
52
{
51
53
SharedMemoryHandle* handle = new SharedMemoryHandle ();
52
54
handle->triton_shm_name_ = triton_shm_name;
53
55
handle->base_addr_ = shm_addr;
54
56
handle->shm_key_ = shm_key;
55
- handle->platform_handle_ . reset (shm_file);
57
+ handle->platform_handle_ = std::move (shm_file);
56
58
handle->offset_ = offset;
57
59
handle->byte_size_ = byte_size;
58
60
return static_cast <void *>(handle);
@@ -73,14 +75,14 @@ SharedMemoryRegionMap(
73
75
DWORD low_order_offset = upperbound_offset & 0xFFFFFFFF ;
74
76
// map shared memory to process address space
75
77
*shm_addr = MapViewOfFile (
76
- shm_file->shm_handle_ , // handle to map object
77
- FILE_MAP_ALL_ACCESS, // read/write permission
78
- high_order_offset, // offset (high-order DWORD)
79
- low_order_offset, // offset (low-order DWORD)
78
+ shm_file->shm_mapping_handle_ , // handle to map object
79
+ FILE_MAP_ALL_ACCESS, // read/write permission
80
+ high_order_offset, // offset (high-order DWORD)
81
+ low_order_offset, // offset (low-order DWORD)
80
82
byte_size);
81
83
82
84
if (*shm_addr == NULL ) {
83
- CloseHandle (shm_file->shm_handle_ );
85
+ CloseHandle (shm_file->shm_mapping_handle_ );
84
86
return -1 ;
85
87
}
86
88
// For Windows, we cannot close the shared memory handle here. When all
@@ -100,6 +102,38 @@ SharedMemoryRegionMap(
100
102
#endif
101
103
}
102
104
105
+ #ifdef _WIN32
106
+ int
107
+ SharedMemoryCreateBackingFile (const char * shm_key, HANDLE* backing_file_handle)
108
+ {
109
+ LPCSTR backing_file_directory (TRITON_SHM_FILE_ROOT);
110
+ bool success = CreateDirectory (backing_file_directory, NULL );
111
+ if (!success && GetLastError () != ERROR_ALREADY_EXISTS) {
112
+ return -1 ;
113
+ }
114
+ LPCSTR backing_file_path =
115
+ std::string (TRITON_SHM_FILE_ROOT + std::string (shm_key)).c_str ();
116
+ *backing_file_handle = CreateFile (
117
+ backing_file_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL ,
118
+ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
119
+ if (*backing_file_handle == INVALID_HANDLE_VALUE) {
120
+ return -1 ;
121
+ }
122
+ return 0 ;
123
+ }
124
+
125
+ int
126
+ SharedMemoryDeleteBackingFile (const char * key, HANDLE backing_file_handle)
127
+ {
128
+ CloseHandle (backing_file_handle);
129
+ LPCSTR backing_file_path =
130
+ std::string (TRITON_SHM_FILE_ROOT + std::string (key)).c_str ();
131
+ if (!DeleteFile (backing_file_path)) {
132
+ return -1 ;
133
+ }
134
+ }
135
+ #endif
136
+
103
137
} // namespace
104
138
105
139
TRITONCLIENT_DECLSPEC int
@@ -108,6 +142,11 @@ SharedMemoryRegionCreate(
108
142
void ** shm_handle)
109
143
{
110
144
#ifdef _WIN32
145
+ HANDLE backing_file_handle;
146
+ int err = SharedMemoryCreateBackingFile (shm_key, &backing_file_handle);
147
+ if (err == -1 ) {
148
+ return -7 ;
149
+ }
111
150
// The CreateFileMapping function takes a high-order and low-order DWORD (4
112
151
// bytes each) for size. 'size_t' can either be 4 or 8 bytes depending on the
113
152
// operating system. To handle both cases agnostically, we cast 'byte_size' to
@@ -118,22 +157,28 @@ SharedMemoryRegionCreate(
118
157
DWORD low_order_size = upperbound_size & 0xFFFFFFFF ;
119
158
120
159
HANDLE win_handle = CreateFileMapping (
121
- INVALID_HANDLE_VALUE , // use paging file
122
- NULL , // default security
123
- PAGE_READWRITE, // read/write access
124
- high_order_size, // maximum object size (high-order DWORD)
125
- low_order_size, // maximum object size (low-order DWORD)
126
- shm_key); // name of mapping object
160
+ backing_file_handle , // use backing file
161
+ NULL , // default security
162
+ PAGE_READWRITE, // read/write access
163
+ high_order_size, // maximum object size (high-order DWORD)
164
+ low_order_size, // maximum object size (low-order DWORD)
165
+ shm_key); // name of mapping object
127
166
128
167
if (win_handle == NULL ) {
129
- return -7 ;
168
+ LPCSTR backing_file_path =
169
+ std::string (TRITON_SHM_FILE_ROOT + std::string (shm_key)).c_str ();
170
+ // Cleanup backing file on failure
171
+ SharedMemoryDeleteBackingFile (shm_key, backing_file_handle);
172
+ return -8 ;
130
173
}
131
174
132
- ShmFile* shm_file = new ShmFile (win_handle);
175
+ std::unique_ptr<ShmFile> shm_file =
176
+ std::make_unique<ShmFile>(backing_file_handle, win_handle);
133
177
// get base address of shared memory region
134
178
void * shm_addr = nullptr ;
135
- int err = SharedMemoryRegionMap (shm_file, 0 , byte_size, &shm_addr);
179
+ err = SharedMemoryRegionMap (shm_file. get () , 0 , byte_size, &shm_addr);
136
180
if (err == -1 ) {
181
+ SharedMemoryDeleteBackingFile (shm_key, backing_file_handle);
137
182
return -4 ;
138
183
}
139
184
#else
@@ -149,18 +194,18 @@ SharedMemoryRegionCreate(
149
194
return -3 ;
150
195
}
151
196
152
- ShmFile* shm_file = new ShmFile (shm_fd);
197
+ std::unique_ptr< ShmFile> shm_file = std::make_unique< ShmFile> (shm_fd);
153
198
// get base address of shared memory region
154
199
void * shm_addr = nullptr ;
155
- int err = SharedMemoryRegionMap (shm_file, 0 , byte_size, &shm_addr);
200
+ int err = SharedMemoryRegionMap (shm_file. get () , 0 , byte_size, &shm_addr);
156
201
if (err == -1 ) {
157
202
return -4 ;
158
203
}
159
204
#endif
160
205
// create a handle for the shared memory region
161
206
*shm_handle = SharedMemoryHandleCreate (
162
- std::string (triton_shm_name), shm_addr, std::string (shm_key), shm_file, 0 ,
163
- byte_size);
207
+ std::string (triton_shm_name), shm_addr, std::string (shm_key),
208
+ std::move (shm_file), 0 , byte_size);
164
209
return 0 ;
165
210
}
166
211
@@ -186,7 +231,8 @@ GetSharedMemoryHandleInfo(
186
231
*offset = handle->offset_ ;
187
232
*byte_size = handle->byte_size_ ;
188
233
#ifdef _WIN32
189
- file->shm_handle_ = handle->platform_handle_ ->shm_handle_ ;
234
+ file->backing_file_handle_ = handle->platform_handle_ ->shm_mapping_handle_ ;
235
+ file->shm_mapping_handle_ = handle->platform_handle_ ->shm_mapping_handle_ ;
190
236
#else
191
237
file->shm_fd_ = handle->platform_handle_ ->shm_fd_ ;
192
238
#endif
@@ -204,10 +250,12 @@ SharedMemoryRegionDestroy(void* shm_handle)
204
250
if (!success) {
205
251
return -6 ;
206
252
}
207
- // We keep Windows shared memory handles open until we are done
208
- // using them. When all handles are closed, the system will free
209
- // the section of the paging file that the object uses.
210
- CloseHandle (handle->platform_handle_ ->shm_handle_ );
253
+ CloseHandle (handle->platform_handle_ ->shm_mapping_handle_ );
254
+ int err = SharedMemoryDeleteBackingFile (
255
+ handle->shm_key_ .c_str (), handle->platform_handle_ ->backing_file_handle_ );
256
+ if (err == -1 ) {
257
+ return -9 ;
258
+ }
211
259
#else
212
260
int status = munmap (shm_addr, handle->byte_size_ );
213
261
if (status == -1 ) {
0 commit comments