@@ -74,7 +74,7 @@ class SemaphoreMutex {
7474
7575class InterprocessMutex {
7676public:
77- InterprocessMutex ();
77+ InterprocessMutex () = default ;
7878 ~InterprocessMutex () noexcept ;
7979
8080 // Disable copying. Copying a locked Mutex will create a scenario
@@ -93,7 +93,6 @@ class InterprocessMutex {
9393 // / The SharedPart is assumed to have been initialized (possibly by another process)
9494 // / elsewhere.
9595 void set_shared_part (SharedPart& shared_part, const std::string& path, const std::string& mutex_name);
96- void set_shared_part (SharedPart& shared_part, File&& lock_file);
9796
9897 // / Destroy shared object. Potentially release system resources. Caller must
9998 // / ensure that the shared_part is not in use at the point of call.
@@ -130,43 +129,13 @@ class InterprocessMutex {
130129
131130private:
132131#if REALM_ROBUST_MUTEX_EMULATION
133- struct LockInfo {
134- File m_file;
132+ File m_file;
135133#if REALM_PLATFORM_APPLE
136- SemaphoreMutex m_local_mutex;
134+ SemaphoreMutex m_local_mutex;
137135#else
138- Mutex m_local_mutex;
136+ Mutex m_local_mutex;
139137#endif
140- LockInfo () {}
141- ~LockInfo () noexcept ;
142- // Disable copying.
143- LockInfo (const LockInfo&) = delete ;
144- LockInfo& operator =(const LockInfo&) = delete ;
145- };
146- // / InterprocessMutex created on the same file (same inode on POSIX) share the same LockInfo.
147- // / LockInfo will be saved in a static map as a weak ptr and use the UniqueID as the key.
148- // / Operations on the map need to be protected by s_mutex
149- static std::map<File::UniqueID, std::weak_ptr<LockInfo>>* s_info_map;
150- static Mutex* s_mutex;
151- // / We manually initialize these static variables when first needed,
152- // / creating them on the heap so that they last for the entire lifetime
153- // / of the process. The destructor of these is never called; the
154- // / process will clean up their memory when exiting. It is not enough
155- // / to count instances of InterprocessMutex and clean up these statics when
156- // / the count reaches zero because the program can create more
157- // / InterprocessMutex instances before the process ends, so we really need
158- // / these variables for the entire lifetime of the process.
159- static std::once_flag s_init_flag;
160- static void initialize_statics ();
161-
162- // / Only used for release_shared_part
163- std::string m_filename;
164- File::UniqueID m_fileuid;
165- std::shared_ptr<LockInfo> m_lock_info;
166-
167- // / Free the lock info hold by this instance.
168- // / If it is the last reference, underly resources will be freed as well.
169- void free_lock_info ();
138+
170139#else
171140 SharedPart* m_shared_part = nullptr ;
172141
@@ -178,13 +147,6 @@ class InterprocessMutex {
178147 friend class InterprocessCondVar ;
179148};
180149
181- inline InterprocessMutex::InterprocessMutex ()
182- {
183- #if REALM_ROBUST_MUTEX_EMULATION
184- std::call_once (s_init_flag, initialize_statics);
185- #endif
186- }
187-
188150inline InterprocessMutex::~InterprocessMutex () noexcept
189151{
190152#ifdef _WIN32
@@ -193,83 +155,31 @@ inline InterprocessMutex::~InterprocessMutex() noexcept
193155 REALM_ASSERT_RELEASE (b);
194156 }
195157#endif
196-
197- #if REALM_ROBUST_MUTEX_EMULATION
198- free_lock_info ();
199- #endif
200158}
201159
202- #if REALM_ROBUST_MUTEX_EMULATION
203- inline InterprocessMutex::LockInfo::~LockInfo () noexcept
204- {
205- if (m_file.is_attached ()) {
206- m_file.close ();
207- }
208- }
209-
210- inline void InterprocessMutex::free_lock_info ()
211- {
212- // It has not been initialized yet.
213- if (!m_lock_info)
214- return ;
215-
216- std::lock_guard<Mutex> guard (*s_mutex);
217-
218- m_lock_info.reset ();
219- if ((*s_info_map)[m_fileuid].expired ()) {
220- s_info_map->erase (m_fileuid);
221- }
222- m_filename.clear ();
223- }
224-
225- inline void InterprocessMutex::initialize_statics ()
226- {
227- s_mutex = new Mutex ();
228- s_info_map = new std::map<File::UniqueID, std::weak_ptr<LockInfo>>();
229- }
230- #endif
231-
232160inline void InterprocessMutex::set_shared_part (SharedPart& shared_part, const std::string& path,
233161 const std::string& mutex_name)
234162{
235163#if REALM_ROBUST_MUTEX_EMULATION
236164 static_cast <void >(shared_part);
237165
238- free_lock_info () ;
166+ std::string filename ;
239167 if (path.size () == 0 ) {
240- m_filename = make_temp_file (mutex_name.c_str ());
168+ filename = make_temp_file (mutex_name.c_str ());
241169 }
242170 else {
243- m_filename = path + " ." + mutex_name + " .mx" ;
244- }
245-
246- std::lock_guard<Mutex> guard (*s_mutex);
247-
248- // Try to get the file uid if the file exists
249- if (auto uid = File::get_unique_id (m_filename)) {
250- m_fileuid = std::move (*uid);
251- auto result = s_info_map->find (m_fileuid);
252- if (result != s_info_map->end ()) {
253- // File exists and the lock info has been created in the map.
254- m_lock_info = result->second .lock ();
255- REALM_ASSERT_RELEASE (m_lock_info && m_lock_info->m_file .get_path () == m_filename);
256- return ;
257- }
171+ filename = util::format (" %1.%2.mx" , path, mutex_name);
258172 }
259173
260- // LockInfo has not been created yet.
261- m_lock_info = std::make_shared<LockInfo>();
262174 // Always open file for write and retreive the uid in case other process
263175 // deletes the file. Avoid using just mode_Write (which implies truncate).
264176 // On fat32/exfat uid could be reused by OS in a situation when
265177 // multiple processes open and truncate the same lock file concurrently.
266- m_lock_info->m_file .open (m_filename, File::mode_Append);
178+ m_file.close ();
179+ m_file.open (filename, File::mode_Append);
267180 // exFAT does not allocate a unique id for the file until it's non-empty
268- m_lock_info->m_file .resize (1 );
269- m_fileuid = m_lock_info->m_file .get_unique_id ();
181+ m_file.resize (1 );
270182
271- REALM_ASSERT_RELEASE (s_info_map->find (m_fileuid) == s_info_map->end ());
272- (*s_info_map)[m_fileuid] = m_lock_info;
273183#elif defined(_WIN32)
274184 if (m_handle) {
275185 bool b = CloseHandle (m_handle);
@@ -292,40 +202,13 @@ inline void InterprocessMutex::set_shared_part(SharedPart& shared_part, const st
292202#endif
293203}
294204
295- inline void InterprocessMutex::set_shared_part (SharedPart& shared_part, File&& lock_file)
296- {
297- #if REALM_ROBUST_MUTEX_EMULATION
298- static_cast <void >(shared_part);
299-
300- free_lock_info ();
301-
302- std::lock_guard<Mutex> guard (*s_mutex);
303-
304- m_fileuid = lock_file.get_unique_id ();
305- auto result = s_info_map->find (m_fileuid);
306- if (result == s_info_map->end ()) {
307- m_lock_info = std::make_shared<LockInfo>();
308- m_lock_info->m_file = std::move (lock_file);
309- (*s_info_map)[m_fileuid] = m_lock_info;
310- }
311- else {
312- // File exists and the lock info has been created in the map.
313- m_lock_info = result->second .lock ();
314- lock_file.close ();
315- }
316- #else
317- m_shared_part = &shared_part;
318- static_cast <void >(lock_file);
319- #endif
320- }
321-
322205inline void InterprocessMutex::release_shared_part ()
323206{
324207#if REALM_ROBUST_MUTEX_EMULATION
325- if (!m_filename. empty ())
326- File::try_remove (m_filename );
327-
328- free_lock_info ();
208+ if (m_file. is_attached ()) {
209+ m_file. close ( );
210+ File::try_remove (m_file. get_path ());
211+ }
329212#else
330213 m_shared_part = nullptr ;
331214#endif
@@ -334,8 +217,8 @@ inline void InterprocessMutex::release_shared_part()
334217inline void InterprocessMutex::lock ()
335218{
336219#if REALM_ROBUST_MUTEX_EMULATION
337- std::unique_lock mutex_lock (m_lock_info-> m_local_mutex );
338- m_lock_info-> m_file .lock ();
220+ std::unique_lock mutex_lock (m_local_mutex);
221+ m_file.lock ();
339222 mutex_lock.release ();
340223#else
341224
@@ -352,21 +235,16 @@ inline void InterprocessMutex::lock()
352235inline bool InterprocessMutex::try_lock ()
353236{
354237#if REALM_ROBUST_MUTEX_EMULATION
355- std::unique_lock mutex_lock (m_lock_info-> m_local_mutex , std::try_to_lock_t ());
238+ std::unique_lock mutex_lock (m_local_mutex, std::try_to_lock_t ());
356239 if (!mutex_lock.owns_lock ()) {
357240 return false ;
358241 }
359- bool success = m_lock_info->m_file .try_lock ();
360- if (success) {
361- mutex_lock.release ();
362- return true ;
363- }
364- else {
242+ if (!m_file.try_lock ()) {
365243 return false ;
366244 }
367- # else
368-
369- #ifdef _WIN32
245+ mutex_lock. release ();
246+ return true ;
247+ #elif defined( _WIN32)
370248 DWORD ret = WaitForSingleObject (m_handle, 0 );
371249 REALM_ASSERT_RELEASE (ret != WAIT_FAILED);
372250
@@ -380,15 +258,14 @@ inline bool InterprocessMutex::try_lock()
380258 REALM_ASSERT (m_shared_part);
381259 return m_shared_part->try_lock ([]() {});
382260#endif
383- #endif
384261}
385262
386263
387264inline void InterprocessMutex::unlock ()
388265{
389266#if REALM_ROBUST_MUTEX_EMULATION
390- m_lock_info-> m_file .unlock ();
391- m_lock_info-> m_local_mutex .unlock ();
267+ m_file.unlock ();
268+ m_local_mutex.unlock ();
392269#else
393270#ifdef _WIN32
394271 bool b = ReleaseMutex (m_handle);
0 commit comments