Merge "Implemented client-server model and changed code for thread safety" into tizen_2.1
[platform/framework/native/appfw.git] / src / io / FIo_FileLockImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16
17 /**
18  * @file        FIo_FileLockImpl.cpp
19  * @brief       This is the implementation file for _FileLockImpl class.
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <new>
29 #include <unique_ptr.h>
30
31 #include <FBaseResult.h>
32 #include <FBaseSysLog.h>
33
34 #include <FBase_NativeError.h>
35 #include "FIo_FileImpl.h"
36 #include "FIo_FileLockImpl.h"
37
38 using namespace Tizen::Base;
39
40 namespace Tizen { namespace Io
41 {
42
43 _FileLockImpl::_FileLockImpl(void)
44         : __pFileImpl(null)
45         , __lockType(FileLockType(-1))
46         , __offset(-1)
47         , __size(-1)
48         , __pid(-1)
49 {
50 }
51
52 _FileLockImpl::~_FileLockImpl(void)
53 {
54         if (__pFileImpl != null)
55         {
56                 __pFileImpl->__pFileLockImpl = null;
57                 int fd = fileno(__pFileImpl->GetFilePointer());
58                 struct stat64 statbuf;
59                 SysTryReturnVoidResult(NID_IO, fstat64(fd, &statbuf) == 0, E_SYSTEM,
60                                 "[E_SYSTEM] Failed to get file status. errno: %d (%s)", errno, strerror(errno));
61                 // release the lock
62                 struct flock lock;
63                 if (__lockType == FILE_LOCK_SHARED)
64                 {
65                         lock.l_type = F_RDLCK;
66                 }
67                 else if (__lockType == FILE_LOCK_EXCLUSIVE)
68                 {
69                         lock.l_type = F_WRLCK;
70                 }
71                 lock.l_whence = SEEK_SET;
72                 lock.l_start = __offset;
73                 lock.l_len = __size;
74                 lock.l_pid = __pid;
75                 SysTryReturnVoidResult(NID_IO, fcntl(fd, F_UNLCK, &lock) == 0, E_SYSTEM,
76                                 "[E_SYSTEM] Failed to release the lock. errno: %d (%s)", errno, strerror(errno));
77         }
78 }
79
80 result
81 _FileLockImpl::Construct(const _FileImpl* pFileImpl, FileLockType lockType, int offset, int size, int pid)
82 {
83         SysTryReturnResult(NID_IO, pFileImpl != null, E_SYSTEM, "File instance is null.");
84
85         __pFileImpl = const_cast< _FileImpl* >(pFileImpl);
86         __lockType = lockType;
87         __offset = offset;
88         __size = size;
89         __pid = pid;
90         return E_SUCCESS;
91 }
92
93 _FileLockImpl*
94 _FileLockImpl::GetInstance(FileLock& fileLock)
95 {
96         return fileLock.__pFileLockImpl;
97 }
98
99 const _FileLockImpl*
100 _FileLockImpl::GetInstance(const FileLock& fileLock)
101 {
102         return fileLock.__pFileLockImpl;
103 }
104
105 bool
106 _FileLockImpl::IsShared(void) const
107 {
108         SetLastResult(E_SUCCESS);
109         return (__lockType == FILE_LOCK_SHARED) ? true : false;
110 }
111
112 bool
113 _FileLockImpl::IsExclusive(void) const
114 {
115         SetLastResult(E_SUCCESS);
116         return (__lockType == FILE_LOCK_EXCLUSIVE) ? true : false;
117 }
118
119 bool
120 _FileLockImpl::IsValid(void) const
121 {
122         struct stat64 statbuf;
123         SysTryReturn(NID_IO, __pFileImpl != null && (fstat64(fileno(__pFileImpl->GetFilePointer()), &statbuf) == 0),
124                         false, E_SYSTEM, "[E_SYSTEM} File lock is invalid.");
125         SetLastResult(E_SUCCESS);
126         return true;
127 }
128
129 FileLock*
130 _FileLockImpl::CreateFileLockInstanceN(const _FileImpl* pFileImpl, FileLockType lockType, int offset, int size, int pid)
131 {
132         std::unique_ptr<FileLock> pFileLock(new (std::nothrow) FileLock());
133         SysTryReturn(NID_IO, pFileLock != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
134         _FileLockImpl* pFileLockImpl = _FileLockImpl::GetInstance(*pFileLock);
135
136         result r = pFileLockImpl->Construct(pFileImpl, lockType, offset, size, pid);
137         SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagating to caller...", GetErrorMessage(r));
138
139         SetLastResult(E_SUCCESS);
140         return pFileLock.release();
141 }
142
143 }} // Tizen::Io