1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci#include "file_descriptor.h"
16cc290419Sopenharmony_ci#ifndef HDC_HOST
17cc290419Sopenharmony_ci#include <sys/epoll.h>
18cc290419Sopenharmony_ci#endif
19cc290419Sopenharmony_ci
20cc290419Sopenharmony_cinamespace Hdc {
21cc290419Sopenharmony_cistatic const int SECONDS_TIMEOUT = 5;
22cc290419Sopenharmony_ci
23cc290419Sopenharmony_ciHdcFileDescriptor::HdcFileDescriptor(uv_loop_t *loopIn, int fdToRead, void *callerContextIn,
24cc290419Sopenharmony_ci                                     CallBackWhenRead callbackReadIn, CmdResultCallback callbackFinishIn,
25cc290419Sopenharmony_ci                                     bool interactiveShell)
26cc290419Sopenharmony_ci{
27cc290419Sopenharmony_ci    loop = loopIn;
28cc290419Sopenharmony_ci    workContinue = true;
29cc290419Sopenharmony_ci    callbackFinish = callbackFinishIn;
30cc290419Sopenharmony_ci    callbackRead = callbackReadIn;
31cc290419Sopenharmony_ci    fdIO = fdToRead;
32cc290419Sopenharmony_ci    refIO = 0;
33cc290419Sopenharmony_ci    isInteractive = interactiveShell;
34cc290419Sopenharmony_ci    callerContext = callerContextIn;
35cc290419Sopenharmony_ci    if (isInteractive) {
36cc290419Sopenharmony_ci        std::thread([this]() {
37cc290419Sopenharmony_ci            HdcFileDescriptor::IOWriteThread(this);
38cc290419Sopenharmony_ci        }).detach();
39cc290419Sopenharmony_ci    }
40cc290419Sopenharmony_ci}
41cc290419Sopenharmony_ci
42cc290419Sopenharmony_ciHdcFileDescriptor::~HdcFileDescriptor()
43cc290419Sopenharmony_ci{
44cc290419Sopenharmony_ci    workContinue = false;
45cc290419Sopenharmony_ci    if (isInteractive) {
46cc290419Sopenharmony_ci        NotifyWrite();
47cc290419Sopenharmony_ci        uv_sleep(MILL_SECONDS);
48cc290419Sopenharmony_ci    }
49cc290419Sopenharmony_ci}
50cc290419Sopenharmony_ci
51cc290419Sopenharmony_cibool HdcFileDescriptor::ReadyForRelease()
52cc290419Sopenharmony_ci{
53cc290419Sopenharmony_ci    return refIO == 0;
54cc290419Sopenharmony_ci}
55cc290419Sopenharmony_ci
56cc290419Sopenharmony_ci// just tryCloseFdIo = true, callback will be effect
57cc290419Sopenharmony_civoid HdcFileDescriptor::StopWorkOnThread(bool tryCloseFdIo, std::function<void()> closeFdCallback)
58cc290419Sopenharmony_ci{
59cc290419Sopenharmony_ci    workContinue = false;
60cc290419Sopenharmony_ci    if (isInteractive) {
61cc290419Sopenharmony_ci        NotifyWrite();
62cc290419Sopenharmony_ci    }
63cc290419Sopenharmony_ci
64cc290419Sopenharmony_ci    callbackCloseFd = closeFdCallback;
65cc290419Sopenharmony_ci    if (tryCloseFdIo && refIO > 0) {
66cc290419Sopenharmony_ci        if (callbackCloseFd != nullptr) {
67cc290419Sopenharmony_ci            callbackCloseFd();
68cc290419Sopenharmony_ci        }
69cc290419Sopenharmony_ci    }
70cc290419Sopenharmony_ci}
71cc290419Sopenharmony_ci
72cc290419Sopenharmony_civoid HdcFileDescriptor::FileIOOnThread(CtxFileIO *ctxIO, int bufSize)
73cc290419Sopenharmony_ci{
74cc290419Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INIF
75cc290419Sopenharmony_ci    mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
76cc290419Sopenharmony_ci    mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
77cc290419Sopenharmony_ci#endif
78cc290419Sopenharmony_ci    HdcFileDescriptor *thisClass = ctxIO->thisClass;
79cc290419Sopenharmony_ci    uint8_t *buf = ctxIO->bufIO;
80cc290419Sopenharmony_ci    bool bFinish = false;
81cc290419Sopenharmony_ci    bool fetalFinish = false;
82cc290419Sopenharmony_ci    ssize_t nBytes;
83cc290419Sopenharmony_ci#ifndef HDC_HOST
84cc290419Sopenharmony_ci    constexpr int epollSize = 1;
85cc290419Sopenharmony_ci    int epfd = epoll_create(epollSize);
86cc290419Sopenharmony_ci    struct epoll_event ev;
87cc290419Sopenharmony_ci    struct epoll_event events[epollSize];
88cc290419Sopenharmony_ci    ev.data.fd = thisClass->fdIO;
89cc290419Sopenharmony_ci    ev.events = EPOLLIN | EPOLLET;
90cc290419Sopenharmony_ci    epoll_ctl(epfd, EPOLL_CTL_ADD, thisClass->fdIO, &ev);
91cc290419Sopenharmony_ci#endif
92cc290419Sopenharmony_ci    while (true) {
93cc290419Sopenharmony_ci        if (thisClass->workContinue == false) {
94cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "FileIOOnThread fdIO:%d workContinue false", thisClass->fdIO);
95cc290419Sopenharmony_ci            bFinish = true;
96cc290419Sopenharmony_ci            break;
97cc290419Sopenharmony_ci        }
98cc290419Sopenharmony_ci
99cc290419Sopenharmony_ci        if (memset_s(buf, bufSize, 0, bufSize) != EOK) {
100cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "FileIOOnThread buf memset_s fail.");
101cc290419Sopenharmony_ci            bFinish = true;
102cc290419Sopenharmony_ci            break;
103cc290419Sopenharmony_ci        }
104cc290419Sopenharmony_ci#ifndef HDC_HOST
105cc290419Sopenharmony_ci        int rc = epoll_wait(epfd, events, epollSize, SECONDS_TIMEOUT * TIME_BASE);
106cc290419Sopenharmony_ci#else
107cc290419Sopenharmony_ci        struct timeval timeout;
108cc290419Sopenharmony_ci        timeout.tv_sec = SECONDS_TIMEOUT;
109cc290419Sopenharmony_ci        timeout.tv_usec = 0;
110cc290419Sopenharmony_ci        fd_set rset;
111cc290419Sopenharmony_ci        FD_ZERO(&rset);
112cc290419Sopenharmony_ci        FD_SET(thisClass->fdIO, &rset);
113cc290419Sopenharmony_ci        int rc = select(thisClass->fdIO + 1, &rset, nullptr, nullptr, &timeout);
114cc290419Sopenharmony_ci#endif
115cc290419Sopenharmony_ci        if (rc < 0) {
116cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "FileIOOnThread select or epoll_wait fdIO:%d error:%d",
117cc290419Sopenharmony_ci                thisClass->fdIO, errno);
118cc290419Sopenharmony_ci            if (errno == EINTR || errno == EAGAIN) {
119cc290419Sopenharmony_ci                continue;
120cc290419Sopenharmony_ci            }
121cc290419Sopenharmony_ci            bFinish = true;
122cc290419Sopenharmony_ci            break;
123cc290419Sopenharmony_ci        } else if (rc == 0) {
124cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "FileIOOnThread select rc = 0, timeout.");
125cc290419Sopenharmony_ci            continue;
126cc290419Sopenharmony_ci        }
127cc290419Sopenharmony_ci        nBytes = 0;
128cc290419Sopenharmony_ci#ifndef HDC_HOST
129cc290419Sopenharmony_ci        uint32_t event = events[0].events;
130cc290419Sopenharmony_ci        if ((event & EPOLLIN) && (thisClass->fdIO > 0)) {
131cc290419Sopenharmony_ci            nBytes = read(thisClass->fdIO, buf, bufSize);
132cc290419Sopenharmony_ci        }
133cc290419Sopenharmony_ci        if ((event & EPOLLERR) || (event & EPOLLHUP) || (event & EPOLLRDHUP)) {
134cc290419Sopenharmony_ci            bFinish = true;
135cc290419Sopenharmony_ci            fetalFinish = true;
136cc290419Sopenharmony_ci            if ((nBytes > 0) && !thisClass->callbackRead(thisClass->callerContext, buf, nBytes)) {
137cc290419Sopenharmony_ci                WRITE_LOG(LOG_WARN, "FileIOOnThread fdIO:%d callbackRead false", thisClass->fdIO);
138cc290419Sopenharmony_ci            }
139cc290419Sopenharmony_ci            break;
140cc290419Sopenharmony_ci        }
141cc290419Sopenharmony_ci        if (nBytes < 0 && (errno == EINTR || errno == EAGAIN)) {
142cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "FileIOOnThread fdIO:%d read interrupt", thisClass->fdIO);
143cc290419Sopenharmony_ci            continue;
144cc290419Sopenharmony_ci        }
145cc290419Sopenharmony_ci        if (nBytes > 0) {
146cc290419Sopenharmony_ci            if (!thisClass->callbackRead(thisClass->callerContext, buf, nBytes)) {
147cc290419Sopenharmony_ci                WRITE_LOG(LOG_WARN, "FileIOOnThread fdIO:%d callbackRead false", thisClass->fdIO);
148cc290419Sopenharmony_ci                bFinish = true;
149cc290419Sopenharmony_ci                break;
150cc290419Sopenharmony_ci            }
151cc290419Sopenharmony_ci            continue;
152cc290419Sopenharmony_ci        } else {
153cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "FileIOOnThread fd:%d nBytes:%d errno:%d",
154cc290419Sopenharmony_ci                thisClass->fdIO, nBytes, errno);
155cc290419Sopenharmony_ci            bFinish = true;
156cc290419Sopenharmony_ci            fetalFinish = true;
157cc290419Sopenharmony_ci            break;
158cc290419Sopenharmony_ci        }
159cc290419Sopenharmony_ci#else
160cc290419Sopenharmony_ci        if (thisClass->fdIO > 0) {
161cc290419Sopenharmony_ci            nBytes = read(thisClass->fdIO, buf, bufSize);
162cc290419Sopenharmony_ci        }
163cc290419Sopenharmony_ci        if (nBytes < 0 && (errno == EINTR || errno == EAGAIN)) {
164cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "FileIOOnThread fdIO:%d read interrupt", thisClass->fdIO);
165cc290419Sopenharmony_ci            continue;
166cc290419Sopenharmony_ci        }
167cc290419Sopenharmony_ci        if (nBytes > 0) {
168cc290419Sopenharmony_ci            if (!thisClass->callbackRead(thisClass->callerContext, buf, nBytes)) {
169cc290419Sopenharmony_ci                WRITE_LOG(LOG_WARN, "FileIOOnThread fdIO:%d callbackRead false", thisClass->fdIO);
170cc290419Sopenharmony_ci                bFinish = true;
171cc290419Sopenharmony_ci                break;
172cc290419Sopenharmony_ci            }
173cc290419Sopenharmony_ci            continue;
174cc290419Sopenharmony_ci        } else {
175cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "FileIOOnThread fd:%d nBytes:%d errno:%d",
176cc290419Sopenharmony_ci                thisClass->fdIO, nBytes, errno);
177cc290419Sopenharmony_ci            bFinish = true;
178cc290419Sopenharmony_ci            fetalFinish = true;
179cc290419Sopenharmony_ci            break;
180cc290419Sopenharmony_ci        }
181cc290419Sopenharmony_ci#endif
182cc290419Sopenharmony_ci    }
183cc290419Sopenharmony_ci#ifndef HDC_HOST
184cc290419Sopenharmony_ci    if ((thisClass->fdIO > 0) && (epoll_ctl(epfd, EPOLL_CTL_DEL, thisClass->fdIO, nullptr) == -1)) {
185cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "EPOLL_CTL_DEL fail fd:%d epfd:%d errno:%d",
186cc290419Sopenharmony_ci            thisClass->fdIO, epfd, errno);
187cc290419Sopenharmony_ci    }
188cc290419Sopenharmony_ci    close(epfd);
189cc290419Sopenharmony_ci#endif
190cc290419Sopenharmony_ci    if (buf != nullptr) {
191cc290419Sopenharmony_ci        delete[] buf;
192cc290419Sopenharmony_ci        buf = nullptr;
193cc290419Sopenharmony_ci    }
194cc290419Sopenharmony_ci    delete ctxIO;
195cc290419Sopenharmony_ci
196cc290419Sopenharmony_ci    --thisClass->refIO;
197cc290419Sopenharmony_ci    if (bFinish) {
198cc290419Sopenharmony_ci        thisClass->workContinue = false;
199cc290419Sopenharmony_ci        thisClass->callbackFinish(thisClass->callerContext, fetalFinish, STRING_EMPTY);
200cc290419Sopenharmony_ci    }
201cc290419Sopenharmony_ci}
202cc290419Sopenharmony_ci
203cc290419Sopenharmony_ciint HdcFileDescriptor::LoopReadOnThread()
204cc290419Sopenharmony_ci{
205cc290419Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INIF
206cc290419Sopenharmony_ci    mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
207cc290419Sopenharmony_ci    mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
208cc290419Sopenharmony_ci#endif
209cc290419Sopenharmony_ci    int readMax = Base::GetMaxBufSizeStable() * 1.2; // 120% of max buf size, use stable size to avoid no buf.
210cc290419Sopenharmony_ci    auto contextIO = new(std::nothrow) CtxFileIO();
211cc290419Sopenharmony_ci    auto buf = new(std::nothrow) uint8_t[readMax]();
212cc290419Sopenharmony_ci    if (!contextIO || !buf) {
213cc290419Sopenharmony_ci        if (contextIO) {
214cc290419Sopenharmony_ci            delete contextIO;
215cc290419Sopenharmony_ci        }
216cc290419Sopenharmony_ci        if (buf) {
217cc290419Sopenharmony_ci            delete[] buf;
218cc290419Sopenharmony_ci        }
219cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Memory alloc failed");
220cc290419Sopenharmony_ci        callbackFinish(callerContext, true, "Memory alloc failed");
221cc290419Sopenharmony_ci        return -1;
222cc290419Sopenharmony_ci    }
223cc290419Sopenharmony_ci    contextIO->bufIO = buf;
224cc290419Sopenharmony_ci    contextIO->thisClass = this;
225cc290419Sopenharmony_ci    ++refIO;
226cc290419Sopenharmony_ci    std::thread([contextIO, readMax]() {
227cc290419Sopenharmony_ci        HdcFileDescriptor::FileIOOnThread(contextIO, readMax);
228cc290419Sopenharmony_ci    }).detach();
229cc290419Sopenharmony_ci    return 0;
230cc290419Sopenharmony_ci}
231cc290419Sopenharmony_ci
232cc290419Sopenharmony_cibool HdcFileDescriptor::StartWorkOnThread()
233cc290419Sopenharmony_ci{
234cc290419Sopenharmony_ci    if (LoopReadOnThread() < 0) {
235cc290419Sopenharmony_ci        return false;
236cc290419Sopenharmony_ci    }
237cc290419Sopenharmony_ci    return true;
238cc290419Sopenharmony_ci}
239cc290419Sopenharmony_ci
240cc290419Sopenharmony_ciint HdcFileDescriptor::Write(uint8_t *data, int size)
241cc290419Sopenharmony_ci{
242cc290419Sopenharmony_ci    if (size > static_cast<int>(HDC_BUF_MAX_BYTES - 1)) {
243cc290419Sopenharmony_ci        size = static_cast<int>(HDC_BUF_MAX_BYTES - 1);
244cc290419Sopenharmony_ci    }
245cc290419Sopenharmony_ci    if (size <= 0) {
246cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "Write failed, size:%d", size);
247cc290419Sopenharmony_ci        return -1;
248cc290419Sopenharmony_ci    }
249cc290419Sopenharmony_ci    auto buf = new(std::nothrow) uint8_t[size];
250cc290419Sopenharmony_ci    if (!buf) {
251cc290419Sopenharmony_ci        return -1;
252cc290419Sopenharmony_ci    }
253cc290419Sopenharmony_ci    if (memcpy_s(buf, size, data, size) != EOK) {
254cc290419Sopenharmony_ci        delete[] buf;
255cc290419Sopenharmony_ci        return -1;
256cc290419Sopenharmony_ci    }
257cc290419Sopenharmony_ci    return WriteWithMem(buf, size);
258cc290419Sopenharmony_ci}
259cc290419Sopenharmony_ci
260cc290419Sopenharmony_ci// Data's memory must be Malloc, and the callback FREE after this function is completed
261cc290419Sopenharmony_ciint HdcFileDescriptor::WriteWithMem(uint8_t *data, int size)
262cc290419Sopenharmony_ci{
263cc290419Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INIF
264cc290419Sopenharmony_ci    mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
265cc290419Sopenharmony_ci    mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
266cc290419Sopenharmony_ci#endif
267cc290419Sopenharmony_ci    auto contextIO = new(std::nothrow) CtxFileIO();
268cc290419Sopenharmony_ci    if (!contextIO) {
269cc290419Sopenharmony_ci        delete[] data;
270cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Memory alloc failed");
271cc290419Sopenharmony_ci        callbackFinish(callerContext, true, "Memory alloc failed");
272cc290419Sopenharmony_ci        return -1;
273cc290419Sopenharmony_ci    }
274cc290419Sopenharmony_ci    contextIO->bufIO = data;
275cc290419Sopenharmony_ci    contextIO->size = static_cast<size_t>(size);
276cc290419Sopenharmony_ci    contextIO->thisClass = this;
277cc290419Sopenharmony_ci    PushWrite(contextIO);
278cc290419Sopenharmony_ci    NotifyWrite();
279cc290419Sopenharmony_ci    return size;
280cc290419Sopenharmony_ci}
281cc290419Sopenharmony_ci
282cc290419Sopenharmony_civoid HdcFileDescriptor::IOWriteThread(void *object)
283cc290419Sopenharmony_ci{
284cc290419Sopenharmony_ci    HdcFileDescriptor *hfd = reinterpret_cast<HdcFileDescriptor *>(object);
285cc290419Sopenharmony_ci    while (hfd->workContinue) {
286cc290419Sopenharmony_ci        hfd->HandleWrite();
287cc290419Sopenharmony_ci        hfd->WaitWrite();
288cc290419Sopenharmony_ci    }
289cc290419Sopenharmony_ci}
290cc290419Sopenharmony_ci
291cc290419Sopenharmony_civoid HdcFileDescriptor::PushWrite(CtxFileIO *cfio)
292cc290419Sopenharmony_ci{
293cc290419Sopenharmony_ci    std::unique_lock<std::mutex> lock(writeMutex);
294cc290419Sopenharmony_ci    writeQueue.push(cfio);
295cc290419Sopenharmony_ci}
296cc290419Sopenharmony_ci
297cc290419Sopenharmony_ciCtxFileIO *HdcFileDescriptor::PopWrite()
298cc290419Sopenharmony_ci{
299cc290419Sopenharmony_ci    std::unique_lock<std::mutex> lock(writeMutex);
300cc290419Sopenharmony_ci    CtxFileIO *cfio = nullptr;
301cc290419Sopenharmony_ci    if (!writeQueue.empty()) {
302cc290419Sopenharmony_ci        cfio = writeQueue.front();
303cc290419Sopenharmony_ci        writeQueue.pop();
304cc290419Sopenharmony_ci    }
305cc290419Sopenharmony_ci    return cfio;
306cc290419Sopenharmony_ci}
307cc290419Sopenharmony_ci
308cc290419Sopenharmony_civoid HdcFileDescriptor::NotifyWrite()
309cc290419Sopenharmony_ci{
310cc290419Sopenharmony_ci    writeCond.notify_one();
311cc290419Sopenharmony_ci}
312cc290419Sopenharmony_ci
313cc290419Sopenharmony_civoid HdcFileDescriptor::WaitWrite()
314cc290419Sopenharmony_ci{
315cc290419Sopenharmony_ci    std::unique_lock<std::mutex> lock(writeMutex);
316cc290419Sopenharmony_ci    writeCond.wait_for(lock, std::chrono::seconds(WAIT_SECONDS), [&]() {
317cc290419Sopenharmony_ci        return !writeQueue.empty() || !workContinue;
318cc290419Sopenharmony_ci    });
319cc290419Sopenharmony_ci}
320cc290419Sopenharmony_ci
321cc290419Sopenharmony_civoid HdcFileDescriptor::HandleWrite()
322cc290419Sopenharmony_ci{
323cc290419Sopenharmony_ci    CtxFileIO *cfio = nullptr;
324cc290419Sopenharmony_ci    while ((cfio = PopWrite()) != nullptr) {
325cc290419Sopenharmony_ci        CtxFileIOWrite(cfio);
326cc290419Sopenharmony_ci        delete cfio;
327cc290419Sopenharmony_ci    }
328cc290419Sopenharmony_ci}
329cc290419Sopenharmony_ci
330cc290419Sopenharmony_civoid HdcFileDescriptor::CtxFileIOWrite(CtxFileIO *cfio)
331cc290419Sopenharmony_ci{
332cc290419Sopenharmony_ci    std::unique_lock<std::mutex> lock(writeMutex);
333cc290419Sopenharmony_ci    uint8_t *buf = cfio->bufIO;
334cc290419Sopenharmony_ci    uint8_t *data = buf;
335cc290419Sopenharmony_ci    size_t cnt = cfio->size;
336cc290419Sopenharmony_ci    constexpr int intrmax = 1000;
337cc290419Sopenharmony_ci    int intrcnt = 0;
338cc290419Sopenharmony_ci    while (cnt > 0) {
339cc290419Sopenharmony_ci        ssize_t rc = write(fdIO, data, cnt);
340cc290419Sopenharmony_ci        if (rc < 0) {
341cc290419Sopenharmony_ci            if (errno == EINTR || errno == EAGAIN) {
342cc290419Sopenharmony_ci                if (++intrcnt > intrmax) {
343cc290419Sopenharmony_ci                    WRITE_LOG(LOG_WARN, "CtxFileIOWrite fdIO:%d interrupt errno:%d", fdIO, errno);
344cc290419Sopenharmony_ci                    intrcnt = 0;
345cc290419Sopenharmony_ci                }
346cc290419Sopenharmony_ci                continue;
347cc290419Sopenharmony_ci            } else {
348cc290419Sopenharmony_ci                WRITE_LOG(LOG_FATAL, "CtxFileIOWrite fdIO:%d rc:%d error:%d", fdIO, rc, errno);
349cc290419Sopenharmony_ci                break;
350cc290419Sopenharmony_ci            }
351cc290419Sopenharmony_ci        }
352cc290419Sopenharmony_ci        data += rc;
353cc290419Sopenharmony_ci        cnt -= static_cast<size_t>(rc);
354cc290419Sopenharmony_ci    }
355cc290419Sopenharmony_ci    delete[] buf;
356cc290419Sopenharmony_ci}
357cc290419Sopenharmony_ci}  // namespace Hdc
358