xref: /f-stack/app/micro_thread/mt_mbuf_pool.cpp (revision 2aa28acd)
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.cpp
22  *  @time 20130924
23  **/
24 
25 #include "micro_thread.h"
26 #include "mt_mbuf_pool.h"
27 
28 using namespace std;
29 using namespace NS_MICRO_THREAD;
30 
31 MsgBuffPool* MsgBuffPool::_instance = NULL;
32 MsgBuffPool* MsgBuffPool::Instance (void)
33 {
34     if (NULL == _instance)
35     {
36         _instance = new MsgBuffPool;
37     }
38 
39     return _instance;
40 }
41 
42 void MsgBuffPool::Destroy()
43 {
44     if( _instance != NULL )
45     {
46         delete _instance;
47         _instance = NULL;
48     }
49 }
50 
51 MsgBuffPool::MsgBuffPool(int max_free)
52 {
53     _max_free = max_free;
54     _hash_map = new HashList(10000);
55 }
56 
57 MsgBuffPool::~MsgBuffPool()
58 {
59     if (!_hash_map) {
60         return;
61     }
62 
63     MsgBufMap* msg_map = NULL;
64     HashKey* hash_item = _hash_map->HashGetFirst();
65     while (hash_item)
66     {
67         _hash_map->HashRemove(hash_item);
68         msg_map = dynamic_cast<MsgBufMap*>(hash_item);
69         delete msg_map;
70 
71         hash_item = _hash_map->HashGetFirst();
72     }
73 
74     delete _hash_map;
75     _hash_map = NULL;
76 }
77 
78 MtMsgBuf* MsgBuffPool::GetMsgBuf(int max_size)
79 {
80     if (!_hash_map) {
81         MTLOG_ERROR("MsgBuffPoll not init! hash %p,", _hash_map);
82         return NULL;
83     }
84 
85     MsgBufMap* msg_map = NULL;
86     MsgBufMap msg_key(max_size);
87     HashKey* hash_item = _hash_map->HashFind(&msg_key);
88     if (hash_item) {
89         msg_map = (MsgBufMap*)hash_item->GetDataPtr();
90         if (msg_map) {
91             return msg_map->GetMsgBuf();
92         } else {
93             MTLOG_ERROR("Hash item: %p, msg_map: %p impossible, clean it", hash_item, msg_map);
94             _hash_map->HashRemove(hash_item);
95             delete hash_item;
96             return NULL;
97         }
98     } else {
99         msg_map = new MsgBufMap(max_size, _max_free);
100         if (!msg_map) {
101             MTLOG_ERROR("maybe no more memory, failed. size: %d", max_size);
102             return NULL;
103         }
104         _hash_map->HashInsert(msg_map);
105 
106         return msg_map->GetMsgBuf();
107     }
108 }
109 
110 void MsgBuffPool::FreeMsgBuf(MtMsgBuf* msg_buf)
111 {
112     if (!_hash_map || !msg_buf) {
113         MTLOG_ERROR("MsgBuffPoll not init or input error! hash %p, msg_buf %p", _hash_map, msg_buf);
114         delete msg_buf;
115         return;
116     }
117     msg_buf->Reset();
118 
119     MsgBufMap* msg_map = NULL;
120     MsgBufMap msg_key(msg_buf->GetMaxLen());
121     HashKey* hash_item = _hash_map->HashFind(&msg_key);
122     if (hash_item) {
123         msg_map = (MsgBufMap*)hash_item->GetDataPtr();
124     }
125     if (!hash_item || !msg_map) {
126         MTLOG_ERROR("MsgBuffPoll find no queue, maybe error: %d", msg_buf->GetMaxLen());
127         delete msg_buf;
128         return;
129     }
130     msg_map->FreeMsgBuf(msg_buf);
131 
132     return;
133 }
134 
135 
136