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