1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef DMLOCK_H 18 #define DMLOCK_H 19 20 #ifndef __cplusplus 21 #error "This is a C++ header file; it requires C++ to compile." 22 #endif 23 24 /*================================================================================================== 25 26 Header Name: dmLock.h 27 28 General Description: Declaration of DMFileLockingThread, Clock and DMLockManager classes. 29 30 ==================================================================================================*/ 31 32 #include "dmdefs.h" 33 #include "SyncML_DM_FileHandle.H" 34 #include "dmvector.h" 35 #include "file_manager.h" 36 #include "dmtDefs.h" 37 38 #ifndef DM_NO_LOCKING 39 #include "dmThreadQueue.h" 40 #endif 41 42 enum { 43 SYNCML_DM_LOCKID_NONE = 0, 44 SYNCML_DM_LOCKID_IGNORE = 2, 45 SYNCML_DM_LOCKID_CURRENT = 4 46 }; // predefined lock ids: ignore - means "no lock", current - means "whatever is registered" 47 typedef UINT8 SYNCML_DM_LOCKID_T; 48 49 enum { 50 SYNCML_DM_FILE_LOCK_STATUS_IN_PROGRESS, 51 SYNCML_DM_FILE_LOCK_STATUS_OK, 52 SYNCML_DM_FILE_LOCK_STATUS_TRY_AGAIN, 53 SYNCML_DM_FILE_LOCK_STATUS_ERROR 54 }; 55 typedef UINT8 SYNCML_DM_FILE_LOCK_STATUS_T; 56 57 enum { 58 SYNCML_DM_THREAD_STARTING, 59 SYNCML_DM_THREAD_STARTED, 60 SYNCML_DM_THREAD_FAILED 61 }; 62 typedef UINT8 SYNCML_DM_THREAD_STATUS_T; 63 64 65 enum { 66 /** Lock applied on ACL file */ 67 SYNCML_DM_FILE_ACL = 0, 68 /** Lock applied on Event file */ 69 SYNCML_DM_FILE_EVENT = 1, 70 }; 71 typedef UINT8 SYNCML_DM_FILE_TYPE_T; 72 73 74 #ifndef DM_NO_LOCKING 75 struct DMFileLockParam 76 { 77 INT32* m_pDoneFlag; 78 BOOLEAN m_bIsLock; 79 FILESETTYPE m_nLockSet; 80 SYNCML_DM_TREE_LOCK_TYPE_T m_eLockType; 81 }; 82 83 class DMLock 84 { 85 public: 86 /** 87 * Default constructor 88 */ 89 DMLock() ; 90 91 /** 92 * Destructor 93 */ 94 ~DMLock() ; 95 96 /** 97 * Initializes file lock 98 * \param szLockFileName [in] - lock file name 99 * \return Return Type (SYNCML_DM_RET_STATUS_T) 100 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 101 * - All other codes indicate failure. 102 */ 103 SYNCML_DM_RET_STATUS_T Init( CPCHAR szLockFileName) ; 104 105 /** 106 * Cleanups file lock 107 * \return Return Type (SYNCML_DM_RET_STATUS_T) 108 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 109 * - All other codes indicate failure. 110 */ 111 SYNCML_DM_RET_STATUS_T Destroy() ; 112 113 /** 114 * Locks file 115 * \param eLockType [in] - type of DM lock 116 * \return Return Type (SYNCML_DM_RET_STATUS_T) 117 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 118 * - All other codes indicate failure. 119 */ 120 SYNCML_DM_RET_STATUS_T Lock( SYNCML_DM_TREE_LOCK_TYPE_T eLockType); 121 122 /** 123 * Unlocks file 124 * \return Return Type (SYNCML_DM_RET_STATUS_T) 125 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 126 * - All other codes indicate failure. 127 */ 128 SYNCML_DM_RET_STATUS_T Unlock() ; 129 130 /** 131 * Verifies if lock counter equal 1 (last reader) 132 */ 133 inline BOOLEAN IsLastLock() { return ( (m_nReadWriteCounter <= 1) ? TRUE : FALSE ); } 134 135 protected: 136 /** Tree pointer */ 137 DMFileHandler* m_pFile; 138 /**Number of readers (>0) or writers (<0)*/ 139 INT32 m_nReadWriteCounter; 140 141 public: 142 /** Saves system handles and use only 1 mutex, since it's locked time very short */ 143 static DMCriticalSection m_csLock ; 144 145 }; 146 147 class DMLockManager; 148 149 150 class DMFileLockingThread : public DMThread 151 { 152 public: 153 154 /** 155 * Constructor 156 * \param pLockManager [in] - pointer on file lock manager 157 */ 158 DMFileLockingThread ( DMLockManager* pLockManager ) ; 159 160 /** 161 * Retrieves thread state 162 */ 163 SYNCML_DM_THREAD_STATUS_T GetThreadState() const; 164 165 protected: 166 /** 167 * Thread run method 168 */ 169 virtual void* Run(); 170 /**Thread state */ 171 SYNCML_DM_THREAD_STATUS_T m_nReady; 172 /** Memory check interval time in msec */ 173 INT32 m_nAgingCheckInterval; 174 /** File lock manager */ 175 DMLockManager * m_pLockManager; 176 }; 177 178 179 class DMLockManager 180 { 181 public: 182 /** 183 * Default constructor 184 */ 185 DMLockManager() ; 186 187 /** 188 * Destructor 189 */ 190 ~DMLockManager() ; 191 192 /** 193 * Initializes locking manager 194 * \param szLockFileNamePrefix [in] - lock file name preffix 195 * \param nNumberOfLocks [in] - maximum number of locks to be applied 196 * \return Return Type (SYNCML_DM_RET_STATUS_T) 197 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 198 * - All other codes indicate failure. 199 */ 200 SYNCML_DM_RET_STATUS_T Init(CPCHAR szLockFileNamePrefix, 201 INT32 nNumberOfLocks ) ; 202 203 /** 204 * Cleanups locking manager 205 * \return Return Type (SYNCML_DM_RET_STATUS_T) 206 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 207 * - All other codes indicate failure. 208 */ 209 SYNCML_DM_RET_STATUS_T Destroy() ; 210 211 /** 212 * Locks file set 213 * \param nLockSet [in] - lock set 214 * \param eLockType [in] - type of lock 215 * \return Return Type (SYNCML_DM_RET_STATUS_T) 216 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 217 * - All other codes indicate failure. 218 */ 219 SYNCML_DM_RET_STATUS_T LockSet( FILESETTYPE nLockSet, 220 SYNCML_DM_TREE_LOCK_TYPE_T eLockType) ; 221 222 /** 223 * Unlocks file set 224 * \param nLockSet [in] - lock set 225 * \param eLockType [in] - type of lock 226 * \return Return Type (SYNCML_DM_RET_STATUS_T) 227 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 228 * - All other codes indicate failure. 229 */ 230 SYNCML_DM_RET_STATUS_T UnlockSet( FILESETTYPE nLockSet, 231 SYNCML_DM_TREE_LOCK_TYPE_T eLockType) ; 232 233 /** 234 * Processes lock request by service thread 235 * \param pFileLockMsg [in] - locking request 236 * \returns TRUE if request is successful 237 */ 238 BOOLEAN ProcessLockRequest( DMFileLockParam* pFileLockMsg ) ; 239 240 /** 241 * Retrieves pointer on message queue 242 */ 243 DMThreadQueue* GetQueue() const {return m_ptrQueue;} 244 245 246 /** 247 * Unlocks acl or event file 248 * \param eFileType [in] - type of a file 249 * \return Return Type (SYNCML_DM_RET_STATUS_T) 250 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 251 * - All other codes indicate failure. 252 */ 253 SYNCML_DM_RET_STATUS_T ReleaseFile(SYNCML_DM_FILE_TYPE_T eFileType); 254 255 /** 256 * Unlocks acl or event file 257 * \param eFileType [in] - type of a file 258 * \return Return Type (SYNCML_DM_RET_STATUS_T) 259 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 260 * - All other codes indicate failure. 261 */ 262 SYNCML_DM_RET_STATUS_T AcquireFile(SYNCML_DM_FILE_TYPE_T eFileType); 263 264 private: 265 /** 266 * Sends locking request to management thread Unlocks acl or event file 267 * \param nOperation [in] - type requested operation (lock/unlock) 268 * \param nLockSet [in] - file set to lock 269 * \param eLockType [in] - type of requested lock 270 * \return Return Type (SYNCML_DM_RET_STATUS_T) 271 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 272 * - All other codes indicate failure. 273 */ 274 SYNCML_DM_RET_STATUS_T SendAndWait(BOOLEAN bIsLock, 275 FILESETTYPE nLockSet, 276 INT32 eLockType ) ; 277 278 private: 279 /** Vector of locks */ 280 DMVector<DMLock> m_aLocks; 281 /** Housekeeping thread */ 282 DMFileLockingThread m_oThread; 283 /** Tree pointer */ 284 PDMThreadQueue m_ptrQueue; 285 286 /** 287 * Starts DM house keeping thread 288 * \return Return Type (SYNCML_DM_RET_STATUS_T) 289 * - SYNCML_DM_SUCCESS - indicate that operation is completed successfully. 290 * - All other codes indicate failure. 291 */ 292 SYNCML_DM_RET_STATUS_T StartThread(); 293 294 }; 295 296 inline SYNCML_DM_THREAD_STATUS_T DMFileLockingThread::GetThreadState() const 297 { 298 return m_nReady; 299 } 300 301 #endif // !DM_NO_LOCKING 302 #endif // !DMLOCK_H 303