1 /*!
2  * \file  mfront/src/MFrontLock.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \brief 15 nov 2009
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #include<stdexcept>
15 #include<sstream>
16 #include<cerrno>
17 
18 #if !(defined _WIN32 || defined _WIN64 || defined __CYGWIN__)
19 #include<sys/types.h>
20 #include<sys/stat.h>
21 #include<fcntl.h>
22 #include<semaphore.h>
23 #include<unistd.h>
24 #endif
25 
26 #include"TFEL/Raise.hxx"
27 #include"TFEL/System/System.hxx"
28 #include"MFront/MFrontLogStream.hxx"
29 #include"MFront/MFrontLock.hxx"
30 
31 namespace mfront{
32 
getMFrontLock()33   MFrontLock& MFrontLock::getMFrontLock() {
34     static MFrontLock lock;
35     return lock;
36   } // end of MFrontLock::getMFrontLock
37 
MFrontLock()38   MFrontLock::MFrontLock() {
39 #if defined _WIN32 || defined _WIN64 ||defined __CYGWIN__
40     this->ghMutex = CreateMutex(nullptr,    // default security attributes
41                                 FALSE,      // initially not owned
42                                 "mfront");  // named mutex
43     tfel::raise_if(this->ghMutex == nullptr,
44                    "MFrontLock::MFrontLock: "
45                    "semaphore creation failed");
46 #else
47     std::ostringstream sn;
48     sn << "/mfront-" << ::geteuid();
49     this->l = ::sem_open(sn.str().c_str(),O_CREAT,S_IRUSR|S_IWUSR,1);
50     tfel::raise_if(this->l==SEM_FAILED,
51 		   "MFrontLock::MFrontLock: "
52 		   "semaphore creation failed");
53 #endif
54   } // end of MFrontLock::MFrontLock()
55 
lock()56   void MFrontLock::lock() {
57     if (getVerboseMode() >= VERBOSE_LEVEL2) {
58       getLogStream() << "MFrontLock::lock: "
59                      << "trying to lock semaphore\n";
60     }
61 #if defined _WIN32 || defined _WIN64 ||defined __CYGWIN__
62     DWORD dwWaitResult;
63     dwWaitResult = ::WaitForSingleObject(this->ghMutex,  // handle to mutex
64                                          INFINITE);      // no time-out interval
65     tfel::raise_if(dwWaitResult == WAIT_ABANDONED,
66                    "MFrontLock::MFrontLock: "
67                    "semaphore can't be aquired");
68 #else
69     tfel::raise_if(::sem_wait(this->l) == -1,
70                    "MFrontLock::MFrontLock: "
71                    "semaphore can't be aquired");
72 #endif
73   } // end of MFrontLock::lock()
74 
unlock()75   void MFrontLock::unlock() {
76     if (getVerboseMode() >= VERBOSE_LEVEL2) {
77       getLogStream() << "MFrontLock::unlock: "
78                      << "unlocking semaphore\n";
79     }
80 #if defined _WIN32 || defined _WIN64 ||defined __CYGWIN__
81     ::ReleaseMutex(this->ghMutex);
82 #else
83     ::sem_post(this->l);
84 #endif
85   } // end of MFrontLock::unlock()
86 
~MFrontLock()87   MFrontLock::~MFrontLock() {
88     this->unlock();
89   } // end of MFrontLock::~MFrontLock()
90 
MFrontLockGuard()91   MFrontLockGuard::MFrontLockGuard() {
92     MFrontLock::getMFrontLock().lock();
93   } // end of MFrontLockGuard::MFrontLockGuard
94 
~MFrontLockGuard()95   MFrontLockGuard::~MFrontLockGuard() {
96     MFrontLock::getMFrontLock().unlock();
97   } // end of MFrontLockGuard::~MFrontLockGuard
98 
99 } // end of namespace mfront
100