mirror of
https://github.com/tribufu/sdk-cpp
synced 2025-06-16 19:54:18 +00:00
Add libhv and test http client
This commit is contained in:
183
vendor/libhv/include/hv/hobjectpool.h
vendored
Normal file
183
vendor/libhv/include/hv/hobjectpool.h
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
#ifndef HV_OBJECT_POOL_H_
|
||||
#define HV_OBJECT_POOL_H_
|
||||
|
||||
/*
|
||||
* @usage unittest/objectpool_test.cpp
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#define DEFAULT_OBJECT_POOL_INIT_NUM 0
|
||||
#define DEFAULT_OBJECT_POOL_MAX_NUM 4
|
||||
#define DEFAULT_OBJECT_POOL_TIMEOUT 3000 // ms
|
||||
|
||||
template<class T>
|
||||
class HObjectFactory {
|
||||
public:
|
||||
static T* create() {
|
||||
return new T;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class TFactory = HObjectFactory<T>>
|
||||
class HObjectPool {
|
||||
public:
|
||||
HObjectPool(
|
||||
int init_num = DEFAULT_OBJECT_POOL_INIT_NUM,
|
||||
int max_num = DEFAULT_OBJECT_POOL_MAX_NUM,
|
||||
int timeout = DEFAULT_OBJECT_POOL_TIMEOUT)
|
||||
: _max_num(max_num)
|
||||
, _timeout(timeout)
|
||||
{
|
||||
for (int i = 0; i < init_num; ++i) {
|
||||
T* p = TFactory::create();
|
||||
if (p) {
|
||||
objects_.push_back(std::shared_ptr<T>(p));
|
||||
}
|
||||
}
|
||||
_object_num = objects_.size();
|
||||
}
|
||||
|
||||
~HObjectPool() {}
|
||||
|
||||
int ObjectNum() { return _object_num; }
|
||||
int IdleNum() { return objects_.size(); }
|
||||
int BorrowNum() { return ObjectNum() - IdleNum(); }
|
||||
|
||||
std::shared_ptr<T> TryBorrow() {
|
||||
std::shared_ptr<T> pObj = NULL;
|
||||
std::lock_guard<std::mutex> locker(mutex_);
|
||||
if (!objects_.empty()) {
|
||||
pObj = objects_.front();
|
||||
objects_.pop_front();
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
std::shared_ptr<T> Borrow() {
|
||||
std::shared_ptr<T> pObj = TryBorrow();
|
||||
if (pObj) {
|
||||
return pObj;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> locker(mutex_);
|
||||
if (_object_num < _max_num) {
|
||||
++_object_num;
|
||||
// NOTE: unlock to avoid TFactory::create block
|
||||
mutex_.unlock();
|
||||
T* p = TFactory::create();
|
||||
mutex_.lock();
|
||||
if (!p) --_object_num;
|
||||
return std::shared_ptr<T>(p);
|
||||
}
|
||||
|
||||
if (_timeout > 0) {
|
||||
std::cv_status status = cond_.wait_for(locker, std::chrono::milliseconds(_timeout));
|
||||
if (status == std::cv_status::timeout) {
|
||||
return NULL;
|
||||
}
|
||||
if (!objects_.empty()) {
|
||||
pObj = objects_.front();
|
||||
objects_.pop_front();
|
||||
return pObj;
|
||||
}
|
||||
else {
|
||||
// WARN: No idle object
|
||||
}
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
void Return(std::shared_ptr<T>& pObj) {
|
||||
if (!pObj) return;
|
||||
std::lock_guard<std::mutex> locker(mutex_);
|
||||
objects_.push_back(pObj);
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
bool Add(std::shared_ptr<T>& pObj) {
|
||||
std::lock_guard<std::mutex> locker(mutex_);
|
||||
if (_object_num >= _max_num) {
|
||||
return false;
|
||||
}
|
||||
objects_.push_back(pObj);
|
||||
++_object_num;
|
||||
cond_.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Remove(std::shared_ptr<T>& pObj) {
|
||||
std::lock_guard<std::mutex> locker(mutex_);
|
||||
auto iter = objects_.begin();
|
||||
while (iter != objects_.end()) {
|
||||
if (*iter == pObj) {
|
||||
iter = objects_.erase(iter);
|
||||
--_object_num;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
std::lock_guard<std::mutex> locker(mutex_);
|
||||
objects_.clear();
|
||||
_object_num = 0;
|
||||
}
|
||||
|
||||
int _object_num;
|
||||
int _max_num;
|
||||
int _timeout;
|
||||
private:
|
||||
std::list<std::shared_ptr<T>> objects_;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
};
|
||||
|
||||
template<class T, class TFactory = HObjectFactory<T>>
|
||||
class HPoolObject {
|
||||
public:
|
||||
typedef HObjectPool<T, TFactory> PoolType;
|
||||
|
||||
HPoolObject(PoolType& pool) : pool_(pool)
|
||||
{
|
||||
sptr_ = pool_.Borrow();
|
||||
}
|
||||
|
||||
~HPoolObject() {
|
||||
if (sptr_) {
|
||||
pool_.Return(sptr_);
|
||||
}
|
||||
}
|
||||
|
||||
HPoolObject(const HPoolObject<T>&) = delete;
|
||||
HPoolObject<T>& operator=(const HPoolObject<T>&) = delete;
|
||||
|
||||
T* get() {
|
||||
return sptr_.get();
|
||||
}
|
||||
|
||||
operator bool() {
|
||||
return sptr_.get() != NULL;
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return sptr_.get();
|
||||
}
|
||||
|
||||
T operator*() {
|
||||
return *sptr_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
PoolType& pool_;
|
||||
std::shared_ptr<T> sptr_;
|
||||
};
|
||||
|
||||
#endif // HV_OBJECT_POOL_H_
|
Reference in New Issue
Block a user