int CHttpClient::PostFile(string url) { string host, path; int port = 0; if(ParseUrl(url, host, port, path) != 0) { m_errno = -9; return -1; } //LOG.Log("Access url: %s", url.c_str()); m_reqMsg.SetHost(host, port); m_reqMsg.SetPath(path); int64 startTime = GetMilSec(); int connSucc = 0; int sock = -1; int i; for(i = 0; i < 1; i++) { sock = CTcpSock::Create(); if(CTcpSock::Connect(sock, host, port, 3000) == 0) { connSucc = 1; break; } else { CTcpSock::Close(sock); } } if(!connSucc) { m_errno = -1; return -1; } if(m_reqMsg.PostFile(sock) != 0) { m_errno = -2; CTcpSock::Close(sock); return -1; } if(m_resMsg.RecvMsg(sock) != 0) { m_errno = -2; CTcpSock::Close(sock); return -1; } m_errno = 0; CTcpSock::Close(sock); return 0; }
uint64 CTimerThread::RegisterByMilSec(bool run_once, int interval_time, std::function<void(long)> fp) { std::shared_ptr<STimer> newTimer = std::make_shared<STimer>(); newTimer->m_iId = ++m_iCurretId; newTimer->m_bOnce = run_once; newTimer->m_pFunc = fp; newTimer->m_iInterval = interval_time; newTimer->m_iStartTime = GetMilSec(); newTimer->m_iNextTime = newTimer->m_iStartTime + newTimer->m_iInterval; { std::unique_lock<std::recursive_mutex> lock(m_mutexTimer); m_mapOrderedTimers.insert(std::make_pair(newTimer->m_iNextTime, newTimer)); m_mapTimers[newTimer->m_iId] = newTimer; m_condition.notify_one(); } return newTimer->m_iId; }
int CHttpClient::AccessUrl(string url, int timeout, int redirectLevel) { if(timeout <= 0) timeout = 99999999; m_resMsg.Clear(); string host, path; int port = 0; if(ParseUrl(url, host, port, path) != 0) { m_errno = -1; return -1; } //LOG.Log("Access url: %s", url.c_str()); m_reqMsg.SetHost(host, port); m_reqMsg.SetPath(path); int64 startTime = GetMilSec(); string ip; if(ntohl(inet_addr(host.c_str())) != 0xffffffff && ntohl(inet_addr(host.c_str())) > ntohl(inet_addr("1.0.0.0"))) { ip = host; } else { struct hostent * phe; phe = gethostbyname(host.c_str()); if (phe == NULL) { m_errno = -1; return -1; } else { struct in_addr addr; addr.s_addr = *(unsigned long *) phe->h_addr_list[0]; ip = inet_ntoa(addr); } } int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock == -1) { m_errno = -2; return -1; } struct sockaddr_in servAddr; servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(ip.c_str()); servAddr.sin_port = htons(port); if(connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -1) { m_errno = -3; CTcpSock::Close(sock); return -1; } //重新计算超时时长 timeout -= GetMilSec() - startTime; if(timeout <= 0) { m_errno = -4; CTcpSock::Close(sock); return -1; } startTime = GetMilSec(); if(m_reqMsg.SendMsg(sock, timeout) != 0) { m_errno = -5; CTcpSock::Close(sock); return -1; } //重新计算超时时长 timeout -= GetMilSec() - startTime; if(timeout <= 0) { m_errno = -4; CTcpSock::Close(sock); return -1; } string reqCmd; m_reqMsg.GetCmd(reqCmd); if(reqCmd == "HEAD") m_resMsg.SetOnlyHead(1); if(m_resMsg.RecvMsg(sock, timeout) != 0) { m_errno = -6; CTcpSock::Close(sock); return -1; } m_errno = 0; CTcpSock::Close(sock); int stateCode; m_resMsg.GetStatusCode(stateCode); if(redirectLevel > 0 && (stateCode == 301 || stateCode == 302)) { string location; m_resMsg.GetHeader("Location", location); if(location.size() > 0) { string newLocation; CvtAbsUrl(url, location, newLocation); return AccessUrl(newLocation, timeout, redirectLevel-1); } } return 0; }
void CTimerThread::RunInThead() { int64 nextTime; std::shared_ptr<STimer> firstTimer; do { //1.找到最早触发的定时器的时间 nextTime = -1; firstTimer.reset(); //mark1:这里锁的用法 std::unique_lock<std::recursive_mutex> lock(m_mutexTimer); auto iterTimer = m_mapOrderedTimers.begin(); for (; iterTimer != m_mapOrderedTimers.end();) { if (iterTimer->second->m_bDeleted == true) { m_mapTimers.erase(iterTimer->second->m_iId); iterTimer = m_mapOrderedTimers.erase(iterTimer); } else { nextTime = iterTimer->second->m_iNextTime; firstTimer = iterTimer->second; break; } } //2.如果没有定时器,等待一小时 if (nextTime == -1) { //mark1:锁配合condition_variable_any使用,wait_for时相当于解锁了 m_condition.wait_for(lock, std::chrono::hours(1)); } else { //3.有定时器的情况,先检查是否已经超时(10ms的精度误差) uint64 nowTime = GetMilSec(); if (nowTime + 10 >= (uint64)nextTime) { //3.1时间已经到了,则执行定时函数 if (m_outMutex != NULL) { //mark2:这里有一点特殊操作,为了确保m_outMutex -> m_mutexTimer这样的加锁顺序,因为对外而言,只能是m_outMutex -> m_mutexTimer //的加锁顺序,如果这里不这样做,会出现两个线程两个锁反序加锁,从而导致死锁 lock.unlock(); std::unique_lock<std::recursive_mutex> lock1(*m_outMutex); lock.lock(); if (!firstTimer->m_bDeleted) firstTimer->m_pFunc(nowTime); } else { firstTimer->m_pFunc(nowTime); } //3.2一次性定时器则标记删除,非一次性定时器重新加入方便排序 if (firstTimer->m_bOnce) firstTimer->m_bDeleted = true; else { firstTimer->m_iNextTime = nowTime + firstTimer->m_iInterval; m_mapOrderedTimers.erase(iterTimer); m_mapOrderedTimers.insert(std::make_pair(firstTimer->m_iNextTime, firstTimer)); } //mark1:退出锁的生命周期,解锁 continue; } else { //3.3时间没有到,则执行等待 //mark1:锁配合condition_variable_any使用,wait_for时相当于解锁了 m_condition.wait_for(lock, std::chrono::milliseconds(nextTime - nowTime)); } } } while (m_bRun); }