xref: /developtools/hdc/src/common/task.cpp (revision cc290419)
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#include "task.h"
16
17namespace Hdc {
18// -----------------------------------------------------------
19// notice!!! The constructor is called at the Child thread, so in addition to initialization, do not excess actions, if
20// destructor is required, please clean up in the subclasses.
21HdcTaskBase::HdcTaskBase(HTaskInfo hTaskInfo)
22{
23    taskInfo = hTaskInfo;
24    loopTask = hTaskInfo->runLoop;
25    clsSession = hTaskInfo->ownerSessionClass;
26    childReady = false;
27    singalStop = false;
28    refCount = 0;
29    if (taskInfo->masterSlave) {
30        SendToAnother(CMD_KERNEL_WAKEUP_SLAVETASK, nullptr, 0);
31    }
32    WRITE_LOG(LOG_DEBUG, "HdcTaskBase channelId:%u", taskInfo->channelId);
33}
34
35HdcTaskBase::~HdcTaskBase()
36{
37    WRITE_LOG(LOG_DEBUG, "~HdcTaskBase channelId:%u", taskInfo->channelId);
38}
39
40bool HdcTaskBase::ReadyForRelease()
41{
42    return refCount == 0;
43}
44
45// Only the Task work thread call is allowed to use only when Workfortask returns FALSE.
46void HdcTaskBase::TaskFinish()
47{
48    StartTraceScope("HdcTaskBase::TaskFinish");
49    uint8_t count = 1;
50    WRITE_LOG(LOG_DEBUG, "HdcTaskBase::TaskFinish notify begin channelId:%u", taskInfo->channelId);
51    SendToAnother(CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
52    WRITE_LOG(LOG_DEBUG, "HdcTaskBase::TaskFinish notify end channelId:%u", taskInfo->channelId);
53}
54
55bool HdcTaskBase::SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size)
56{
57    StartTraceScope("HdcTaskBase::SendToAnother");
58    if (singalStop) {
59        WRITE_LOG(LOG_FATAL, "TaskFinish singalStop channelId:%u command:%u", taskInfo->channelId, command);
60        return false;
61    }
62    if (taskInfo->channelTask) {
63        HdcChannelBase *channelBase = reinterpret_cast<HdcChannelBase *>(taskInfo->channelClass);
64        channelBase->SendWithCmd(taskInfo->channelId, command, bufPtr, size);
65        return true;
66    } else {
67        HdcSessionBase *sessionBase = reinterpret_cast<HdcSessionBase *>(taskInfo->ownerSessionClass);
68        if (Base::IsSessionDeleted(taskInfo->sessionId)) {
69            WRITE_LOG(LOG_FATAL, "SendToAnother session is deleted channelId:%u command:%u",
70                taskInfo->channelId, command);
71            return false;
72        }
73        return sessionBase->Send(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size) > 0;
74    }
75}
76
77void HdcTaskBase::LogMsg(MessageLevel level, const char *msg, ...)
78{
79    va_list vaArgs;
80    va_start(vaArgs, msg);
81    string log = Base::StringFormat(msg, vaArgs);
82    va_end(vaArgs);
83
84    if (taskInfo->channelTask) {
85        string logInfo = "";
86        switch (level) {
87            case MSG_FAIL:
88                logInfo = MESSAGE_FAIL;
89                break;
90            case MSG_INFO:
91                logInfo = MESSAGE_INFO;
92                break;
93            default:  // successful, not append extra info
94                break;
95        }
96
97        fprintf(stdout, "%s%s\n", logInfo.c_str(), log.c_str());
98        fflush(stdout);
99    } else {
100        HdcSessionBase *sessionBase = reinterpret_cast<HdcSessionBase *>(clsSession);
101        sessionBase->LogMsg(taskInfo->sessionId, taskInfo->channelId, level, log.c_str());
102    }
103}
104
105bool HdcTaskBase::ServerCommand(const uint16_t command, uint8_t *bufPtr, const int size)
106{
107    HdcSessionBase *hSession = (HdcSessionBase *)taskInfo->ownerSessionClass;
108    return hSession->ServerCommand(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size);
109}
110
111// cross thread
112int HdcTaskBase::ThreadCtrlCommunicate(const uint8_t *bufPtr, const int size)
113{
114    HdcSessionBase *sessionBase = (HdcSessionBase *)taskInfo->ownerSessionClass;
115    HSession hSession = sessionBase->AdminSession(OP_QUERY, taskInfo->sessionId, nullptr);
116    if (!hSession) {
117        WRITE_LOG(LOG_FATAL, "ThreadCtrlCommunicate hSession nullptr sessionId:%u", taskInfo->sessionId);
118        return -1;
119    }
120    int fd = hSession->ctrlFd[STREAM_WORK];
121    return Base::SendToPollFd(fd, bufPtr, size);
122}
123}
124