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_mbuf_pool.h 22 * @info �߳�ͬ����Ϣbuf�� 23 **/ 24 25 #ifndef __MT_MBUF_POOL_H__ 26 #define __MT_MBUF_POOL_H__ 27 28 #include <netinet/in.h> 29 #include <queue> 30 #include "hash_list.h" 31 32 namespace NS_MICRO_THREAD { 33 34 using std::queue; 35 36 enum BUFF_TYPE 37 { 38 BUFF_UNDEF = 0, ///< δ�������� 39 BUFF_RECV = 1, ///< ����buff 40 BUFF_SEND = 2, ///< ����buff 41 }; 42 43 /** 44 * @brief ��ϢͶ�ݵ�buffer�� 45 */ 46 typedef TAILQ_ENTRY(MtMsgBuf) MsgBufLink; 47 typedef TAILQ_HEAD(__MtbuffTailq, MtMsgBuf) MsgBufQueue; 48 class MtMsgBuf 49 { 50 private: 51 int _max_len; // ���Ŀռ䳤�� 52 int _msg_len; // ʵ�ʵ���Ϣ���� 53 int _buf_type; // buff�Ƿ��ͻ��ǽ��� 54 int _recv_len; // �ѽ��յ���Ϣ���� 55 int _send_len; // �ѷ��͵���Ϣ���� 56 void* _msg_buff; // buffer ʵ��ͷָ�� 57 58 public: 59 60 MsgBufLink _entry; 61 62 /** 63 * @brief ���캯��, ָ�����buff���� 64 */ 65 MtMsgBuf(int max_len) { 66 _max_len = max_len; 67 _msg_len = 0; 68 _buf_type = BUFF_UNDEF; 69 _recv_len = 0; 70 _send_len = 0; 71 _msg_buff = malloc(max_len); 72 }; 73 74 ~MtMsgBuf() { 75 if (_msg_buff) { 76 free(_msg_buff); 77 _msg_buff = NULL; 78 } 79 }; 80 81 /** 82 * @brief ��Ϣ���͵��������ȡ 83 */ 84 void SetBuffType(BUFF_TYPE type) { 85 _buf_type = (int)type; 86 }; 87 BUFF_TYPE GetBuffType() { 88 return (BUFF_TYPE)_buf_type; 89 }; 90 91 /** 92 * @brief ���ýӿ�, �ָ���ʼ״̬ 93 */ 94 void Reset() { 95 _msg_len = 0; 96 _recv_len = 0; 97 _send_len = 0; 98 _buf_type = BUFF_UNDEF; 99 }; 100 101 /** 102 * @brief ��Ϣ���ȵ��������ȡ 103 */ 104 void SetMsgLen(int msg_len) { 105 _msg_len = msg_len; 106 }; 107 int GetMsgLen() { 108 return _msg_len; 109 }; 110 111 /** 112 * @brief �����bufferָ���ȡ 113 */ 114 int GetMaxLen() { 115 return _max_len; 116 }; 117 void* GetMsgBuff() { 118 return _msg_buff; 119 }; 120 121 /** 122 * @brief �м�״̬��ȡ����� 123 */ 124 int GetHaveSndLen() { 125 return _send_len; 126 }; 127 void SetHaveSndLen(int snd_len) { 128 _send_len = snd_len; 129 }; 130 131 /** 132 * @brief �м�״̬��ȡ����� 133 */ 134 int GetHaveRcvLen() { 135 return _recv_len; 136 }; 137 void SetHaveRcvLen(int rcv_len) { 138 _recv_len = rcv_len; 139 }; 140 }; 141 142 /** 143 * @brief ָ����С��buffer, �����ӳ��ɿ��ж��� 144 */ 145 class MsgBufMap : public HashKey 146 { 147 public: 148 149 /** 150 * @brief ��Ϣbuff����Ĺ��� 151 * @param buff_size ��mapԪ���ϵ�����buff, �����buff�ռ��Сֵ 152 * @param max_free �ö��й���Ԫ��, ��ֵ�free��Ŀ 153 */ 154 MsgBufMap(int buff_size, int max_free) { 155 _max_buf_size = buff_size; 156 _max_free = max_free; 157 this->SetDataPtr(this); 158 _queue_num = 0; 159 TAILQ_INIT(&_msg_queue); 160 }; 161 162 /** 163 * @brief ��Ϣbuff����Ĺ���, ����, ������key��Ϣ 164 * @param buff_size ��mapԪ���ϵ�����buff, �����buff�ռ��Сֵ 165 */ 166 explicit MsgBufMap(int buff_size) { 167 _max_buf_size = buff_size; 168 TAILQ_INIT(&_msg_queue); 169 }; 170 171 /** 172 * @brief ��Ϣbuff������������� 173 */ 174 ~MsgBufMap() { 175 MtMsgBuf* ptr = NULL; 176 MtMsgBuf* tmp = NULL; 177 TAILQ_FOREACH_SAFE(ptr, &_msg_queue, _entry, tmp) 178 { 179 TAILQ_REMOVE(&_msg_queue, ptr, _entry); 180 delete ptr; 181 _queue_num--; 182 } 183 184 TAILQ_INIT(&_msg_queue); 185 }; 186 187 /** 188 * @brief ��ȡ��ϢbuffԪ�� 189 * @return msgbufָ��, ʧ��ΪNULL 190 */ 191 MtMsgBuf* GetMsgBuf(){ 192 MtMsgBuf* ptr = NULL; 193 if (!TAILQ_EMPTY(&_msg_queue)) { 194 ptr = TAILQ_FIRST(&_msg_queue); 195 TAILQ_REMOVE(&_msg_queue, ptr, _entry); 196 _queue_num--; 197 } else { 198 ptr = new MtMsgBuf(_max_buf_size); 199 } 200 201 return ptr; 202 }; 203 204 /** 205 * @brief �ͷ���ϢbuffԪ�� 206 * @param msgbufָ�� 207 */ 208 void FreeMsgBuf(MtMsgBuf* ptr){ 209 if (_queue_num >= _max_free) { 210 delete ptr; 211 } else { 212 ptr->Reset(); 213 TAILQ_INSERT_TAIL(&_msg_queue, ptr, _entry); 214 _queue_num++; 215 } 216 }; 217 218 /** 219 * @brief �ڵ�Ԫ�ص�hash�㷨, ��ȡkey��hashֵ 220 * @return �ڵ�Ԫ�ص�hashֵ 221 */ 222 virtual uint32_t HashValue(){ 223 return _max_buf_size; 224 }; 225 226 /** 227 * @brief �ڵ�Ԫ�ص�cmp����, ͬһͰID��, ��key�Ƚ� 228 * @return �ڵ�Ԫ�ص�hashֵ 229 */ 230 virtual int HashCmp(HashKey* rhs){ 231 return this->_max_buf_size - (int)rhs->HashValue(); 232 }; 233 234 private: 235 int _max_free; ///< �����б������� 236 int _max_buf_size; ///< ����������buffsize 237 int _queue_num; ///< ���ж��и��� 238 MsgBufQueue _msg_queue; ///< ʵ�ʵĿ��ж��� 239 }; 240 241 242 /** 243 * @brief ȫ�ֵ�buffer�ض���, ͳһ���������buffer 244 */ 245 class MsgBuffPool 246 { 247 public: 248 249 /** 250 * @brief ��Ϣbuff��ȫ�ֹ������ӿ� 251 * @return ȫ�־��ָ�� 252 */ 253 static MsgBuffPool* Instance (void); 254 255 /** 256 * @brief ��Ϣ����ӿ� 257 */ 258 static void Destroy(void); 259 260 /** 261 * @brief ��Ϣbuff��ȫ�ֹ�������Ĭ�����Ŀ��и��� 262 * @param max_free �����б�����Ŀ, ��Ҫ�ڷ���Ԫ��ǰ���� 263 */ 264 void SetMaxFreeNum(int max_free) { 265 _max_free = max_free; 266 }; 267 268 /** 269 * @brief ��ȡ��ϢbuffԪ�� 270 * @return msgbufָ��, ʧ��ΪNULL 271 */ 272 MtMsgBuf* GetMsgBuf(int max_size); 273 274 /** 275 * @brief �ͷ���ϢbuffԪ�� 276 * @param msgbufָ�� 277 */ 278 void FreeMsgBuf(MtMsgBuf* msg_buf); 279 280 /** 281 * @brief ��Ϣbuff��ȫ������������ 282 */ 283 ~MsgBuffPool(); 284 285 private: 286 287 /** 288 * @brief ��Ϣbuff�Ĺ��캯�� 289 */ 290 explicit MsgBuffPool(int max_free = 300); 291 292 static MsgBuffPool * _instance; ///< �������� 293 int _max_free; ///< �����������Ŀ 294 HashList* _hash_map; ///< ��size hashmap ������ж��� 295 296 }; 297 298 299 300 } 301 302 #endif 303 304 305