@@ -41,11 +41,23 @@ void ProgramPool::_remove_oldest_program() {
4141 _remove_program (0 );
4242}
4343
44+ const ProgramPool::Snapshot& ProgramPool::load_snapshot () const {
45+ return *std::atomic_load_explicit (&_snapshot, std::memory_order_acquire);
46+ }
47+
48+ void ProgramPool::_set_snapshot (std::shared_ptr<const Snapshot> new_snapshot) {
49+ std::atomic_store_explicit (&_snapshot, new_snapshot, std::memory_order_release);
50+ }
51+
4452void ProgramPool::update_snapshot () {
45- std::lock_guard<std::recursive_mutex> snapshot_lock (snapshot_mutex);
46- programs_snapshot = programs; // Copy the current programs state
47- program_indices_snapshot = program_indices; // Copy the current program indices state
48- open_files_snapshot = open_files; // Copy the current open files state
53+ auto new_snapshot = std::make_shared<Snapshot>();
54+ {
55+ std::lock_guard<std::recursive_mutex> lock (pool_mutex);
56+ new_snapshot->programs_snapshot = programs;
57+ new_snapshot->program_indices_snapshot = program_indices;
58+ new_snapshot->open_files_snapshot = open_files;
59+ }
60+ _set_snapshot (new_snapshot); // Update the snapshot atomically
4961}
5062
5163void ProgramPool::_remove_program (size_t index) {
@@ -148,12 +160,12 @@ std::shared_ptr<bpp::bpp_program> ProgramPool::get_program(const std::string& fi
148160 if (jump_queue) {
149161 // Jump the queue:
150162 // Skip getting a lock on the pool's main state, since we're not modifying it
151- // Instead, get a lock on the snapshot
163+ // Instead, read from the snapshot
152164 // And REFUSE to modify the pool if the file isn't already in it
153- std::lock_guard<std::recursive_mutex> lock (snapshot_mutex );
154- auto it = program_indices_snapshot.find (file_path);
155- if (it != program_indices_snapshot.end ()) {
156- return programs_snapshot[it->second ];
165+ Snapshot snapshot = load_snapshot ( );
166+ auto it = snapshot. program_indices_snapshot .find (file_path);
167+ if (it != snapshot. program_indices_snapshot .end ()) {
168+ return snapshot. programs_snapshot [it->second ];
157169 } else {
158170 return nullptr ;
159171 }
@@ -193,56 +205,58 @@ std::shared_ptr<bpp::bpp_program> ProgramPool::get_program(const std::string& fi
193205
194206bool ProgramPool::has_program (const std::string& file_path) {
195207 // Scan the SNAPSHOT for the program
196- std::lock_guard<std::recursive_mutex> lock (snapshot_mutex);
208+ Snapshot snapshot = load_snapshot ();
209+ const auto & program_indices_snapshot = snapshot.program_indices_snapshot ;
197210 return program_indices_snapshot.find (file_path) != program_indices_snapshot.end ();
198211}
199212
200213std::shared_ptr<bpp::bpp_program> ProgramPool::re_parse_program (const std::string& file_path) {
214+ if (!has_program (file_path)) {
215+ return get_program (file_path); // If it doesn't exist, create it
216+ }
217+
201218 std::lock_guard<std::recursive_mutex> lock (pool_mutex);
202- if ( has_program (file_path)) {
203- size_t index = program_indices[file_path];
204- std::string main_source_file = programs[index]->get_main_source_file ();
219+ // The program exists, so we can re-parse it
220+ size_t index = program_indices[file_path];
221+ std::string main_source_file = programs[index]->get_main_source_file ();
205222
206- auto new_program = _parse_program (main_source_file);
207- if (new_program == nullptr ) {
208- return nullptr ; // Return nullptr if parsing fails
209- }
223+ auto new_program = _parse_program (main_source_file);
224+ if (new_program == nullptr ) {
225+ return nullptr ; // Return nullptr if parsing fails
226+ }
210227
211- programs[index] = new_program;
212- open_files[file_path] = true ; // Mark the file as open
228+ programs[index] = new_program;
229+ open_files[file_path] = true ; // Mark the file as open
213230
214- update_snapshot ();
231+ update_snapshot ();
215232
216- return programs[index];
217- } else {
218- return get_program (file_path); // If it doesn't exist, create it
219- }
233+ return programs[index];
220234}
221235
222236std::shared_ptr<bpp::bpp_program> ProgramPool::re_parse_program (
223237 const std::string& file_path,
224238 std::pair<std::string, std::string> replacement_file_contents
225239) {
240+ if (!has_program (file_path)) {
241+ return nullptr ;
242+ }
243+
226244 std::lock_guard<std::recursive_mutex> lock (pool_mutex);
227- if (has_program (file_path)) {
228- size_t index = program_indices[file_path];
229- std::string main_source_file = programs[index]->get_main_source_file ();
245+ size_t index = program_indices[file_path];
246+ std::string main_source_file = programs[index]->get_main_source_file ();
230247
231- auto new_program = _parse_program (main_source_file, replacement_file_contents);
248+ auto new_program = _parse_program (main_source_file, replacement_file_contents);
232249
233- if (new_program == nullptr ) {
234- return nullptr ; // Return nullptr if parsing fails
235- }
250+ if (new_program == nullptr ) {
251+ return nullptr ; // Return nullptr if parsing fails
252+ }
236253
237- programs[index] = new_program;
238- open_files[file_path] = true ; // Mark the file as open
254+ programs[index] = new_program;
255+ open_files[file_path] = true ; // Mark the file as open
239256
240- update_snapshot ();
257+ update_snapshot ();
241258
242- return programs[index];
243- } else {
244- return nullptr ;
245- }
259+ return programs[index];
246260}
247261
248262void ProgramPool::open_file (const std::string& file_path) {
@@ -289,13 +303,10 @@ void ProgramPool::close_file(const std::string& file_path) {
289303
290304void ProgramPool::clean () {
291305 std::lock_guard<std::recursive_mutex> lock (pool_mutex);
292- std::lock_guard<std::recursive_mutex> snapshot_lock (snapshot_mutex);
293306
294307 programs.clear ();
295308 program_indices.clear ();
296309 open_files.clear ();
297310
298- programs_snapshot.clear ();
299- program_indices_snapshot.clear ();
300- open_files_snapshot.clear ();
311+ update_snapshot (); // Update the snapshot after cleaning
301312}
0 commit comments