2727namespace facebook {
2828namespace cachelib {
2929
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 ;
17031
17132PosixShmSegment::PosixShmSegment (ShmAttachT,
17233 const std::string& name,
@@ -215,13 +76,15 @@ PosixShmSegment::~PosixShmSegment() {
21576
21677int PosixShmSegment::createNewSegment (const std::string& name) {
21778 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);
21981}
22082
22183int PosixShmSegment::getExisting (const std::string& name,
22284 const ShmSegmentOpts& opts) {
22385 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);
22588}
22689
22790void PosixShmSegment::markForRemoval () {
@@ -239,7 +102,8 @@ void PosixShmSegment::markForRemoval() {
239102bool PosixShmSegment::removeByName (const std::string& segmentName) {
240103 try {
241104 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);
243107 return true ;
244108 } catch (const std::system_error& e) {
245109 // unlink is opaque unlike sys-V api where its through the shmid. Hence
@@ -258,7 +122,7 @@ size_t PosixShmSegment::getSize() const {
258122 return buf.st_size ;
259123 } else {
260124 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" ,
262126 getName ()));
263127 }
264128 return 0 ;
0 commit comments