This commit is contained in:
biosvos
2026-08-07 17:38:18 +09:00
commit 873193a243
9613 changed files with 2755992 additions and 0 deletions
+470
View File
@@ -0,0 +1,470 @@
/***************************************************************************
Work Pool
-----------------------------------------
begin : 2011/10/27
copyright : (C) 2011 SolutionBox Inc.
author : Service 1 Team
email : svc1@solbox.com
version : 3.0.1
CopyRight(C) 2011 SolutionBox Inc. All Rights reserved.
Redistribution and use in source and binary forms, with or with out
modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/
#include "WorkPool.h"
#include "Validation.h"
#include "Logger.h"
#include "Util.h"
#include <unistd.h>
#include <errno.h>
#include <iostream>
#define DIFF_SPLIT_CNT 6 // diff file format split count
#define SLEEP_TIME 1000 //microsecond
#define _LOGMSG(level, msg) \
_LOG(level, "%s", msg.str().c_str());\
msg.str("");
CWorkPool *CWorkPool::m_inst = NULL;
// work
CWork::CWork()
: m_step(-5), m_exit(false), m_enablesync("0000")
{
m_nofi = NULL;
pthread_mutex_init(&m_workmutex, NULL);
pthread_cond_init(&m_workcond, NULL);
}
CWork::~CWork()
{
pthread_mutex_destroy(&m_workmutex);
pthread_cond_destroy(&m_workcond);
}
void* CWork::working(void * pdata)
{
ostringstream msg;
CWork* pObject = reinterpret_cast<CWork *>(pdata);
//pthread_detach( pthread_self() );
#ifdef _DEBUG
cout << "work::working start - " << pthread_self() << endl;
#endif // _DEBUG
while(pObject->m_exit == false)
{
pthread_mutex_lock(&pObject->m_workmutex);
pObject->m_step = -1;
int err = pthread_cond_wait(&pObject->m_workcond, &pObject->m_workmutex);
pObject->m_step = 0;
#ifdef _DEBUG
cerr << "work::working - signal : " << pthread_self() << "," << pObject->m_exit << endl;
#endif // _DEBUG
if ( err == 0 && pObject->m_exit == false)
{
pObject->m_step = 1;
short success = 0;
msg << "Valid Start : " << pObject->m_rundata;
_LOGMSG(LDBG, msg);
do
{
// add uri
pObject->m_step = 2;
if (CWorkPool::getInstance()->addworkuri(pObject->m_syncinfo.sync_master,
pObject->m_rundata,
pObject->m_workuri, true)
== false)
{
LOG(LERR, "Failed work uri map add [%s].", pObject->m_rundata.c_str());
success = -1;
break;
}
// validation
pObject->m_step = 3;
CValidation v(pObject->m_syncinfo, pObject->m_rundata);
if (v.CheckValidation() == false)
success = -2;
pObject->m_step = 4;
} while (false);
if(pObject->m_nofi)
{
pObject->m_step = 6;
#ifdef _DEBUG
cerr << "Work Thread Notify Call."<< endl;
#endif //_DEBUG
pObject->m_nofi(pObject->m_parm, success);
}
pObject->m_step = 7;
msg << "Valid End : " << pObject->m_rundata;
_LOGMSG(LDBG, msg);
if(pObject->m_workuri.size())
{
CWorkPool::getInstance()->delworkuri(pObject->m_workuri);
}
CWorkPool::getInstance()->ReleaseWork(pObject);
}
else
{
pObject->m_step = -3;
if(pObject->m_exit == false)
{
pObject->m_step = -4;
msg << "Work Thread Error.";
//LOGACERR(LCRT, msg);
LOG(LCRT, msg.str().c_str());
}
else
{
pObject->m_step = -5;
/* nothing -- signal exit */
}
}
pObject->m_step = -6;
pthread_mutex_unlock(&pObject->m_workmutex);
}
#ifdef _DEBUG
cerr << "work::working end - " << pthread_self() << endl;
#endif // _DEBUG
return NULL;
}
bool CWork::init()
{
int nRet = pthread_create(&m_thread, 0, CWork::working, this);
if( nRet )
{
cerr << "Thread create failed.: errno: " << errno << endl;
return false;
}
sleep(0);
return true;
}
void CWork::setexit(bool v)
{
m_exit = v;
pthread_mutex_lock(&m_workmutex);
pthread_cond_signal(&m_workcond);
pthread_mutex_unlock(&m_workmutex);
}
bool CWork::run(CSyncInfo info, string rundata, work_notifyfn nofi /* = NULL */, void * parm /* = NULL */)
{
m_syncinfo = info;
m_rundata = rundata;
m_parm = parm;
m_nofi = nofi;
ostringstream msg;
//msg << "Work Run : TranID(" <<m_master.m_tranid <<"=>" << m_slave.m_tranid <<
// "), UserSeq(" << m_master.m_userseq << "=>" << m_slave.m_userseq << ")" <<
// ", Sync Data - " << m_rundata;
//_LOGACOUT(LDBG, msg);
//spin lock
int64_t looptime = 0;
do
{
solusleep(SLEEP_TIME);
looptime += SLEEP_TIME;
if( looptime > (10 *1000*1000) )
{
msg << "Work Loop.... 10 sec over :" << m_rundata;
LOG(LNOT, "%s", msg.str().c_str());
break;
}
} while (m_step != -1);
pthread_cond_signal(&m_workcond);
return true;
}
// work pool
CWorkPool::CWorkPool()
{
pthread_mutex_init(&m_mutex, NULL);
pthread_mutex_init(&m_mutexuri, NULL);
pthread_mutex_init(&m_mutextry, NULL);
}
CWorkPool::~CWorkPool()
{
pthread_mutex_destroy(&m_mutex);
pthread_mutex_destroy(&m_mutexuri);
pthread_mutex_destroy(&m_mutextry);
}
CWorkPool* CWorkPool::getInstance()
{
if(CWorkPool::m_inst == NULL)
{
CWorkPool::m_inst = new CWorkPool();
}
return CWorkPool::m_inst;
}
void CWorkPool::release()
{
if( CWorkPool::m_inst != NULL)
{
m_inst->DestroyPool();
delete CWorkPool::m_inst;
CWorkPool::m_inst = NULL;
}
}
int CWorkPool::CreatePool( int poolcnt /* = 10 */ )
{
// pool
for(int i=0 ; i < poolcnt ; i++)
{
srand ( time(NULL) );
CWork * w = new CWork();
if( w->init() == false)
{
delete w;
break;
}
//m_pool.insert(make_pair(w, CWorkPool::NOTWORK));
m_pool.insert(pair<CWork *, short>(w, CWorkPool::NOTWORK));
}
if( m_pool.size() < static_cast<unsigned int>(poolcnt) )
{
DestroyPool();
return -1;
}
return 0;
}
int CWorkPool::DestroyPool()
{
map<CWork*, short>::iterator iter;
while(m_pool.size() > 0 )
//for( iter = m_pool.begin(); !m_pool.empty()&& iter != m_pool.end(); iter++ )
{
iter = m_pool.begin();
if(iter->second == CWorkPool::NOTWORK)
{
CWork *data = static_cast<CWork *>(iter->first);
data->setexit(true);
pthread_join(*data->getworkhandle(), NULL);
m_pool.erase(iter);
delete (CWork *)data;
}
//sleep(1);
}
//m_pool.clear();
return m_pool.size();
}
CWork* CWorkPool::GetWorkPool(int timeout)
{
CWork * r = NULL;
int64_t usetime = 0;
int64_t out = timeout * 1000 * 1000;
do
{
pthread_mutex_lock(&m_mutex);
map<CWork*, short>::iterator iter;
for( iter = m_pool.begin(); !m_pool.empty()&& iter != m_pool.end(); iter++ )
{
if(iter->second == CWorkPool::NOTWORK)
{
iter->second = CWorkPool::WORKING;
r = iter->first;
break;
}
}
if( r == NULL )
{
solusleep(SLEEP_TIME);
if( out > 0 )
{
usetime += SLEEP_TIME;
if( usetime > out)
{
ostringstream msg;
msg << "Get Work Pool Timeout.";
//LOGACERR(LERR, msg);
LOG(LERR, msg.str().c_str());
pthread_mutex_unlock(&m_mutex);
break;
}
}
}
pthread_mutex_unlock(&m_mutex);
} while (r == NULL);
return r;
}
void CWorkPool::ReleaseWork(CWork *w)
{
//pthread_mutex_lock(&m_mutex);
map<CWork*, short>::iterator iter = m_pool.find(w);
if( iter != m_pool.end() )
{
if(iter->second==CWorkPool::WORKING)
iter->second=CWorkPool::NOTWORK;
}
else
{
ostringstream msg;
msg << "unknown work pool.";
//LOGACERR(LWAR, msg);
LOG(LWAR, msg.str().c_str());
}
//pthread_mutex_unlock(&m_mutex);
}
void CWorkPool::printstatus(string prefixed)
{
int w = 0, n = 0;
map<CWork*, short>::iterator iter;
for( iter = m_pool.begin(); !m_pool.empty()&& iter != m_pool.end(); iter++ )
{
if(iter->second == CWorkPool::NOTWORK)
{
++n;
}
else
{
++w;
}
}
ostringstream msg;
if( prefixed.empty() == false )
msg << "[" << prefixed << "]";
msg << "Work Pool - " <<"total : " << m_pool.size() << "(" << w <<
"/" << n << ")";
//_LOGACOUT(LINF, msg);
_LOG(LINF, msg.str().c_str());
}
void CWorkPool::printstatusex(string prefixed)
{
ostringstream msg;
map<CWork*, short>::iterator iter;
for( iter = m_pool.begin(); !m_pool.empty()&& iter != m_pool.end(); iter++ )
{
if(iter->second == CWorkPool::NOTWORK)
{
msg << "Work Pool(NOTWORK) - " << iter->first->getrundata() << "," <<
iter->first->getsetp();
}
else
{
msg << "Work Pool(WORKING) - " << iter->first->getrundata() << "," <<
iter->first->getsetp();
}
if( prefixed.empty() == false )
msg << "[" << prefixed << "]";
//_LOGACOUT(LINF, msg);
_LOG(LINF, "%s", msg.str().c_str());
}
}
bool CWorkPool::addworkuri(string tranid, string uri, string &workuri,
bool sourcedata, int timeout)
{
bool r = true;
string key;
ostringstream msg;
if(sourcedata)
{
vector<string> strSplit;
StringSplit(uri, "|", strSplit, true);
if(strSplit.size() != DIFF_SPLIT_CNT)
{
pthread_mutex_unlock(&m_mutexuri);
msg << "addworkuri sync file string split caution : [" << uri << "]";
//LOGACERR(LERR, msg);
LOG(LERR, "%s", msg.str().c_str());
return false;
}
key = "/" + tranid + strSplit[0] + "|[Size=" + strSplit[2] + "]";
}
else
key = "/"+ tranid + uri;
int64_t out = 0, usetime = 0;
out = timeout * 1000 * 1000;
TRY_ADD_WORK_URI:
pthread_mutex_lock(&m_mutexuri);
workurimap::iterator find = m_workurimap.find(key);
if (find != m_workurimap.end())
{
pthread_mutex_unlock(&m_mutexuri);
msg << "Work uri duplication occurred and to add work uri try again." << key;
_LOGMSG(LDBG, msg);
// try
solusleep(SLEEP_TIME);
usetime += SLEEP_TIME;
if(timeout > 0 && usetime > out)
{
r = false;
msg << "Work adduri Timeout." << key;
//LOGACERR(LERR, msg);
LOG(LERR, "%s", msg.str().c_str());
pthread_mutex_unlock(&m_mutexuri);
return false;
}
goto TRY_ADD_WORK_URI;
}
else
{
// add
workuri = key;
m_workurimap[key] = 1;
//pthread_mutex_unlock(&m_mutexuri);
}
pthread_mutex_unlock(&m_mutexuri);
return r;
}
bool CWorkPool::delworkuri(string key)
{
pthread_mutex_lock(&m_mutexuri);
// deleted
m_workurimap.erase(key);
pthread_mutex_unlock(&m_mutexuri);
return true;
}