#include "FaceDBPool.h"
|
#include "logger.h"
|
#include "faceAPI.h"
|
|
#include <pthread.h>
|
#include <map>
|
|
#define PLP_MUTEX_LOCK(mut,_ret) if (mut != nullptr) {\
|
int ret = pthread_mutex_lock((pthread_mutex_t*)mut); \
|
if(ret != 0) \
|
{ \
|
LOG_ERROR << "pthread_mutex_lock " << #mut << ": " << ret; \
|
return _ret; \
|
} \
|
}
|
|
#define PLP_MUTEX_UNLOCK(mut,_ret) if (mut != nullptr) {\
|
int ret = pthread_mutex_unlock((pthread_mutex_t*)mut); \
|
if(ret != 0) \
|
{ \
|
LOG_ERROR << "pthread_mutex_unlock " << #mut << ": " << ret; \
|
return _ret; \
|
} \
|
}
|
|
struct MutexLocker
|
{
|
pthread_mutex_t* mut;
|
MutexLocker(pthread_mutex_t* _mut) : mut(_mut)
|
{
|
PLP_MUTEX_LOCK(mut,);
|
}
|
~MutexLocker()
|
{
|
PLP_MUTEX_UNLOCK(mut,);
|
}
|
};
|
|
struct ThreadSafeFaceDB
|
{
|
int dbid;
|
pthread_mutex_t db_mutex;
|
faceAPI* api;
|
|
ThreadSafeFaceDB() : dbid(-1), db_mutex(), api(nullptr)
|
{
|
pthread_mutex_init(db_mutex, NULL);
|
}
|
|
~ThreadSafeFaceDB()
|
{
|
pthread_mutex_destroy(db_mutex);
|
}
|
};
|
|
typedef std::map<int, ThreadSafeFaceDB*> facedb_map_t;
|
|
FaceDBPool::FaceDBPool() :
|
pool_mutex(nullptr), face_db_map(nullptr)
|
{
|
pool_mutex = new pthread_mutex_t;
|
pthread_mutex_init((pthread_mutex_t*)pool_mutex, NULL);
|
|
face_db_map = new facedb_map_t();
|
}
|
|
FaceDBPool::~FaceDBPool()
|
{
|
facedb_map_t* _face_db_map = (facedb_map_t*)face_db_map;
|
for (facedb_map_t::iterator iter = _face_db_map->begin(); iter != _face_db_map->end(); ++iter)
|
{
|
iter->second.api->db_save();
|
delete iter->second.api;
|
delete iter->second;
|
}
|
|
_face_db_map.clear();
|
|
pthread_mutex_destroy((pthread_mutex_t*)pool_mutex);
|
delete (pthread_mutex_t*)pool_mutex;
|
pool_mutex = nullptr;
|
}
|
|
void FaceDBPool::manage(int dbid, faceAPI* db)
|
{
|
if (dbid < 0 || db == nullptr)
|
return;
|
|
MutexLocker _ml(pool_mutex);
|
|
facedb_map_t* _face_db_map = (facedb_map_t*)face_db_map;
|
|
if (_face_db_map.find(dbid) != _face_db_map.end())
|
return;
|
|
ThreadSafeFaceDB* tsfdb = new ThreadSafeFaceDB;
|
tsfdb.dbid = dbid;
|
tsfdb.api = db;
|
|
_face_db_map.insert(std::make_pair(dbid, tsfdb));
|
}
|
|
void FaceDBPool::unmanage(int dbid)
|
{
|
MutexLocker _ml(pool_mutex);
|
|
facedb_map_t* _face_db_map = (facedb_map_t*)face_db_map;
|
facedb_map_t::iterator iter = _face_db_map.find(dbid);
|
if (iter == _face_db_map.end())
|
return;
|
|
iter->second.api->db_save();
|
delete iter->second.api;
|
delete iter->second;
|
|
_face_db_map.erase(iter);
|
}
|
|
faceAPI* FaceDBPool::get_free(int dbid)
|
{
|
ThreadSafeFaceDB* tsfdb = nullptr;
|
{
|
//avoid dead lock
|
MutexLocker _ml(pool_mutex);
|
|
facedb_map_t* _face_db_map = (facedb_map_t*)face_db_map;
|
if (_face_db_map.empty())
|
return nullptr;
|
|
facedb_map_t::iterator iter = _face_db_map.find(dbid);
|
if (iter == _face_db_map.end())
|
return nullptr;
|
|
tsfdb = iter->second;
|
}
|
|
if (tsfdb != nullptr)
|
{
|
PLP_MUTEX_LOCK(tsfdb->db_mutex, nullptr);
|
return tsfdb->api;
|
}
|
}
|
|
void FaceDBPool::release(int dbid)
|
{
|
ThreadSafeFaceDB* tsfdb = nullptr;
|
{
|
//avoid dead lock
|
MutexLocker _ml(pool_mutex);
|
|
facedb_map_t* _face_db_map = (facedb_map_t*)face_db_map;
|
if (_face_db_map.empty())
|
return;
|
|
facedb_map_t::iterator iter = _face_db_map.find(dbid);
|
if (iter == _face_db_map.end())
|
return nullptr;
|
|
tsfdb = iter->second;
|
}
|
|
if (tsfdb != nullptr)
|
{
|
PLP_MUTEX_UNLOCK(tsfdb->db_mutex,);
|
}
|
}
|