Changeset - 7500ab6c4c30
[Not reviewed]
0 3 0
Jan Kaluza - 9 years ago 2016-02-24 08:35:10
jkaluza@redhat.com
Libtransport: Fix memory leak in HTTPRequest, initialize CURL in the same thread as we use for its cleanup
3 files changed with 22 insertions and 7 deletions:
0 comments (0 inline, 0 general)
libtransport/HTTPRequest.cpp
Show inline comments
 
@@ -6,36 +6,37 @@ DEFINE_LOGGER(logger, "HTTPRequest")
 

	
 
HTTPRequest::HTTPRequest(ThreadPool *tp, Type type, const std::string &url, Callback callback) {
 
	m_type = type;
 
	m_url = url;
 
	m_tp = tp;
 
	m_callback = callback;
 

	
 
	init();
 
	curlhandle = NULL;
 
}
 

	
 
HTTPRequest::HTTPRequest(Type type, const std::string &url) {
 
	m_type = type;
 
	m_url = url;
 
	m_tp = NULL;
 

	
 
	init();
 
	curlhandle = NULL;
 
}
 

	
 
HTTPRequest::~HTTPRequest() {
 
	if (curlhandle) {
 
		LOG4CXX_INFO(logger, "Cleaning up CURL handle");
 
		curl_easy_cleanup(curlhandle);
 
		curlhandle = NULL;
 
	}
 
}
 

	
 
bool HTTPRequest::init() {
 
	curlhandle = curl_easy_init();
 
	if (curlhandle) {
 
		return true;
 
	}
 

	
 
	curlhandle = curl_easy_init();
 
	if (curlhandle) {
 
		curl_easy_setopt(curlhandle, CURLOPT_PROXY, NULL);
 
		curl_easy_setopt(curlhandle, CURLOPT_PROXYUSERPWD, NULL);
 
		curl_easy_setopt(curlhandle, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
 
		return true;
 
	}
 

	
 
@@ -110,17 +111,25 @@ bool HTTPRequest::GET(std::string url, rapidjson::Document &json) {
 
	}
 

	
 
	return true;
 
}
 

	
 
void HTTPRequest::run() {
 
	if (!init()) {
 
		m_ok =  false;
 
		return;
 
	}
 

	
 
	switch (m_type) {
 
		case Get:
 
			m_ok = GET(m_url, m_json);
 
			break;
 
	}
 

	
 
	curl_easy_cleanup(curlhandle);
 
	curlhandle = NULL;
 
}
 

	
 
void HTTPRequest::finalize() {
 
	m_callback(this, m_ok, m_json, m_data);
 
	onRequestFinished();
 
}
 
@@ -132,12 +141,13 @@ bool HTTPRequest::execute() {
 

	
 
	m_tp->runAsThread(this);
 
	return true;
 
}
 

	
 
bool HTTPRequest::execute(rapidjson::Document &json) {
 
	init();
 
	switch (m_type) {
 
		case Get:
 
			m_ok = GET(m_url, json);
 
			break;
 
	}
 

	
libtransport/ThreadPool.cpp
Show inline comments
 
@@ -15,13 +15,13 @@ static void Worker(Thread *t, int wid, Swift::EventLoop *loop)
 

	
 

	
 
ThreadPool::ThreadPool(Swift::EventLoop *loop, int maxthreads) : MAX_THREADS(maxthreads)
 
{
 
	this->loop = loop;
 
	activeThreads = 0;
 
	worker = new boost::thread*[MAX_THREADS];
 
	worker = (boost::thread **) malloc(sizeof(boost::thread *) * MAX_THREADS);
 
	for(int i=0 ; i<MAX_THREADS ; i++) {
 
		worker[i] = NULL;
 
		freeThreads.push(i);
 
	}
 
	onWorkCompleted.connect(boost::bind(&ThreadPool::cleandUp, this, _1, _2));
 
	onWorkerAvailable.connect(boost::bind(&ThreadPool::scheduleFromQueue, this));
 
@@ -31,13 +31,13 @@ ThreadPool::~ThreadPool()
 
{
 
	for(int i=0; i<MAX_THREADS ; i++) {
 
		if(worker[i]) {
 
			delete worker[i];
 
		}
 
	}
 
	delete worker;
 
	free(worker);
 

	
 
	while(!requestQueue.empty()) {
 
		Thread *t = requestQueue.front(); requestQueue.pop();
 
		delete t;
 
	}
 
}
tests/libtransport/main.cpp
Show inline comments
 
@@ -9,12 +9,13 @@
 
#include "log4cxx/logger.h"
 
#include "log4cxx/fileappender.h"
 
#include "log4cxx/patternlayout.h"
 
#include "log4cxx/propertyconfigurator.h"
 

	
 
#include "transport/protocol.pb.h"
 
#include "transport/HTTPRequest.h"
 

	
 
using namespace log4cxx;
 
#endif
 

	
 

	
 
int main (int argc, char* argv[])
 
@@ -35,12 +36,14 @@ int main (int argc, char* argv[])
 
	}
 

	
 
	if (testsToRun.empty()) {
 
		testsToRun.push_back("");
 
	}
 

	
 
	Transport::HTTPRequest::globalInit();
 

	
 
	// informs test-listener about testresults
 
	CPPUNIT_NS :: TestResult testresult;
 

	
 
	// register listener for collecting the test-results
 
	CPPUNIT_NS :: TestResultCollector collectedresults;
 
	testresult.addListener (&collectedresults);
 
@@ -55,20 +58,22 @@ int main (int argc, char* argv[])
 
	for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) {
 
		try {
 
			testrunner.run(testresult, *i);
 
		}
 
		catch (const std::exception& e) {
 
			google::protobuf::ShutdownProtobufLibrary();
 
			Transport::HTTPRequest::globalCleanup();
 
			std::cerr << "Error: " << e.what() << std::endl;
 
			return -1;
 
		}
 
	}
 

	
 
	// output results in compiler-format
 
	CPPUNIT_NS :: CompilerOutputter compileroutputter (&collectedresults, std::cerr);
 
	compileroutputter.write ();
 

	
 
	google::protobuf::ShutdownProtobufLibrary();
 
	Transport::HTTPRequest::globalCleanup();
 

	
 
	// return 0 if tests were successful
 
	return collectedresults.wasSuccessful () ? 0 : 1;
 
}
0 comments (0 inline, 0 general)