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