• 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 #include "securec.h"
18 #include "sys_binder.h"
19 #include "ipc_debug.h"
20 #include "log_tags.h"
21 
22 namespace OHOS {
BufferObject()23 BufferObject::BufferObject()
24 {
25 }
26 
~BufferObject()27 BufferObject::~BufferObject()
28 {
29     if (receiveBuffer_ != nullptr) {
30         delete[] receiveBuffer_;
31         receiveBuffer_ = nullptr;
32     }
33     if (sendBuffer_ != nullptr) {
34         delete[] sendBuffer_;
35         sendBuffer_ = nullptr;
36     }
37 }
38 
39 /* update buffer need get mutex first */
UpdateSendBuffer(uint32_t userDataSize)40 void BufferObject::UpdateSendBuffer(uint32_t userDataSize)
41 {
42     if (sendBufferCursorW_ <= sendBufferCursorR_) {
43         sendBufferCursorW_ = 0;
44         sendBufferCursorR_ = 0;
45         return;
46     }
47     /* buffer is not enough, means need expand buffer */
48     if (sendBuffSize_ - sendBufferCursorW_ <= userDataSize) {
49         ExpandSendBuffer(sendBuffSize_ + sendBuffSize_);
50     }
51     /* check whether buffer size is enough, if not, move write/read cursor to head */
52     if (sendBuffSize_ - sendBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE) {
53         /* writeCursor always bigger than readCursor */
54         if (sendBufferCursorW_ - sendBufferCursorR_ < sendBufferCursorR_) {
55             auto memcpyResult = memmove_s(sendBuffer_, sendBufferCursorW_ - sendBufferCursorR_,
56                 sendBuffer_ + sendBufferCursorR_, sendBufferCursorW_ - sendBufferCursorR_);
57             if (memcpyResult != EOK) {
58                 sendBufferCursorW_ = 0; // drop data in buffer, if memmove failed
59             } else {
60                 sendBufferCursorW_ = sendBufferCursorW_ - sendBufferCursorR_;
61             }
62             sendBufferCursorR_ = 0;
63         }
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     if (recvBuffSize_ - recvBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE) {
77         /* writeCursor always bigger than readCursor */
78         if (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 }
90 
GetSendBufferAndLock(uint32_t size)91 char *BufferObject::GetSendBufferAndLock(uint32_t size)
92 {
93     uint32_t needSize = GetNeedBufferSize(size);
94     if (needSize == 0) {
95         return nullptr;
96     }
97     sendMutex_.lock();
98     if (!ExpandSendBuffer(size)) {
99         sendMutex_.unlock();
100         return nullptr;
101     }
102 
103     /* attention: need unlock mutex by caller */
104     return sendBuffer_;
105 }
106 
107 /* this function should be call in mutex locked */
ExpandSendBuffer(uint32_t size)108 bool BufferObject::ExpandSendBuffer(uint32_t size)
109 {
110     uint32_t needSize = GetNeedBufferSize(size);
111     if (needSize == 0) {
112         return true;
113     }
114     if (needSize > sendBuffSize_) {
115         char *newBuffer_ = new (std::nothrow) char[needSize];
116         if (newBuffer_ == nullptr) {
117             return false;
118         }
119 
120         if ((sendBuffer_ != nullptr) && (sendBuffSize_ != 0)) {
121             int memcpyResult = memcpy_s(newBuffer_, needSize, sendBuffer_, sendBuffSize_);
122             if (memcpyResult != 0) {
123                 delete[] newBuffer_;
124                 return false;
125             }
126         }
127 
128         delete[] sendBuffer_;
129         sendBuffer_ = newBuffer_;
130         sendBuffSize_ = needSize;
131     }
132     return true;
133 }
134 
GetReceiveBufferAndLock(uint32_t size)135 char *BufferObject::GetReceiveBufferAndLock(uint32_t size)
136 {
137     uint32_t needSize = GetNeedBufferSize(size);
138     if (needSize == 0) {
139         return nullptr;
140     }
141     recvMutex_.lock();
142     if (needSize > recvBuffSize_) {
143         char *newBuffer_ = new (std::nothrow) char[needSize];
144         if (newBuffer_ == nullptr) {
145             recvMutex_.unlock();
146             return nullptr;
147         }
148 
149         if ((receiveBuffer_ != nullptr) && (recvBuffSize_ != 0)) {
150             int memcpyResult = memcpy_s(newBuffer_, needSize, receiveBuffer_, recvBuffSize_);
151             if (memcpyResult != 0) {
152                 delete[] newBuffer_;
153                 recvMutex_.unlock();
154                 return nullptr;
155             }
156         }
157 
158         delete[] receiveBuffer_;
159         receiveBuffer_ = newBuffer_;
160         recvBuffSize_ = needSize;
161     }
162 
163     /* attention: need unlock mutex by caller */
164     return receiveBuffer_;
165 }
166 
ReleaseSendBufferLock()167 void BufferObject::ReleaseSendBufferLock()
168 {
169     sendMutex_.unlock();
170 }
171 
ReleaseReceiveBufferLock()172 void BufferObject::ReleaseReceiveBufferLock()
173 {
174     recvMutex_.unlock();
175 }
176 
GetReceiveBufferWriteCursor() const177 ssize_t BufferObject::GetReceiveBufferWriteCursor() const
178 {
179     return recvBufferCursorW_;
180 }
181 
SetReceiveBufferWriteCursor(ssize_t newWriteCursor)182 void BufferObject::SetReceiveBufferWriteCursor(ssize_t newWriteCursor)
183 {
184     recvBufferCursorW_ = newWriteCursor;
185 }
186 
GetReceiveBufferReadCursor() const187 ssize_t BufferObject::GetReceiveBufferReadCursor() const
188 {
189     return recvBufferCursorR_;
190 }
191 
SetReceiveBufferReadCursor(ssize_t newReadCursor)192 void BufferObject::SetReceiveBufferReadCursor(ssize_t newReadCursor)
193 {
194     recvBufferCursorR_ = newReadCursor;
195 }
196 
GetSendBufferWriteCursor() const197 ssize_t BufferObject::GetSendBufferWriteCursor() const
198 {
199     return sendBufferCursorW_;
200 }
201 
SetSendBufferWriteCursor(ssize_t newWriteCursor)202 void BufferObject::SetSendBufferWriteCursor(ssize_t newWriteCursor)
203 {
204     sendBufferCursorW_ = newWriteCursor;
205 }
206 
GetSendBufferReadCursor() const207 ssize_t BufferObject::GetSendBufferReadCursor() const
208 {
209     return sendBufferCursorR_;
210 }
211 
SetSendBufferReadCursor(ssize_t newReadCursor)212 void BufferObject::SetSendBufferReadCursor(ssize_t newReadCursor)
213 {
214     sendBufferCursorR_ = newReadCursor;
215 }
216 
GetNeedBufferSize(uint32_t size) const217 uint32_t BufferObject::GetNeedBufferSize(uint32_t size) const
218 {
219     if (size <= SOCKET_BUFF_SIZE_USER_S) {
220         return SOCKET_BUFF_SIZE_USER_S;
221     } else if (size <= SOCKET_BUFF_SIZE_USER_M) {
222         return SOCKET_BUFF_SIZE_USER_M;
223     } else if (size <= SOCKET_BUFF_SIZE_USER_L) {
224         return SOCKET_BUFF_SIZE_USER_L;
225     } else if (size <= SOCKET_BUFF_SIZE_USER_HUGE) {
226         return SOCKET_BUFF_SIZE_USER_HUGE;
227     } else {
228         return 0;
229     }
230 }
231 
GetSendBufferSize() const232 uint32_t BufferObject::GetSendBufferSize() const
233 {
234     return sendBuffSize_;
235 }
236 
GetRecvBufferSize() const237 uint32_t BufferObject::GetRecvBufferSize() const
238 {
239     return recvBuffSize_;
240 }
241 } // namespace OHOS
242