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 /** 21 * @file mt_action.cpp 22 * @info �߳�ACTION����ʵ�� 23 * @time 20130924 24 **/ 25 26 #include "micro_thread.h" 27 #include "mt_notify.h" 28 #include "mt_connection.h" 29 #include "mt_session.h" 30 #include "mt_action.h" 31 32 using namespace std; 33 using namespace NS_MICRO_THREAD; 34 35 36 /** 37 * @brief ��ʼitem״̬ 38 */ 39 void IMtAction::Init() 40 { 41 _flag = MULTI_FLAG_UNDEF; 42 _proto = MT_UDP; 43 _conn_type = CONN_TYPE_SHORT; 44 _errno = ERR_NONE; 45 _time_cost = 0; 46 _buff_size = 0; 47 _msg = NULL; 48 _conn = NULL; 49 _ntfy_name = 0; 50 memset(&_addr, 0, sizeof(_addr)); 51 } 52 53 /** 54 * @brief ������, ����item״̬ 55 */ 56 void IMtAction::Reset() 57 { 58 // ������, ����ɹ��Ÿ���, ����ǿ�ƹر� 59 bool force_free = false; 60 if (_errno != ERR_NONE) { 61 force_free = true; 62 } 63 64 if (_conn) { 65 ConnectionMgr::Instance()->FreeConnection(_conn, force_free); 66 _conn = NULL; 67 } 68 } 69 70 /** 71 * @brief ��ȡ���Ӷ���, ֪ͨ����, ��Ϣ���� 72 */ 73 KqueuerObj* IMtAction::GetNtfyObj() { 74 IMtConnection* conn = GetIConnection(); 75 if (conn) { 76 return conn->GetNtfyObj(); 77 } else { 78 return NULL; 79 } 80 }; 81 82 83 /** 84 * @brief ������ӻ�����ʼ�� 85 */ 86 int IMtAction::InitConnEnv() 87 { 88 MtFrame* mtframe = MtFrame::Instance(); 89 ConnectionMgr* connmgr = ConnectionMgr::Instance(); 90 MsgBuffPool* msgmgr = MsgBuffPool::Instance(); 91 NtfyObjMgr* ntfymgr = NtfyObjMgr::Instance(); 92 SessionMgr* sessionmgr = SessionMgr::Instance(); 93 94 if (_conn != NULL) { 95 MTLOG_ERROR("Action init failed, maybe action reused in actionlist, check it!!"); 96 return -100; 97 } 98 99 // 1. �����ȡconn��� 100 CONN_OBJ_TYPE conn_obj_type = OBJ_CONN_UNDEF; 101 NTFY_OBJ_TYPE ntfy_obj_type = NTFY_OBJ_UNDEF; 102 103 MULTI_PROTO proto = this->GetProtoType(); 104 MULTI_CONNECT type = this->GetConnType(); 105 if ((MT_UDP == proto) && (CONN_TYPE_SESSION == type)) // UDP sessionģʽ 106 { 107 conn_obj_type = OBJ_UDP_SESSION; 108 ntfy_obj_type = NTFY_OBJ_SESSION; 109 } 110 else if (MT_UDP == proto) // UDP ����ģʽ 111 { 112 conn_obj_type = OBJ_SHORT_CONN; 113 ntfy_obj_type = NTFY_OBJ_THREAD; 114 } 115 else // TCP ģʽ 116 { 117 conn_obj_type = OBJ_TCP_KEEP; 118 ntfy_obj_type = NTFY_OBJ_THREAD; 119 } 120 121 _conn = connmgr->GetConnection(conn_obj_type, this->GetMsgDstAddr()); 122 if (!_conn) { 123 MTLOG_ERROR("Get conn failed, type: %d", conn_obj_type); 124 return -1; 125 } 126 _conn->SetIMtActon(this); 127 128 // 2. ��ȡmsg buff��� 129 int max_len = this->GetMsgBuffSize(); 130 MtMsgBuf* msg_buff = msgmgr->GetMsgBuf(max_len); 131 if (!msg_buff) { 132 MTLOG_ERROR("Maybe no memory, buffsize: %d, get failed", max_len); 133 return -2; 134 } 135 msg_buff->SetBuffType(BUFF_SEND); 136 _conn->SetMtMsgBuff(msg_buff); 137 138 // 3. ��ȡ ntfy ������ 139 KqueuerObj* ntfy_obj = ntfymgr->GetNtfyObj(ntfy_obj_type, _ntfy_name); 140 if (!ntfy_obj) { 141 MTLOG_ERROR("Maybe no memory, ntfy type: %d, get failed", ntfy_obj_type); 142 return -3; 143 } 144 _conn->SetNtfyObj(ntfy_obj); 145 146 // 4. SESSIONģ��, ����session 147 MicroThread* thread = mtframe->GetActiveThread(); 148 ntfy_obj->SetOwnerThread(thread); 149 this->SetIMsgPtr((IMtMsg*)thread->GetThreadArgs()); 150 if (conn_obj_type == OBJ_UDP_SESSION) 151 { 152 this->SetOwnerThread(thread); 153 this->SetSessionConn(_conn); 154 this->SetSessionId(sessionmgr->GetSessionId()); 155 sessionmgr->InsertSession(this); 156 } 157 158 return 0; 159 } 160 161 162 /** 163 * @brief �����麯��, �ӿ���ʵ�ֲ��� 164 */ 165 int IMtAction::DoEncode() 166 { 167 MtMsgBuf* msg_buff = NULL; 168 if (_conn) { 169 msg_buff = _conn->GetMtMsgBuff(); 170 } 171 if (!_conn || !msg_buff) { 172 MTLOG_ERROR("conn(%p) or msgbuff(%p) null", _conn, msg_buff); 173 return -100; 174 } 175 176 int msg_len = msg_buff->GetMaxLen(); 177 int ret = this->HandleEncode(msg_buff->GetMsgBuff(), msg_len, _msg); 178 if (ret < 0) 179 { 180 MTLOG_DEBUG("handleecode failed, ret %d", ret); 181 return ret; 182 } 183 msg_buff->SetMsgLen(msg_len); 184 185 return 0; 186 } 187 188 /** 189 * @brief �����麯��, �ӿ���ʵ�ֲ��� 190 */ 191 int IMtAction::DoInput() 192 { 193 MtMsgBuf* msg_buff = NULL; 194 if (_conn) { 195 msg_buff = _conn->GetMtMsgBuff(); 196 } 197 if (!_conn || !msg_buff) { 198 MTLOG_ERROR("conn(%p) or msgbuff(%p) null", _conn, msg_buff); 199 return -100; 200 } 201 202 int msg_len = msg_buff->GetHaveRcvLen(); 203 int ret = this->HandleInput(msg_buff->GetMsgBuff(), msg_len, _msg); 204 if (ret < 0) 205 { 206 MTLOG_DEBUG("HandleInput failed, ret %d", ret); 207 return ret; 208 } 209 210 return ret; 211 } 212 213 214 int IMtAction::DoProcess() 215 { 216 MtMsgBuf* msg_buff = NULL; 217 if (_conn) { 218 msg_buff = _conn->GetMtMsgBuff(); 219 } 220 if (!_conn || !msg_buff) { 221 MTLOG_ERROR("conn(%p) or msgbuff(%p) null", _conn, msg_buff); 222 return -100; 223 } 224 225 int ret = this->HandleProcess(msg_buff->GetMsgBuff(), msg_buff->GetMsgLen(), _msg); 226 if (ret < 0) 227 { 228 MTLOG_DEBUG("handleprocess failed, ret %d", ret); 229 return ret; 230 } 231 232 return 0; 233 234 } 235 236 int IMtAction::DoError() 237 { 238 return this->HandleError((int)_errno, _msg); 239 } 240 241 242 243 /** 244 * @brief �������������� 245 */ 246 IMtAction::IMtAction() 247 { 248 Init(); 249 } 250 IMtAction::~IMtAction() 251 { 252 Reset(); 253 Init(); 254 } 255 256