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
Init()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
Reset()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
GetNtfyObj()56 KqueuerObj* IMtAction::GetNtfyObj() {
57 IMtConnection* conn = GetIConnection();
58 if (conn) {
59 return conn->GetNtfyObj();
60 } else {
61 return NULL;
62 }
63 };
64
InitConnEnv()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
DoEncode()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
DoInput()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
DoProcess()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
DoError()203 int IMtAction::DoError()
204 {
205 return this->HandleError((int)_errno, _msg);
206 }
207
IMtAction()208 IMtAction::IMtAction()
209 {
210 Init();
211 }
212
~IMtAction()213 IMtAction::~IMtAction()
214 {
215 Reset();
216 Init();
217 }
218
219