houxiao
2017-01-11 97dbd476ee99f36286cd866b2208ceead3019b31
RtspFace/SensetimeFaceAPIWrapper/src/FaceDBPool.cpp
@@ -1,2 +1,166 @@
#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,);
   }
}