@@ -39,6 +39,7 @@ struct THMapAllocatorContext_ {
39
39
char * filename ; /* file name */
40
40
int flags ;
41
41
long size ; /* mapped size */
42
+ int fd ;
42
43
};
43
44
44
45
#define TH_ALLOC_ALIGNMENT 64
@@ -47,21 +48,35 @@ typedef struct {
47
48
int refcount ;
48
49
} THMapInfo ;
49
50
51
+ char * unknown_filename = "filename not specified" ;
52
+
50
53
THMapAllocatorContext * THMapAllocatorContext_new (const char * filename , int flags )
51
54
{
52
55
THMapAllocatorContext * ctx = THAlloc (sizeof (THMapAllocatorContext ));
53
56
54
-
55
57
if (!(flags & TH_ALLOCATOR_MAPPED_SHARED ) && !(flags & TH_ALLOCATOR_MAPPED_SHAREDMEM ))
56
58
flags &= ~TH_ALLOCATOR_MAPPED_NOCREATE ;
57
59
if ((flags ^ TH_ALLOCATOR_MAPPED_EXCLUSIVE ) == 0 )
58
60
THError ("TH_ALLOCATOR_MAPPED_EXCLUSIVE flag requires opening the file "
59
61
"in shared mode" );
60
62
61
- ctx -> filename = THAlloc (strlen (filename )+ 1 );
62
- strcpy (ctx -> filename , filename );
63
+ if (filename ) {
64
+ ctx -> filename = THAlloc (strlen (filename )+ 1 );
65
+ strcpy (ctx -> filename , filename );
66
+ } else {
67
+ ctx -> filename = unknown_filename ;
68
+ }
63
69
ctx -> flags = flags ;
64
70
ctx -> size = 0 ;
71
+ ctx -> fd = -1 ;
72
+
73
+ return ctx ;
74
+ }
75
+
76
+ THMapAllocatorContext * THMapAllocatorContext_newWithFd (const char * filename , int fd , int flags )
77
+ {
78
+ THMapAllocatorContext * ctx = THMapAllocatorContext_new (filename , flags );
79
+ ctx -> fd = fd ;
65
80
66
81
return ctx ;
67
82
}
@@ -71,14 +86,20 @@ char * THMapAllocatorContext_filename(THMapAllocatorContext *ctx)
71
86
return ctx -> filename ;
72
87
}
73
88
89
+ int THMapAllocatorContext_fd (THMapAllocatorContext * ctx )
90
+ {
91
+ return ctx -> fd ;
92
+ }
93
+
74
94
long THMapAllocatorContext_size (THMapAllocatorContext * ctx )
75
95
{
76
96
return ctx -> size ;
77
97
}
78
98
79
99
void THMapAllocatorContext_free (THMapAllocatorContext * ctx )
80
100
{
81
- THFree (ctx -> filename );
101
+ if (ctx -> filename != unknown_filename )
102
+ THFree (ctx -> filename );
82
103
THFree (ctx );
83
104
}
84
105
@@ -98,6 +119,10 @@ static void *_map_alloc(void* ctx_, long size)
98
119
THError ("exclusive file mapping is not supported on Windows" );
99
120
if (ctx -> flags & TH_ALLOCATOR_MAPPED_NOCREATE )
100
121
THError ("file mapping without creation is not supported on Windows" );
122
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_KEEPFD )
123
+ THError ("TH_ALLOCATOR_MAPPED_KEEPFD not supported on Windows" );
124
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_FROMFD )
125
+ THError ("TH_ALLOCATOR_MAPPED_FROMFD not supported on Windows" );
101
126
102
127
/* open file */
103
128
/* FILE_FLAG_RANDOM_ACCESS ? */
@@ -193,9 +218,9 @@ static void *_map_alloc(void* ctx_, long size)
193
218
/* open file */
194
219
int fd ;
195
220
int flags ;
196
- long fdsz ;
221
+ struct stat file_stat ;
197
222
198
- if (ctx -> flags )
223
+ if (ctx -> flags & ( TH_ALLOCATOR_MAPPED_SHARED | TH_ALLOCATOR_MAPPED_SHAREDMEM ) )
199
224
flags = O_RDWR | O_CREAT ;
200
225
else
201
226
flags = O_RDONLY ;
@@ -205,35 +230,40 @@ static void *_map_alloc(void* ctx_, long size)
205
230
if (ctx -> flags & TH_ALLOCATOR_MAPPED_NOCREATE )
206
231
flags &= ~O_CREAT ;
207
232
208
- if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHARED )
209
- {
210
- if ((fd = open (ctx -> filename , flags , (mode_t )0600 )) == -1 )
211
- THError ("unable to open file <%s> in read-write mode" , ctx -> filename );
212
- }
213
- else if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHAREDMEM )
214
- {
233
+ if (!(ctx -> flags & TH_ALLOCATOR_MAPPED_FROMFD )) {
234
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHARED )
235
+ {
236
+ if ((fd = open (ctx -> filename , flags , (mode_t )0600 )) == -1 )
237
+ THError ("unable to open file <%s> in read-write mode" , ctx -> filename );
238
+ }
239
+ else if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHAREDMEM )
240
+ {
215
241
#ifdef HAVE_SHM_OPEN
216
- if ((fd = shm_open (ctx -> filename , flags , (mode_t )0600 )) == -1 )
217
- THError ("unable to open shared memory object <%s> in read-write mode" , ctx -> filename );
242
+ if ((fd = shm_open (ctx -> filename , flags , (mode_t )0600 )) == -1 )
243
+ THError ("unable to open shared memory object <%s> in read-write mode" , ctx -> filename );
218
244
#else
219
- THError ("unable to open file <%s> in sharedmem mode, shm_open unavailable on this platform" );
245
+ THError ("unable to open file <%s> in sharedmem mode, shm_open unavailable on this platform" );
220
246
#endif
221
- }
222
- else
223
- {
224
- if ((fd = open (ctx -> filename , O_RDONLY )) == -1 )
225
- THError ("unable to open file <%s> in read-only mode" , ctx -> filename );
247
+ }
248
+ else
249
+ {
250
+ if ((fd = open (ctx -> filename , O_RDONLY )) == -1 )
251
+ THError ("unable to open file <%s> in read-only mode" , ctx -> filename );
252
+ }
253
+ } else {
254
+ fd = ctx -> fd ;
226
255
}
227
256
228
- if (( fdsz = lseek ( fd , 0 , SEEK_END ) ) == -1 )
257
+ if (fstat ( fd , & file_stat ) == -1 )
229
258
{
230
- close (fd );
231
- THError ("unable to seek at end of file <%s>" , ctx -> filename );
259
+ if (!(ctx -> flags & TH_ALLOCATOR_MAPPED_FROMFD ))
260
+ close (fd );
261
+ THError ("unable to stat the file <%s>" , ctx -> filename );
232
262
}
233
263
234
264
if (size > 0 )
235
265
{
236
- if (size > fdsz )
266
+ if (size > file_stat . st_size )
237
267
{
238
268
if (ctx -> flags )
239
269
{
@@ -243,7 +273,7 @@ static void *_map_alloc(void* ctx_, long size)
243
273
if (ftruncate (fd , size ) == -1 )
244
274
THError ("unable to resize shared memory file <%s> to the right size" , ctx -> filename );
245
275
}
246
- if (( fdsz = lseek ( fd , size - 1 , SEEK_SET )) == -1 )
276
+ if (fstat ( fd , & file_stat ) == -1 || file_stat . st_size < size )
247
277
{
248
278
close (fd );
249
279
THError ("unable to stretch file <%s> to the right size" , ctx -> filename );
@@ -262,18 +292,40 @@ static void *_map_alloc(void* ctx_, long size)
262
292
}
263
293
}
264
294
else
265
- size = fdsz ;
295
+ size = file_stat . st_size ;
266
296
267
297
ctx -> size = size ; /* if we are here, it must be the right size */
268
298
269
299
/* map it */
270
- if (ctx -> flags )
300
+ if (ctx -> flags & ( TH_ALLOCATOR_MAPPED_SHARED | TH_ALLOCATOR_MAPPED_SHAREDMEM ) )
271
301
data = mmap (NULL , ctx -> size , PROT_READ |PROT_WRITE , MAP_SHARED , fd , 0 );
272
302
else
273
303
data = mmap (NULL , ctx -> size , PROT_READ |PROT_WRITE , MAP_PRIVATE , fd , 0 );
274
304
275
- if (close (fd ) == -1 )
276
- THError ("Error closing file <%s>" , ctx -> filename );
305
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_KEEPFD ) {
306
+ ctx -> fd = fd ;
307
+ } else {
308
+ if (close (fd ) == -1 )
309
+ THError ("Error closing file <%s>" , ctx -> filename );
310
+ ctx -> fd = -1 ;
311
+ }
312
+
313
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_UNLINK ) {
314
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHAREDMEM )
315
+ {
316
+ #ifdef HAVE_SHM_UNLINK
317
+ if (shm_unlink (ctx -> filename ) == -1 )
318
+ THError ("could not unlink the shared memory file %s" , ctx -> filename );
319
+ #else
320
+ THError ("could not unlink the shared memory file %s, shm_unlink not available on platform" , ctx -> filename );
321
+ #endif
322
+ }
323
+ else
324
+ {
325
+ if (unlink (ctx -> filename ) == -1 )
326
+ THError ("could not unlink file %s" , ctx -> filename );
327
+ }
328
+ }
277
329
278
330
if (data == MAP_FAILED )
279
331
{
@@ -302,16 +354,25 @@ static void THMapAllocator_free(void* ctx_, void* data) {
302
354
if (!UnmapViewOfFile ((LPINT )data ))
303
355
THError ("could not unmap the shared memory file" );
304
356
#else /* _WIN32 */
357
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_KEEPFD ) {
358
+ if (close (ctx -> fd ) == -1 )
359
+ THError ("could not close file descriptor %d" , ctx -> fd );
360
+ }
361
+
305
362
if (munmap (data , ctx -> size ))
306
363
THError ("could not unmap the shared memory file" );
307
- if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHAREDMEM )
364
+
365
+ if (!(ctx -> flags & (TH_ALLOCATOR_MAPPED_FROMFD | TH_ALLOCATOR_MAPPED_UNLINK )))
308
366
{
367
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_SHAREDMEM )
368
+ {
309
369
#ifdef HAVE_SHM_UNLINK
310
- if (shm_unlink (ctx -> filename ) == -1 )
311
- THError ("could not unlink the shared memory file %s" , ctx -> filename );
370
+ if (shm_unlink (ctx -> filename ) == -1 )
371
+ THError ("could not unlink the shared memory file %s" , ctx -> filename );
312
372
#else
313
- THError ("could not unlink the shared memory file %s, shm_unlink not available on platform" , ctx -> filename );
373
+ THError ("could not unlink the shared memory file %s, shm_unlink not available on platform" , ctx -> filename );
314
374
#endif
375
+ }
315
376
}
316
377
#endif /* _WIN32 */
317
378
@@ -350,8 +411,14 @@ static void THMapAllocator_free(void* ctx, void* data) {
350
411
static void * THRefcountedMapAllocator_alloc (void * _ctx , long size ) {
351
412
THMapAllocatorContext * ctx = _ctx ;
352
413
414
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_FROMFD )
415
+ THError ("THRefcountedMapAllocator doesn't support TH_ALLOCATOR_MAPPED_FROMFD flag" );
416
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_KEEPFD )
417
+ THError ("THRefcountedMapAllocator doesn't support TH_ALLOCATOR_MAPPED_KEEPFD flag" );
418
+ if (ctx -> flags & TH_ALLOCATOR_MAPPED_UNLINK )
419
+ THError ("THRefcountedMapAllocator doesn't support TH_ALLOCATOR_MAPPED_UNLINK flag" );
353
420
if (!(ctx -> flags & TH_ALLOCATOR_MAPPED_SHAREDMEM ))
354
- THError ("THRefcountedMapAllcator requires SHAREDMEM flag" );
421
+ THError ("THRefcountedMapAllocator requires TH_ALLOCATOR_MAPPED_SHAREDMEM flag" );
355
422
356
423
size = size + TH_ALLOC_ALIGNMENT ;
357
424
void * ptr = _map_alloc (ctx , size );
0 commit comments