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
-3
View File
@@ -103,7 +103,6 @@ private:
#ifdef HAVE_THREADED_DNS
int m_iTDNSpipe[2];
pthread_mutex_t* m_mTDNSmutex;
class CTDNSMonitorFD;
friend class CTDNSMonitorFD;
@@ -124,7 +123,6 @@ private:
struct TDNSArg {
CString sHostname;
TDNSTask* task;
pthread_mutex_t* mutex;
int fd;
bool bBind;
@@ -133,7 +131,6 @@ private:
};
void StartTDNSThread(TDNSTask* task, bool bBind);
void SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* aiResult);
void TryToFinishTDNSTask(TDNSTask* task);
void RetrieveTDNSResult();
static void* TDNSThread(void* argument);
#endif
+12 -11
View File
@@ -98,11 +98,11 @@ ax_pthread_ok=no
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CXXFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
if test x"$ax_pthread_ok" = xno; then
@@ -110,7 +110,7 @@ if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CXXFLAGS="$save_CXXFLAGS"
fi
# We must check for the threads library under a number of different
@@ -175,6 +175,7 @@ for flag in $ax_pthread_flags; do
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
PTHREAD_LIBS="$flag"
;;
pthread-config)
@@ -191,9 +192,9 @@ for flag in $ax_pthread_flags; do
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
save_CXXFLAGS="$CXXFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@@ -205,7 +206,7 @@ for flag in $ax_pthread_flags; do
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { a = 0; }
static void routine(void *a) { *((int*)a) = 42; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
@@ -217,7 +218,7 @@ for flag in $ax_pthread_flags; do
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CXXFLAGS="$save_CXXFLAGS"
AC_MSG_RESULT($ax_pthread_ok)
if test "x$ax_pthread_ok" = xyes; then
@@ -233,8 +234,8 @@ fi
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
@@ -281,7 +282,7 @@ if test "x$ax_pthread_ok" = xyes; then
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CXXFLAGS="$save_CXXFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
+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();
}