• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "buffer_object.h"
17 
18 #include "ipc_debug.h"
19 #include "log_tags.h"
20 #include "securec.h"
21 #include "sys_binder.h"
22 
23 namespace OHOS {
BufferObject()24 BufferObject::BufferObject()
25 {
26 }
27 
~BufferObject()28 BufferObject::~BufferObject()
29 {
30     if (receiveBuffer_ != nullptr) {
31         delete[] receiveBuffer_;
32         receiveBuffer_ = nullptr;
33     }
34     if (sendBuffer_ != nullptr) {
35         delete[] sendBuffer_;
36         sendBuffer_ = nullptr;
37     }
38 }
39 
40 /* update buffer need get mutex first */
UpdateSendBuffer(uint32_t userDataSize)41 void BufferObject::UpdateSendBuffer(uint32_t userDataSize)
42 {
43     if (sendBufferCursorW_ <= sendBufferCursorR_) {
44         sendBufferCursorW_ = 0;
45         sendBufferCursorR_ = 0;
46         return;
47     }
48     /* buffer is not enough, means need expand buffer */
49     if (sendBuffSize_ - sendBufferCursorW_ <= userDataSize) {
50         ExpandSendBuffer(sendBuffSize_ + sendBuffSize_);
51     }
52     /* check whether buffer size is enough, if not, move write/read cursor to head */
53     /* writeCursor always bigger than readCursor */
54     if (sendBuffSize_ - sendBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
55         sendBufferCursorW_ - sendBufferCursorR_ < sendBufferCursorR_) {
56         auto memcpyResult = memmove_s(sendBuffer_, sendBufferCursorW_ - sendBufferCursorR_,
57             sendBuffer_ + sendBufferCursorR_, sendBufferCursorW_ - sendBufferCursorR_);
58         if (memcpyResult != EOK) {
59             sendBufferCursorW_ = 0; // drop data in buffer, if memmove failed
60         } else {
61             sendBufferCursorW_ = sendBufferCursorW_ - sendBufferCursorR_;
62         }
63         sendBufferCursorR_ = 0;
64     }
65 }
66 
67 /* update buffer need get mutex first */
68 // LCOV_EXCL_START
UpdateReceiveBuffer()69 void BufferObject::UpdateReceiveBuffer()
70 {
71     if (recvBufferCursorW_ <= recvBufferCursorR_) {
72         recvBufferCursorR_ = 0;
73         recvBufferCursorW_ = 0;
74         return;
75     }
76     /* check whether buffer size is enough, if not, move write/read cursor to head */
77     /* writeCursor always bigger than readCursor */
78     if (recvBuffSize_ - recvBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
79         recvBufferCursorW_ - recvBufferCursorR_ < recvBufferCursorR_) {
80         auto memcpyResult = memmove_s(receiveBuffer_, recvBufferCursorW_ - recvBufferCursorR_,
81             receiveBuffer_ + recvBufferCursorR_, recvBufferCursorW_ - recvBufferCursorR_);
82         if (memcpyResult != EOK) {
83             recvBufferCursorW_ = 0; // drop data in buffer, if memmove failed
84         } else {
85             recvBufferCursorW_ = recvBufferCursorW_ - recvBufferCursorR_;
86         }
87         recvBufferCursorR_ = 0;
88     }
89 }
90 // LCOV_EXCL_STOP
91 
GetSendBufferAndLock(uint32_t size)92 char *BufferObject::GetSendBufferAndLock(uint32_t size)
93 {
94     uint32_t needSize = GetNeedBufferSize(size);
95     if (needSize == 0) {
96         return nullptr;
97     }
98     sendMutex_.lock();
99     if (!ExpandSendBuffer(size)) {
100         sendMutex_.unlock();
101         return nullptr;
102     }
103 
104     /* attention: need unlock mutex by caller */
105     return sendBuffer_;
106 }
107 
108 /* this function should be call in mutex locked */
ExpandSendBuffer(uint32_t size)109 bool BufferObject::ExpandSendBuffer(uint32_t size)
110 {
111     uint32_t needSize = GetNeedBufferSize(size);
112     if (needSize == 0) {
113         return true;
114     }
115     if (needSize > sendBuffSize_) {
116         char *newBuffer_ = new (std::nothrow) char[needSize];
117         if (newBuffer_ == nullptr) {
118             return false;
119         }
120 
121         if ((sendBuffer_ != nullptr) && (sendBuffSize_ != 0)) {
122             int memcpyResult = memcpy_s(newBuffer_, needSize, sendBuffer_, sendBuffSize_);
123             if (memcpyResult != 0) {
124                 delete[] newBuffer_;
125                 return false;
126             }
127         }
128 
129         delete[] sendBuffer_;
130         sendBuffer_ = newBuffer_;
131         sendBuffSize_ = needSize;
132     }
133     return true;
134 }
135 
GetReceiveBufferAndLock(uint32_t size)136 char *BufferObject::GetReceiveBufferAndLock(uint32_t size)
137 {
138     uint32_t needSize = GetNeedBufferSize(size);
139     if (needSize == 0) {
140         return nullptr;
141     }
142     recvMutex_.lock();
143     if (needSize > recvBuffSize_) {
144         char *newBuffer_ = new (std::nothrow) char[needSize];
145         if (newBuffer_ == nullptr) {
146             recvMutex_.unlock();
147             return nullptr;
148         }
149 
150         if ((receiveBuffer_ != nullptr) && (recvBuffSize_ != 0)) {
151             int memcpyResult = memcpy_s(newBuffer_, needSize, receiveBuffer_, recvBuffSize_);
152             if (memcpyResult != 0) {
153                 delete[] newBuffer_;
154                 recvMutex_.unlock();
155                 return nullptr;
156             }
157         }
158 
159         delete[] receiveBuffer_;
160         receiveBuffer_ = newBuffer_;
161         recvBuffSize_ = needSize;
162     }
163 
164     /* attention: need unlock mutex by caller */
165     return receiveBuffer_;
166 }
167 
ReleaseSendBufferLock()168 void BufferObject::ReleaseSendBufferLock()
169 {
170     sendMutex_.unlock();
171 }
172 
ReleaseReceiveBufferLock()173 void BufferObject::ReleaseReceiveBufferLock()
174 {
175     recvMutex_.unlock();
176 }
177 
GetReceiveBufferWriteCursor() const178 ssize_t BufferObject::GetReceiveBufferWriteCursor() const
179 {
180     return recvBufferCursorW_;
181 }
182 
SetReceiveBufferWriteCursor(ssize_t newWriteCursor)183 void BufferObject::SetReceiveBufferWriteCursor(ssize_t newWriteCursor)
184 {
185     recvBufferCursorW_ = newWriteCursor;
186 }
187 
GetReceiveBufferReadCursor() const188 ssize_t BufferObject::GetReceiveBufferReadCursor() const
189 {
190     return recvBufferCursorR_;
191 }
192 
SetReceiveBufferReadCursor(ssize_t newReadCursor)193 void BufferObject::SetReceiveBufferReadCursor(ssize_t newReadCursor)
194 {
195     recvBufferCursorR_ = newReadCursor;
196 }
197 
GetSendBufferWriteCursor() const198 ssize_t BufferObject::GetSendBufferWriteCursor() const
199 {
200     return sendBufferCursorW_;
201 }
202 
SetSendBufferWriteCursor(ssize_t newWriteCursor)203 void BufferObject::SetSendBufferWriteCursor(ssize_t newWriteCursor)
204 {
205     sendBufferCursorW_ = newWriteCursor;
206 }
207 
GetSendBufferReadCursor() const208 ssize_t BufferObject::GetSendBufferReadCursor() const
209 {
210     return sendBufferCursorR_;
211 }
212 
SetSendBufferReadCursor(ssize_t newReadCursor)213 void BufferObject::SetSendBufferReadCursor(ssize_t newReadCursor)
214 {
215     sendBufferCursorR_ = newReadCursor;
216 }
217 
GetNeedBufferSize(uint32_t size) const218 uint32_t BufferObject::GetNeedBufferSize(uint32_t size) const
219 {
220     if (size <= SOCKET_BUFF_SIZE_USER_S) {
221         return SOCKET_BUFF_SIZE_USER_S;
222     } else if (size <= SOCKET_BUFF_SIZE_USER_M) {
223         return SOCKET_BUFF_SIZE_USER_M;
224     } else if (size <= SOCKET_BUFF_SIZE_USER_L) {
225         return SOCKET_BUFF_SIZE_USER_L;
226     } else if (size <= SOCKET_BUFF_SIZE_USER_HUGE) {
227         return SOCKET_BUFF_SIZE_USER_HUGE;
228     } else {
229         return 0;
230     }
231 }
232 
GetSendBufferSize() const233 uint32_t BufferObject::GetSendBufferSize() const
234 {
235     return sendBuffSize_;
236 }
237 
GetRecvBufferSize() const238 uint32_t BufferObject::GetRecvBufferSize() const
239 {
240     return recvBuffSize_;
241 }
242 } // namespace OHOS
243