#include "FaceDBPool.h" #include "logger.h" #include "faceAPI.h" #include #include #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 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,); } }