Mercurial > hg > orthanc
comparison OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp @ 5737:2fe77dfe0466
rewrote FileSystemStorage::Create knowing that we should not check the return value of boost::file_system::create_directories and that it throws on errors we were detecting manually
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Thu, 01 Aug 2024 19:44:48 +0200 |
parents | 264d84c1936a |
children | 8279eaab0d1d |
comparison
equal
deleted
inserted
replaced
5736:264d84c1936a | 5737:2fe77dfe0466 |
---|---|
137 // Extremely unlikely case: This Uuid has already been created | 137 // Extremely unlikely case: This Uuid has already been created |
138 // in the past. | 138 // in the past. |
139 throw OrthancException(ErrorCode_InternalError, "This file UUID already exists"); | 139 throw OrthancException(ErrorCode_InternalError, "This file UUID already exists"); |
140 } | 140 } |
141 | 141 |
142 // In very unlikely case (but we've seen it !), 2 threads might enter this same piece | 142 // In very unlikely cases, a thread could be deleting a |
143 // of code and both try to create the same directory or a thread could be deleting a | |
144 // directory while another thread needs it -> introduce 3 retries at 1 ms interval | 143 // directory while another thread needs it -> introduce 3 retries at 1 ms interval |
145 int retryCount = 0; | 144 int retryCount = 0; |
146 const int maxRetryCount = 3; | 145 const int maxRetryCount = 3; |
147 | 146 |
148 while (retryCount < maxRetryCount) | 147 while (retryCount < maxRetryCount) |
153 boost::this_thread::sleep(boost::posix_time::milliseconds(2 * retryCount + (rand() % 10))); | 152 boost::this_thread::sleep(boost::posix_time::milliseconds(2 * retryCount + (rand() % 10))); |
154 LOG(INFO) << "Retrying to create attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) | 153 LOG(INFO) << "Retrying to create attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) |
155 << "\" type"; | 154 << "\" type"; |
156 } | 155 } |
157 | 156 |
158 if (boost::filesystem::exists(path.parent_path())) | 157 try |
159 { | 158 { |
160 if (!boost::filesystem::is_directory(path.parent_path())) | 159 boost::filesystem::create_directories(path.parent_path()); // the function ensures that the directory exists or throws |
160 } | |
161 catch (boost::filesystem::filesystem_error& er) | |
162 { | |
163 if (er.code() == boost::system::errc::file_exists // the last element of the parent_path is a file | |
164 || er.code() == boost::system::errc::not_a_directory) // one of the element of the parent_path is not a directory | |
161 { | 165 { |
162 throw OrthancException(ErrorCode_DirectoryOverFile); // no need to retry this error | 166 throw OrthancException(ErrorCode_DirectoryOverFile, "One of the element of the path is a file"); // no need to retry this error |
163 } | 167 } |
164 } | 168 |
165 else | 169 // ignore other errors and retry |
166 { | |
167 if (!boost::filesystem::create_directories(path.parent_path())) | |
168 { | |
169 if (retryCount >= maxRetryCount) | |
170 { | |
171 throw OrthancException(ErrorCode_FileStorageCannotWrite); | |
172 } | |
173 | |
174 continue; // retry | |
175 } | |
176 } | 170 } |
177 | 171 |
178 try | 172 try |
179 { | 173 { |
180 SystemToolbox::WriteFile(content, size, path.string(), fsyncOnWrite_); | 174 SystemToolbox::WriteFile(content, size, path.string(), fsyncOnWrite_); |