f-stack/app/micro_thread/mt_notify.h

569 lines
14 KiB
C
Raw Normal View History

2017-04-21 10:43:26 +00:00
/**
* Tencent is pleased to support the open source community by making MSEC available.
*
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the GNU General Public License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* https://opensource.org/licenses/GPL-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
/**
* @file mt_notify.h
* @info ΢<EFBFBD>߳<EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @time 20130926
**/
#ifndef __MT_NOTIFY_H__
#define __MT_NOTIFY_H__
#include <netinet/in.h>
#include <queue>
#include <map>
#include "mt_mbuf_pool.h"
namespace NS_MICRO_THREAD {
using std::queue;
using std::map;
class SessionProxy;
class TcpKeepConn;
/**
* @brief ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
enum NTFY_OBJ_TYPE
{
NTFY_OBJ_UNDEF = 0, ///< δ<><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
NTFY_OBJ_THREAD = 1, ///< <20><><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>, һ<><D2BB>fd<66><64>Ӧһ<D3A6><D2BB>thread
NTFY_OBJ_KEEPALIVE = 2, ///< TCP<43><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>notify<66><79><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> thread
NTFY_OBJ_SESSION = 3, ///< UDP<44><50>sessionģ<6E><C4A3>, <20><><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
};
/**
* @brief Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD><EFBFBD>
*/
enum MULTI_PROTO
{
MT_UNKNOWN = 0,
MT_UDP = 0x1, ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UDP
MT_TCP = 0x2 ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TCP
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sessionģ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
*/
typedef TAILQ_ENTRY(SessionProxy) NtfyEntry;
typedef TAILQ_HEAD(__NtfyList, SessionProxy) NtfyList;
class ISessionNtfy : public KqueuerObj
{
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ͬʱ<EFBFBD><EFBFBD>ȡsessionid<EFBFBD><EFBFBD>Ϣ
* @param pkg <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>
* @param session <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sessionid, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <=0 ʧ<EFBFBD><EFBFBD>, >0 ʵ<EFBFBD>ʱ<EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>
*/
virtual int GetSessionId(void* pkg, int len, int& session) { return 0;};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>
* @return fd<EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
virtual int CreateSocket(){return -1;};
/**
* @brief <EFBFBD>ر<EFBFBD>socket, ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>
*/
virtual void CloseSocket(){};
/**
* @brief <EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int InputNotify(){return 0;};
/**
* @brief <EFBFBD><EFBFBD>д<EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int OutputNotify(){return 0;};
/**
* @brief <EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>
* @return <EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD>ֵ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int HangupNotify(){return 0;};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
*/
virtual int KqueueCtlAdd(void* args){return 0;};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
*/
virtual int KqueueCtlDel(void* args){return 0;};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
ISessionNtfy(): KqueuerObj(0) {
_proto = MT_UDP;
_buff_size = 0;
_msg_buff = NULL;
TAILQ_INIT(&_write_list);
}
virtual ~ISessionNtfy() { };
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>proto<EFBFBD><EFBFBD>Ϣ
*/
void SetProtoType(MULTI_PROTO proto) {
_proto = proto;
};
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>proto<EFBFBD><EFBFBD>Ϣ
* @return proto type
*/
MULTI_PROTO GetProtoType() {
return _proto;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>buff<EFBFBD><EFBFBD>С, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>msgbuff<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0<EFBFBD>ɹ<EFBFBD>
*/
void SetMsgBuffSize(int buff_size) {
_buff_size = buff_size;
};
/**
* @brief <EFBFBD><EFBFBD>ȡԤ<EFBFBD>õ<EFBFBD>buff<EFBFBD><EFBFBD>С, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>65535
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣbuff<EFBFBD><EFBFBD><EFBFBD>󳤶<EFBFBD>
*/
int GetMsgBuffSize() {
return (_buff_size > 0) ? _buff_size : 65535;
}
/**
* @brief ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>״̬
*/
void InsertWriteWait(SessionProxy* proxy);
/**
* @brief ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>״̬
*/
void RemoveWriteWait(SessionProxy* proxy);
/**
* @brief <EFBFBD>۲<EFBFBD><EFBFBD><EFBFBD>ģʽ, ֪ͨд<EFBFBD>ȴ<EFBFBD><EFBFBD>߳<EFBFBD>
* @info UDP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨÿ<EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ִ<EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, TCP<EFBFBD><EFBFBD>Ҫ<EFBFBD>Ŷ<EFBFBD>д
*/
virtual void NotifyWriteWait(){};
protected:
MULTI_PROTO _proto; // Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UDP/TCP
int _buff_size; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
NtfyList _write_list; // <20><>д<EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
MtMsgBuf* _msg_buff; // <20><>ʱ<EFBFBD>հ<EFBFBD><D5B0><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD><EFBFBD>
};
/**
* @brief UDP<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sessionģ<EFBFBD>͵Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
* @info ҵ<EFBFBD><EFBFBD>session<EFBFBD><EFBFBD>Ҫ<EFBFBD>̳иýӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ʵ<EFBFBD>ֻ<EFBFBD>ȡGetSessionId<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @info <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ, <EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ض˿ڵ<EFBFBD>
*/
class UdpSessionNtfy : public ISessionNtfy
{
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ͬʱ<EFBFBD><EFBFBD>ȡsessionid<EFBFBD><EFBFBD>Ϣ, <EFBFBD>ɼ̳<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param pkg <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>
* @param session <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sessionid, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <=0 ʧ<EFBFBD><EFBFBD>, >0 ʵ<EFBFBD>ʱ<EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>
*/
virtual int GetSessionId(void* pkg, int len, int& session) { return 0;};
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
UdpSessionNtfy() : ISessionNtfy(){
ISessionNtfy::SetProtoType(MT_UDP);
_local_addr.sin_family = AF_INET;
_local_addr.sin_addr.s_addr = 0;
_local_addr.sin_port = 0;
}
virtual ~UdpSessionNtfy() { };
/**
* @brief <EFBFBD>۲<EFBFBD><EFBFBD><EFBFBD>ģʽ, ֪ͨд<EFBFBD>ȴ<EFBFBD><EFBFBD>߳<EFBFBD>
* @info UDP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨÿ<EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ִ<EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, TCP<EFBFBD><EFBFBD>Ҫ<EFBFBD>Ŷ<EFBFBD>д
*/
virtual void NotifyWriteWait();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>
* @return fd<EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
virtual int CreateSocket();
/**
* @brief <EFBFBD>ر<EFBFBD>socket, ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>
*/
virtual void CloseSocket();
/**
* @brief <EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int InputNotify();
/**
* @brief <EFBFBD><EFBFBD>д<EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int OutputNotify();
/**
* @brief <EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>
* @return <EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD>ֵ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int HangupNotify();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
*/
virtual int KqueueCtlAdd(void* args);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
*/
virtual int KqueueCtlDel(void* args);
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>udp<EFBFBD><EFBFBD><EFBFBD>صı<EFBFBD><EFBFBD><EFBFBD>bind<EFBFBD><EFBFBD>ַ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bind<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ, <EFBFBD><EFBFBD>ʱͣ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>ܱ<EFBFBD>֤ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψһport<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
*/
void SetLocalAddr(struct sockaddr_in* local_addr) {
memcpy(&_local_addr, local_addr, sizeof(_local_addr));
};
protected:
struct sockaddr_in _local_addr;
};
/**
* @brief UDPģʽsessionģ<EFBFBD>͵Ĵ<EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD>ijһ<EFBFBD><EFBFBD>session notify
* @info session proxy <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>epollע<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʱ<EFBFBD><EFBFBD>
*/
class SessionProxy : public KqueuerObj
{
public:
int _flag; ///< 0-<2D><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>, 1-<2D>ڵȴ<DAB5><C8B4><EFBFBD><EFBFBD><EFBFBD>
NtfyEntry _write_entry; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>еĹ<D0B5><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetRealNtfyObj(ISessionNtfy* obj) {
_real_ntfy = obj;
this->SetOsfd(obj->GetOsfd());
};
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
*/
ISessionNtfy* GetRealNtfyObj() {
return _real_ntfy;
};
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void Reset() {
_real_ntfy = NULL;
this->KqueuerObj::Reset();
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
*/
virtual int KqueueCtlAdd(void* args) {
if (!_real_ntfy) {
return -1;
}
int events = this->GetEvents();
if (!(events & KQ_EVENT_WRITE)) {
return 0;
}
if (_real_ntfy->KqueueCtlAdd(args) < 0) {
return -2;
}
_real_ntfy->InsertWriteWait(this);
return 0;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
*/
virtual int KqueueCtlDel(void* args) {
if (!_real_ntfy) {
return -1;
}
int events = this->GetEvents();
if (!(events & KQ_EVENT_WRITE)) {
return 0;
}
_real_ntfy->RemoveWriteWait(this);
return _real_ntfy->KqueueCtlDel(args);
};
private:
ISessionNtfy* _real_ntfy; // ʵ<>ʵ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD>
};
/**
* @brief TCPģʽ<EFBFBD><EFBFBD>keepalive֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀɶ<EFBFBD><EFBFBD>¼<EFBFBD>, ȷ<EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>Զ˹ر<EFBFBD>
*/
class TcpKeepNtfy: public KqueuerObj
{
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
TcpKeepNtfy() : _keep_conn(NULL){};
/**
* @brief <EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int InputNotify();
/**
* @brief <EFBFBD><EFBFBD>д<EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int OutputNotify();
/**
* @brief <EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>
* @return <EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD>ֵ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int HangupNotify();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetKeepNtfyObj(TcpKeepConn* obj) {
_keep_conn = obj;
};
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
*/
TcpKeepConn* GetKeepNtfyObj() {
return _keep_conn;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹرղ<EFBFBD><EFBFBD><EFBFBD>
*/
void KeepaliveClose();
private:
TcpKeepConn* _keep_conn; // ʵ<>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
/**
* @brief <EFBFBD><EFBFBD>̬<EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>new/delete<EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
template<typename ValueType>
class CPtrPool
{
public:
typedef typename std::queue<ValueType*> PtrQueue; ///< <20>ڴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public:
/**
* @brief <EFBFBD><EFBFBD>̬<EFBFBD>ڴ<EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param max <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>, Ĭ<EFBFBD><EFBFBD>500
*/
explicit CPtrPool(int max = 500) : _max_free(max), _total(0){};
/**
* @brief <EFBFBD><EFBFBD>̬<EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>freelist
*/
~CPtrPool() {
ValueType* ptr = NULL;
while (!_ptr_list.empty()) {
ptr = _ptr_list.front();
_ptr_list.pop();
delete ptr;
}
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ָ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>ȴӻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ, <EFBFBD>޿<EFBFBD><EFBFBD>п<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬ new <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ָ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>, <EFBFBD>ձ<EFBFBD>ʾ<EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
*/
ValueType* AllocPtr() {
ValueType* ptr = NULL;
if (!_ptr_list.empty()) {
ptr = _ptr_list.front();
_ptr_list.pop();
} else {
ptr = new ValueType;
_total++;
}
return ptr;
};
/**
* @brief <EFBFBD>ͷ<EFBFBD><EFBFBD>ڴ<EFBFBD>ָ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD><EFBFBD>
*/
void FreePtr(ValueType* ptr) {
if ((int)_ptr_list.size() >= _max_free) {
delete ptr;
_total--;
} else {
_ptr_list.push(ptr);
}
};
protected:
PtrQueue _ptr_list; ///< <20><><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>
int _max_free; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
int _total; ///< <20><><EFBFBD><EFBFBD>new<65>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3>
};
/**
* @brief ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class NtfyObjMgr
{
public:
typedef std::map<int, ISessionNtfy*> SessionMap;
typedef CPtrPool<KqueuerObj> NtfyThreadQueue;
typedef CPtrPool<SessionProxy> NtfySessionQueue;
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ȫ<EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
* @return ȫ<EFBFBD>־<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
*/
static NtfyObjMgr* Instance (void);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
*/
static void Destroy(void);
/**
* @brief ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>session<EFBFBD><EFBFBD>Ϣ
* @param session_name <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵı<EFBFBD>ʶ, ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>session<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD>ʽ
* @param session <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>
*/
int RegisterSession(int session_name, ISessionNtfy* session);
/**
* @brief <EFBFBD><EFBFBD>ȡע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>session<EFBFBD><EFBFBD>Ϣ
* @param session_name <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵı<EFBFBD>ʶ, ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>session<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD>ʽ
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>, ʧ<EFBFBD><EFBFBD>ΪNULL
*/
ISessionNtfy* GetNameSession(int session_name);
/**
* @brief <EFBFBD><EFBFBD>ȡͨ<EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>session֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param type <EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>߳<EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>UDP/TCP SESSION֪ͨ<EFBFBD><EFBFBD>
* @param session_name proxyģ<EFBFBD><EFBFBD>,һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡsession<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>, ʧ<EFBFBD><EFBFBD>ΪNULL
*/
KqueuerObj* GetNtfyObj(int type, int session_name = 0);
/**
* @brief <EFBFBD>ͷ<EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param obj ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void FreeNtfyObj(KqueuerObj* obj);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
~NtfyObjMgr();
private:
/**
* @brief <EFBFBD><EFBFBD>Ϣbuff<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
NtfyObjMgr();
static NtfyObjMgr * _instance; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SessionMap _session_map; ///< ȫ<>ֵ<EFBFBD>ע<EFBFBD><D7A2>session<6F><6E><EFBFBD><EFBFBD>
NtfyThreadQueue _fd_ntfy_pool; ///< fd֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>
NtfySessionQueue _udp_proxy_pool; ///< fd֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>
};
}
#endif