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
|
/** BEGIN COPYRIGHT BLOCK
* Copyright 2001 Sun Microsystems, Inc.
* Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
* shmem.h: Portable abstraction for memory shared among a server's workers
*
* Rob McCool
*/
#include "shmem.h"
#if defined (SHMEM_UNIX_MMAP)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <private/pprio.h> /* for nspr20 binary release */
NSPR_BEGIN_EXTERN_C
#include <sys/mman.h>
NSPR_END_EXTERN_C
NSAPI_PUBLIC shmem_s *shmem_alloc(char *name, int size, int expose)
{
shmem_s *ret = (shmem_s *) PERM_MALLOC(sizeof(shmem_s));
char *growme;
if( (ret->fd = PR_Open(name, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0666)) == NULL) {
PERM_FREE(ret);
return NULL;
}
growme = (char *) PERM_MALLOC(size);
ZERO(growme, size);
if(PR_Write(ret->fd, (char *)growme, size) < 0) {
PR_Close(ret->fd);
PERM_FREE(growme);
PERM_FREE(ret);
return NULL;
}
PERM_FREE(growme);
PR_Seek(ret->fd, 0, PR_SEEK_SET);
if( (ret->data = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE,
SHMEM_MMAP_FLAGS, PR_FileDesc2NativeHandle(ret->fd), 0)) == (caddr_t) -1)
{
PR_Close(ret->fd);
PERM_FREE(ret);
return NULL;
}
if(!expose) {
ret->name = NULL;
unlink(name);
}
else
ret->name = STRDUP(name);
ret->size = size;
return ret;
}
NSAPI_PUBLIC void shmem_free(shmem_s *region)
{
if(region->name) {
unlink(region->name);
PERM_FREE(region->name);
}
munmap((char *)region->data, region->size); /* CLEARLY, C++ SUCKS */
PR_Close(region->fd);
PERM_FREE(region);
}
#elif defined (SHMEM_WIN32_MMAP)
#define PAGE_SIZE (1024*8)
#define ALIGN(x) ( (x+PAGE_SIZE-1) & (~(PAGE_SIZE-1)) )
NSAPI_PUBLIC shmem_s *shmem_alloc(char *name, int size, int expose)
{
shmem_s *ret = (shmem_s *) PERM_MALLOC(sizeof(shmem_s));
HANDLE fHandle;
ret->fd = 0; /* not used on NT */
size = ALIGN(size);
if( !(ret->fdmap = CreateFileMapping(
(HANDLE)0xffffffff,
NULL,
PAGE_READWRITE,
0,
size,
name)) )
{
int err = GetLastError();
PERM_FREE(ret);
return NULL;
}
if( !(ret->data = (char *)MapViewOfFile (
ret->fdmap,
FILE_MAP_ALL_ACCESS,
0,
0,
0)) )
{
CloseHandle(ret->fdmap);
PERM_FREE(ret);
return NULL;
}
ret->size = size;
ret->name = NULL;
return ret;
}
NSAPI_PUBLIC void shmem_free(shmem_s *region)
{
if(region->name) {
DeleteFile(region->name);
PERM_FREE(region->name);
}
UnmapViewOfFile(region->data);
CloseHandle(region->fdmap);
PERM_FREE(region);
}
#endif /* SHMEM_WIN32_MMAP */
|