Merge branch 'master' of github.com:znc/znc

This commit is contained in:
Alexey Sokolov
2012-02-05 17:44:31 +07:00
5 changed files with 42 additions and 59 deletions
+9 -28
View File
@@ -76,21 +76,15 @@ void* CSockManager::TDNSThread(void* argument) {
sleep(5); // wait 5 seconds before next try
}
pthread_mutex_t* mutex = a->mutex;
pthread_mutex_lock(mutex);
int wrote = 0;
int need = sizeof(TDNSArg*);
char* x = (char*)&a;
while (wrote < need) {
int w = write(a->fd, x, need - wrote);
if (-1 == w) {
DEBUG("Something bad happened during write() to a pipe from TDNSThread: " << strerror(errno));
exit(1);
}
wrote += w;
x += w;
// This write() must succeed because POSIX guarantees that writes of
// less than PIPE_BUF are atomic (and PIPE_BUF is at least 512).
int w = write(a->fd, x, need);
if (w != need) {
DEBUG("Something bad happened during write() to a pipe from TDNSThread, wrote " << w << " bytes: " << strerror(errno));
exit(1);
}
pthread_mutex_unlock(mutex);
return NULL;
}
@@ -99,7 +93,6 @@ void CSockManager::StartTDNSThread(TDNSTask* task, bool bBind) {
TDNSArg* arg = new TDNSArg;
arg->sHostname = sHostname;
arg->task = task;
arg->mutex = m_mTDNSmutex;
arg->fd = m_iTDNSpipe[1];
arg->bBind = bBind;
arg->iRes = 0;
@@ -136,13 +129,13 @@ void CSockManager::SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* a
task->aiTarget = aiResult;
task->bDoneTarget = true;
}
TryToFinishTDNSTask(task);
}
void CSockManager::TryToFinishTDNSTask(TDNSTask* task) {
// Now that something is done, check if everything we needed is done
if (!task->bDoneBind || !task->bDoneTarget) {
return;
}
// All needed DNS is done, now collect the results
addrinfo* aiTarget = NULL;
addrinfo* aiBind = NULL;
@@ -237,12 +230,6 @@ void CSockManager::RetrieveTDNSResult() {
CSockManager::CSockManager() {
#ifdef HAVE_THREADED_DNS
m_mTDNSmutex = new pthread_mutex_t;
int m = pthread_mutex_init(m_mTDNSmutex, NULL);
if (m) {
DEBUG("Ouch, can't init mutex for threaded DNS resolving: " << strerror(m));
exit(1);
}
if (pipe(m_iTDNSpipe)) {
DEBUG("Ouch, can't open pipe for threaded DNS resolving: " << strerror(errno));
exit(1);
@@ -253,12 +240,6 @@ CSockManager::CSockManager() {
}
CSockManager::~CSockManager() {
#ifdef HAVE_THREADED_DNS
// Here pthread_mutex_destroy(m_mTDNSmutex); and delete m_mTDNSmutex; should be called...
// But lifetime of CSockManager is the same of CZNC, and if to destroy the mutex now,
// lock() from inside TDNSThread will fail.
// So here is a resource and memory leak, but this znc process will die in few moments anyway.
#endif
}
void CSockManager::Connect(const CString& sHostname, u_short iPort, const CString& sSockName, int iTimeout, bool bSSL, const CString& sBindHost, CZNCSock *pcSock) {
+2 -4
View File
@@ -89,11 +89,9 @@ CUser::CUser(const CString& sUserName)
CUser::~CUser() {
// Delete networks
for (unsigned int c = 0; c < m_vIRCNetworks.size(); c++) {
CIRCNetwork* pNetwork = m_vIRCNetworks[c];
delete pNetwork;
while (!m_vIRCNetworks.empty()) {
delete *m_vIRCNetworks.begin();
}
m_vIRCNetworks.clear();
// Delete clients
for (unsigned int c = 0; c < m_vClients.size(); c++) {
+19 -13
View File
@@ -1827,27 +1827,33 @@ public:
protected:
virtual void RunJob() {
list<CIRCNetwork*>& ConnectionQueue = CZNC::Get().GetConnectionQueue();
list<CIRCNetwork*> ConnectionQueue;
list<CIRCNetwork*>& RealConnectionQueue = CZNC::Get().GetConnectionQueue();
/* We store the end of the queue, so CIRCNetwork::Connect() can add
* itself back to the queue and we wont end up in an infinite loop. */
list<CIRCNetwork*>::iterator end = ConnectionQueue.end();
list<CIRCNetwork*>::iterator it;
// Problem: If a network can't connect right now because e.g. it
// is throttled, it will re-insert itself into the connection
// queue. However, we must only give each network a single
// chance during this timer run.
//
// Solution: We move the connection queue to our local list at
// the beginning and work from that.
ConnectionQueue.swap(RealConnectionQueue);
for (it = ConnectionQueue.begin(); it != end;) {
CIRCNetwork *pNetwork = *it;
/* We must erase the network from the queue before we try to connect
* because it may try to add the network to the queue (which would
* fail if we were already in the queue) */
it = ConnectionQueue.erase(it);
while (!ConnectionQueue.empty()) {
CIRCNetwork *pNetwork = ConnectionQueue.front();
ConnectionQueue.pop_front();
if (pNetwork->Connect()) {
break;
}
}
if (ConnectionQueue.empty()) {
/* Now re-insert anything that is left in our local list into
* the real connection queue.
*/
RealConnectionQueue.splice(RealConnectionQueue.begin(), ConnectionQueue);
if (RealConnectionQueue.empty()) {
DEBUG("ConnectQueueTimer done");
CZNC::Get().DisableConnectQueue();
}