1 2 /** 3 * Tencent is pleased to support the open source community by making MSEC available. 4 * 5 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. 6 * 7 * Licensed under the GNU General Public License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. You may 9 * obtain a copy of the License at 10 * 11 * https://opensource.org/licenses/GPL-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software distributed under the 14 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 * either express or implied. See the License for the specific language governing permissions 16 * and limitations under the License. 17 */ 18 19 20 #include "micro_thread.h" 21 #include "mt_notify.h" 22 #include "mt_connection.h" 23 #include "mt_session.h" 24 #include "mt_action.h" 25 26 using namespace std; 27 using namespace NS_MICRO_THREAD; 28 29 void IMtAction::Init() 30 { 31 _flag = MULTI_FLAG_UNDEF; 32 _proto = MT_UDP; 33 _conn_type = CONN_TYPE_SHORT; 34 _errno = ERR_NONE; 35 _time_cost = 0; 36 _buff_size = 0; 37 _msg = NULL; 38 _conn = NULL; 39 _ntfy_name = 0; 40 memset(&_addr, 0, sizeof(_addr)); 41 } 42 43 void IMtAction::Reset() 44 { 45 bool force_free = false; 46 if (_errno != ERR_NONE) { 47 force_free = true; 48 } 49 50 if (_conn) { 51 ConnectionMgr::Instance()->FreeConnection(_conn, force_free); 52 _conn = NULL; 53 } 54 } 55 56 KqueuerObj* IMtAction::GetNtfyObj() { 57 IMtConnection* conn = GetIConnection(); 58 if (conn) { 59 return conn->GetNtfyObj(); 60 } else { 61 return NULL; 62 } 63 }; 64 65 int IMtAction::InitConnEnv() 66 { 67 MtFrame* mtframe = MtFrame::Instance(); 68 ConnectionMgr* connmgr = ConnectionMgr::Instance(); 69 MsgBuffPool* msgmgr = MsgBuffPool::Instance(); 70 NtfyObjMgr* ntfymgr = NtfyObjMgr::Instance(); 71 SessionMgr* sessionmgr = SessionMgr::Instance(); 72 73 if (_conn != NULL) { 74 MTLOG_ERROR("Action init failed, maybe action reused in actionlist, check it!!"); 75 return -100; 76 } 77 78 CONN_OBJ_TYPE conn_obj_type = OBJ_CONN_UNDEF; 79 NTFY_OBJ_TYPE ntfy_obj_type = NTFY_OBJ_UNDEF; 80 81 MULTI_PROTO proto = this->GetProtoType(); 82 MULTI_CONNECT type = this->GetConnType(); 83 if ((MT_UDP == proto) && (CONN_TYPE_SESSION == type)) // UDP session 84 { 85 conn_obj_type = OBJ_UDP_SESSION; 86 ntfy_obj_type = NTFY_OBJ_SESSION; 87 } 88 else if (MT_UDP == proto) // UDP 89 { 90 conn_obj_type = OBJ_SHORT_CONN; 91 ntfy_obj_type = NTFY_OBJ_THREAD; 92 } 93 else // TCP 94 { 95 conn_obj_type = OBJ_TCP_KEEP; 96 ntfy_obj_type = NTFY_OBJ_THREAD; 97 } 98 99 _conn = connmgr->GetConnection(conn_obj_type, this->GetMsgDstAddr()); 100 if (!_conn) { 101 MTLOG_ERROR("Get conn failed, type: %d", conn_obj_type); 102 return -1; 103 } 104 _conn->SetIMtActon(this); 105 106 int max_len = this->GetMsgBuffSize(); 107 MtMsgBuf* msg_buff = msgmgr->GetMsgBuf(max_len); 108 if (!msg_buff) { 109 MTLOG_ERROR("Maybe no memory, buffsize: %d, get failed", max_len); 110 return -2; 111 } 112 msg_buff->SetBuffType(BUFF_SEND); 113 _conn->SetMtMsgBuff(msg_buff); 114 115 KqueuerObj* ntfy_obj = ntfymgr->GetNtfyObj(ntfy_obj_type, _ntfy_name); 116 if (!ntfy_obj) { 117 MTLOG_ERROR("Maybe no memory, ntfy type: %d, get failed", ntfy_obj_type); 118 return -3; 119 } 120 _conn->SetNtfyObj(ntfy_obj); 121 122 MicroThread* thread = mtframe->GetActiveThread(); 123 ntfy_obj->SetOwnerThread(thread); 124 this->SetIMsgPtr((IMtMsg*)thread->GetThreadArgs()); 125 if (conn_obj_type == OBJ_UDP_SESSION) 126 { 127 this->SetOwnerThread(thread); 128 this->SetSessionConn(_conn); 129 this->SetSessionId(sessionmgr->GetSessionId()); 130 sessionmgr->InsertSession(this); 131 } 132 133 return 0; 134 } 135 136 int IMtAction::DoEncode() 137 { 138 MtMsgBuf* msg_buff = NULL; 139 if (_conn) { 140 msg_buff = _conn->GetMtMsgBuff(); 141 } 142 if (!_conn || !msg_buff) { 143 MTLOG_ERROR("conn(%p) or msgbuff(%p) null", _conn, msg_buff); 144 return -100; 145 } 146 147 int msg_len = msg_buff->GetMaxLen(); 148 int ret = this->HandleEncode(msg_buff->GetMsgBuff(), msg_len, _msg); 149 if (ret < 0) 150 { 151 MTLOG_DEBUG("handleecode failed, ret %d", ret); 152 return ret; 153 } 154 msg_buff->SetMsgLen(msg_len); 155 156 return 0; 157 } 158 159 int IMtAction::DoInput() 160 { 161 MtMsgBuf* msg_buff = NULL; 162 if (_conn) { 163 msg_buff = _conn->GetMtMsgBuff(); 164 } 165 if (!_conn || !msg_buff) { 166 MTLOG_ERROR("conn(%p) or msgbuff(%p) null", _conn, msg_buff); 167 return -100; 168 } 169 170 int msg_len = msg_buff->GetHaveRcvLen(); 171 int ret = this->HandleInput(msg_buff->GetMsgBuff(), msg_len, _msg); 172 if (ret < 0) 173 { 174 MTLOG_DEBUG("HandleInput failed, ret %d", ret); 175 return ret; 176 } 177 178 return ret; 179 } 180 181 int IMtAction::DoProcess() 182 { 183 MtMsgBuf* msg_buff = NULL; 184 if (_conn) { 185 msg_buff = _conn->GetMtMsgBuff(); 186 } 187 if (!_conn || !msg_buff) { 188 MTLOG_ERROR("conn(%p) or msgbuff(%p) null", _conn, msg_buff); 189 return -100; 190 } 191 192 int ret = this->HandleProcess(msg_buff->GetMsgBuff(), msg_buff->GetMsgLen(), _msg); 193 if (ret < 0) 194 { 195 MTLOG_DEBUG("handleprocess failed, ret %d", ret); 196 return ret; 197 } 198 199 return 0; 200 201 } 202 203 int IMtAction::DoError() 204 { 205 return this->HandleError((int)_errno, _msg); 206 } 207 208 IMtAction::IMtAction() 209 { 210 Init(); 211 } 212 213 IMtAction::~IMtAction() 214 { 215 Reset(); 216 Init(); 217 } 218 219