27
27
namespace facebook {
28
28
namespace cachelib {
29
29
30
- constexpr static mode_t kRWMode = 0666 ;
31
- typedef struct stat stat_t ;
32
-
33
- namespace detail {
34
-
35
- static int shmOpenImpl (const char * name, int flags) {
36
- const int fd = shm_open (name, flags, kRWMode );
37
-
38
- if (fd != -1 ) {
39
- return fd;
40
- }
41
-
42
- switch (errno) {
43
- case EEXIST:
44
- case EMFILE:
45
- case ENFILE:
46
- case EACCES:
47
- util::throwSystemError (errno);
48
- break ;
49
- case ENAMETOOLONG:
50
- case EINVAL:
51
- util::throwSystemError (errno, " Invalid segment name" );
52
- break ;
53
- case ENOENT:
54
- if (!(flags & O_CREAT)) {
55
- util::throwSystemError (errno);
56
- } else {
57
- XDCHECK (false );
58
- // FIXME: posix says that ENOENT is thrown only when O_CREAT
59
- // is not set. However, it seems to be set even when O_CREAT
60
- // was set and the parent of path name does not exist.
61
- util::throwSystemError (errno, " Invalid errno" );
62
- }
63
- break ;
64
- default :
65
- XDCHECK (false );
66
- util::throwSystemError (errno, " Invalid errno" );
67
- }
68
- return kInvalidFD ;
69
- }
70
-
71
- static void shmUnlinkImpl (const char * const name) {
72
- const int ret = shm_unlink (name);
73
- if (ret == 0 ) {
74
- return ;
75
- }
76
-
77
- switch (errno) {
78
- case ENOENT:
79
- case EACCES:
80
- util::throwSystemError (errno);
81
- break ;
82
- case ENAMETOOLONG:
83
- case EINVAL:
84
- util::throwSystemError (errno, " Invalid segment name" );
85
- break ;
86
- default :
87
- XDCHECK (false );
88
- util::throwSystemError (errno, " Invalid errno" );
89
- }
90
- }
91
-
92
- static void ftruncateImpl (int fd, size_t size) {
93
- const int ret = ftruncate (fd, size);
94
- if (ret == 0 ) {
95
- return ;
96
- }
97
- switch (errno) {
98
- case EBADF:
99
- case EINVAL:
100
- util::throwSystemError (errno);
101
- break ;
102
- default :
103
- XDCHECK (false );
104
- util::throwSystemError (errno, " Invalid errno" );
105
- }
106
- }
107
-
108
- static void fstatImpl (int fd, stat_t * buf) {
109
- const int ret = fstat (fd, buf);
110
- if (ret == 0 ) {
111
- return ;
112
- }
113
- switch (errno) {
114
- case EBADF:
115
- case ENOMEM:
116
- case EOVERFLOW:
117
- util::throwSystemError (errno);
118
- break ;
119
- default :
120
- XDCHECK (false );
121
- util::throwSystemError (errno, " Invalid errno" );
122
- }
123
- }
124
-
125
- static void * mmapImpl (
126
- void * addr, size_t length, int prot, int flags, int fd, off_t offset) {
127
- void * ret = mmap (addr, length, prot, flags, fd, offset);
128
- if (ret != MAP_FAILED) {
129
- return ret;
130
- }
131
-
132
- switch (errno) {
133
- case EACCES:
134
- case EAGAIN:
135
- if (flags & MAP_LOCKED) {
136
- util::throwSystemError (ENOMEM);
137
- break ;
138
- }
139
- case EBADF:
140
- case EINVAL:
141
- case ENFILE:
142
- case ENODEV:
143
- case ENOMEM:
144
- case EPERM:
145
- case ETXTBSY:
146
- case EOVERFLOW:
147
- util::throwSystemError (errno);
148
- break ;
149
- default :
150
- XDCHECK (false );
151
- util::throwSystemError (errno, " Invalid errno" );
152
- }
153
- return nullptr ;
154
- }
155
-
156
- static void munmapImpl (void * addr, size_t length) {
157
- const int ret = munmap (addr, length);
158
-
159
- if (ret == 0 ) {
160
- return ;
161
- } else if (errno == EINVAL) {
162
- util::throwSystemError (errno);
163
- } else {
164
- XDCHECK (false );
165
- util::throwSystemError (EINVAL, " Invalid errno" );
166
- }
167
- }
168
-
169
- } // namespace detail
30
+ constexpr mode_t kRWMode = 0666 ;
170
31
171
32
PosixShmSegment::PosixShmSegment (ShmAttachT,
172
33
const std::string& name,
@@ -215,13 +76,15 @@ PosixShmSegment::~PosixShmSegment() {
215
76
216
77
int PosixShmSegment::createNewSegment (const std::string& name) {
217
78
constexpr static int createFlags = O_RDWR | O_CREAT | O_EXCL;
218
- return detail::shmOpenImpl (name.c_str (), createFlags);
79
+ detail::open_func_t open_func = std::bind (shm_open, name.c_str (), createFlags, kRWMode );
80
+ return detail::openImpl (open_func, createFlags);
219
81
}
220
82
221
83
int PosixShmSegment::getExisting (const std::string& name,
222
84
const ShmSegmentOpts& opts) {
223
85
int flags = opts.readOnly ? O_RDONLY : O_RDWR;
224
- return detail::shmOpenImpl (name.c_str (), flags);
86
+ detail::open_func_t open_func = std::bind (shm_open, name.c_str (), flags, kRWMode );
87
+ return detail::openImpl (open_func, flags);
225
88
}
226
89
227
90
void PosixShmSegment::markForRemoval () {
@@ -239,7 +102,8 @@ void PosixShmSegment::markForRemoval() {
239
102
bool PosixShmSegment::removeByName (const std::string& segmentName) {
240
103
try {
241
104
auto key = createKeyForName (segmentName);
242
- detail::shmUnlinkImpl (key.c_str ());
105
+ detail::unlink_func_t unlink_func = std::bind (shm_unlink, key.c_str ());
106
+ detail::unlinkImpl (unlink_func);
243
107
return true ;
244
108
} catch (const std::system_error& e) {
245
109
// unlink is opaque unlike sys-V api where its through the shmid. Hence
@@ -258,7 +122,7 @@ size_t PosixShmSegment::getSize() const {
258
122
return buf.st_size ;
259
123
} else {
260
124
throw std::runtime_error (folly::sformat (
261
- " Trying to get size of segment with name {} in an invalid state" ,
125
+ " Trying to get size of segment with name {} in an invalid state" ,
262
126
getName ()));
263
127
}
264
128
return 0 ;
0 commit comments