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