ECLockManager.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <memory>
  18. #include <mutex>
  19. #include <kopano/platform.h>
  20. #include "ECLockManager.h"
  21. #include <kopano/lockhelper.hpp>
  22. using namespace std;
  23. namespace KC {
  24. class ECObjectLockImpl {
  25. public:
  26. ECObjectLockImpl(ECLockManagerPtr ptrLockManager, unsigned int ulObjId, ECSESSIONID sessionId);
  27. ECObjectLockImpl(const ECObjectLockImpl &) = delete;
  28. ~ECObjectLockImpl();
  29. void operator=(const ECObjectLockImpl &) = delete;
  30. ECRESULT Unlock();
  31. private:
  32. std::weak_ptr<ECLockManager> m_ptrLockManager;
  33. unsigned int m_ulObjId;
  34. ECSESSIONID m_sessionId;
  35. };
  36. ECObjectLockImpl::ECObjectLockImpl(ECLockManagerPtr ptrLockManager, unsigned int ulObjId, ECSESSIONID sessionId)
  37. : m_ptrLockManager(ptrLockManager)
  38. , m_ulObjId(ulObjId)
  39. , m_sessionId(sessionId)
  40. { }
  41. ECObjectLockImpl::~ECObjectLockImpl() {
  42. Unlock();
  43. }
  44. ECRESULT ECObjectLockImpl::Unlock() {
  45. ECRESULT er = erSuccess;
  46. ECLockManagerPtr ptrLockManager = m_ptrLockManager.lock();
  47. if (ptrLockManager) {
  48. er = ptrLockManager->UnlockObject(m_ulObjId, m_sessionId);
  49. if (er == erSuccess)
  50. m_ptrLockManager.reset();
  51. }
  52. return er;
  53. }
  54. ECObjectLock::ECObjectLock(ECLockManagerPtr ptrLockManager, unsigned int ulObjId, ECSESSIONID sessionId)
  55. : m_ptrImpl(new ECObjectLockImpl(ptrLockManager, ulObjId, sessionId))
  56. { }
  57. ECRESULT ECObjectLock::Unlock() {
  58. ECRESULT er = erSuccess;
  59. er = m_ptrImpl->Unlock();
  60. if (er == erSuccess)
  61. m_ptrImpl.reset();
  62. return er;
  63. }
  64. ECLockManagerPtr ECLockManager::Create() {
  65. return ECLockManagerPtr(new ECLockManager());
  66. }
  67. ECRESULT ECLockManager::LockObject(unsigned int ulObjId, ECSESSIONID sessionId, ECObjectLock *lpObjectLock)
  68. {
  69. ECRESULT er = erSuccess;
  70. std::lock_guard<KC::shared_mutex> lock(m_hRwLock);
  71. auto res = m_mapLocks.insert(LockMap::value_type(ulObjId, sessionId));
  72. if (res.second == false && res.first->second != sessionId)
  73. er = KCERR_NO_ACCESS;
  74. if (lpObjectLock)
  75. *lpObjectLock = ECObjectLock(shared_from_this(), ulObjId, sessionId);
  76. return er;
  77. }
  78. ECRESULT ECLockManager::UnlockObject(unsigned int ulObjId, ECSESSIONID sessionId)
  79. {
  80. ECRESULT er = erSuccess;
  81. std::lock_guard<KC::shared_mutex> lock(m_hRwLock);
  82. auto i = m_mapLocks.find(ulObjId);
  83. if (i == m_mapLocks.cend())
  84. er = KCERR_NOT_FOUND;
  85. else if (i->second != sessionId)
  86. er = KCERR_NO_ACCESS;
  87. else
  88. m_mapLocks.erase(i);
  89. return er;
  90. }
  91. bool ECLockManager::IsLocked(unsigned int ulObjId, ECSESSIONID *lpSessionId)
  92. {
  93. KC::shared_lock<KC::shared_mutex> lock(m_hRwLock);
  94. auto i = m_mapLocks.find(ulObjId);
  95. if (i != m_mapLocks.cend() && lpSessionId != NULL)
  96. *lpSessionId = i->second;
  97. return i != m_mapLocks.end();
  98. }
  99. } /* namespace */