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 */
UpdateReceiveBuffer()68 void BufferObject::UpdateReceiveBuffer()
69 {
70 if (recvBufferCursorW_ <= recvBufferCursorR_) {
71 recvBufferCursorR_ = 0;
72 recvBufferCursorW_ = 0;
73 return;
74 }
75 /* check whether buffer size is enough, if not, move write/read cursor to head */
76 /* writeCursor always bigger than readCursor */
77 if (recvBuffSize_ - recvBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
78 recvBufferCursorW_ - recvBufferCursorR_ < recvBufferCursorR_) {
79 auto memcpyResult = memmove_s(receiveBuffer_, recvBufferCursorW_ - recvBufferCursorR_,
80 receiveBuffer_ + recvBufferCursorR_, recvBufferCursorW_ - recvBufferCursorR_);
81 if (memcpyResult != EOK) {
82 recvBufferCursorW_ = 0; // drop data in buffer, if memmove failed
83 } else {
84 recvBufferCursorW_ = recvBufferCursorW_ - recvBufferCursorR_;
85 }
86 recvBufferCursorR_ = 0;
87 }
88 }
89
GetSendBufferAndLock(uint32_t size)90 char *BufferObject::GetSendBufferAndLock(uint32_t size)
91 {
92 uint32_t needSize = GetNeedBufferSize(size);
93 if (needSize == 0) {
94 return nullptr;
95 }
96 sendMutex_.lock();
97 if (!ExpandSendBuffer(size)) {
98 sendMutex_.unlock();
99 return nullptr;
100 }
101
102 /* attention: need unlock mutex by caller */
103 return sendBuffer_;
104 }
105
106 /* this function should be call in mutex locked */
ExpandSendBuffer(uint32_t size)107 bool BufferObject::ExpandSendBuffer(uint32_t size)
108 {
109 uint32_t needSize = GetNeedBufferSize(size);
110 if (needSize == 0) {
111 return true;
112 }
113 if (needSize > sendBuffSize_) {
114 char *newBuffer_ = new (std::nothrow) char[needSize];
115 if (newBuffer_ == nullptr) {
116 return false;
117 }
118
119 if ((sendBuffer_ != nullptr) && (sendBuffSize_ != 0)) {
120 int memcpyResult = memcpy_s(newBuffer_, needSize, sendBuffer_, sendBuffSize_);
121 if (memcpyResult != 0) {
122 delete[] newBuffer_;
123 return false;
124 }
125 }
126
127 delete[] sendBuffer_;
128 sendBuffer_ = newBuffer_;
129 sendBuffSize_ = needSize;
130 }
131 return true;
132 }
133
GetReceiveBufferAndLock(uint32_t size)134 char *BufferObject::GetReceiveBufferAndLock(uint32_t size)
135 {
136 uint32_t needSize = GetNeedBufferSize(size);
137 if (needSize == 0) {
138 return nullptr;
139 }
140 recvMutex_.lock();
141 if (needSize > recvBuffSize_) {
142 char *newBuffer_ = new (std::nothrow) char[needSize];
143 if (newBuffer_ == nullptr) {
144 recvMutex_.unlock();
145 return nullptr;
146 }
147
148 if ((receiveBuffer_ != nullptr) && (recvBuffSize_ != 0)) {
149 int memcpyResult = memcpy_s(newBuffer_, needSize, receiveBuffer_, recvBuffSize_);
150 if (memcpyResult != 0) {
151 delete[] newBuffer_;
152 recvMutex_.unlock();
153 return nullptr;
154 }
155 }
156
157 delete[] receiveBuffer_;
158 receiveBuffer_ = newBuffer_;
159 recvBuffSize_ = needSize;
160 }
161
162 /* attention: need unlock mutex by caller */
163 return receiveBuffer_;
164 }
165
ReleaseSendBufferLock()166 void BufferObject::ReleaseSendBufferLock()
167 {
168 sendMutex_.unlock();
169 }
170
ReleaseReceiveBufferLock()171 void BufferObject::ReleaseReceiveBufferLock()
172 {
173 recvMutex_.unlock();
174 }
175
GetReceiveBufferWriteCursor() const176 ssize_t BufferObject::GetReceiveBufferWriteCursor() const
177 {
178 return recvBufferCursorW_;
179 }
180
SetReceiveBufferWriteCursor(ssize_t newWriteCursor)181 void BufferObject::SetReceiveBufferWriteCursor(ssize_t newWriteCursor)
182 {
183 recvBufferCursorW_ = newWriteCursor;
184 }
185
GetReceiveBufferReadCursor() const186 ssize_t BufferObject::GetReceiveBufferReadCursor() const
187 {
188 return recvBufferCursorR_;
189 }
190
SetReceiveBufferReadCursor(ssize_t newReadCursor)191 void BufferObject::SetReceiveBufferReadCursor(ssize_t newReadCursor)
192 {
193 recvBufferCursorR_ = newReadCursor;
194 }
195
GetSendBufferWriteCursor() const196 ssize_t BufferObject::GetSendBufferWriteCursor() const
197 {
198 return sendBufferCursorW_;
199 }
200
SetSendBufferWriteCursor(ssize_t newWriteCursor)201 void BufferObject::SetSendBufferWriteCursor(ssize_t newWriteCursor)
202 {
203 sendBufferCursorW_ = newWriteCursor;
204 }
205
GetSendBufferReadCursor() const206 ssize_t BufferObject::GetSendBufferReadCursor() const
207 {
208 return sendBufferCursorR_;
209 }
210
SetSendBufferReadCursor(ssize_t newReadCursor)211 void BufferObject::SetSendBufferReadCursor(ssize_t newReadCursor)
212 {
213 sendBufferCursorR_ = newReadCursor;
214 }
215
GetNeedBufferSize(uint32_t size) const216 uint32_t BufferObject::GetNeedBufferSize(uint32_t size) const
217 {
218 if (size <= SOCKET_BUFF_SIZE_USER_S) {
219 return SOCKET_BUFF_SIZE_USER_S;
220 } else if (size <= SOCKET_BUFF_SIZE_USER_M) {
221 return SOCKET_BUFF_SIZE_USER_M;
222 } else if (size <= SOCKET_BUFF_SIZE_USER_L) {
223 return SOCKET_BUFF_SIZE_USER_L;
224 } else if (size <= SOCKET_BUFF_SIZE_USER_HUGE) {
225 return SOCKET_BUFF_SIZE_USER_HUGE;
226 } else {
227 return 0;
228 }
229 }
230
GetSendBufferSize() const231 uint32_t BufferObject::GetSendBufferSize() const
232 {
233 return sendBuffSize_;
234 }
235
GetRecvBufferSize() const236 uint32_t BufferObject::GetRecvBufferSize() const
237 {
238 return recvBuffSize_;
239 }
240 } // namespace OHOS
241