You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "eagle518 (JIRA)" <ji...@apache.org> on 2015/01/23 02:46:34 UTC

[jira] [Created] (AMQCPP-559) Deadlock in concurrent condition

eagle518 created AMQCPP-559:
-------------------------------

             Summary: Deadlock in concurrent condition
                 Key: AMQCPP-559
                 URL: https://issues.apache.org/jira/browse/AMQCPP-559
             Project: ActiveMQ C++ Client
          Issue Type: Bug
         Environment: CentOS release 6.4 (Final)
            Reporter: eagle518
            Assignee: Timothy Bish


run a moment and deadlock at await().

code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <activemq/util/Config.h>
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Runtime.h>
#include <decaf/lang/Integer.h>
#include <decaf/util/ArrayList.h>
#include <decaf/lang/String.h>
#include <decaf/lang/System.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/exceptions/RuntimeException.h>
#include <decaf/util/concurrent/locks/Lock.h>
#include <decaf/util/concurrent/locks/Condition.h>
#include <decaf/util/concurrent/locks/ReentrantLock.h>
#include <decaf/util/LinkedList.h>

using namespace std;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::util;
using namespace decaf::util::concurrent;
using namespace decaf::util::concurrent::locks;

class LockConditionTest {
public:
	LockConditionTest();
	virtual ~LockConditionTest();

	void put();

	String* take();

private:
	Condition* fullCondition;
	Condition* emptyCondition;
	decaf::util::concurrent::locks::Lock* lock;
	int maxSize;

	LinkedList<String*> *bag;
};

class Producer: public Runnable {
public:
	Producer(LockConditionTest *test) {
		m_parent = test;
	}
	virtual ~Producer() {

	}
	void run() {
		try {
			do {
				m_parent->put();
			} while (1);
		} catch (Exception& e) {
			e.printStackTrace();
			throw e;
		}
	}
private:
	LockConditionTest *m_parent;
};

class Customer: public Runnable {
public:
	Customer(LockConditionTest *test) {
		m_parent = test;
	}
	virtual ~Customer() {

	}
	void run() {
		do {
			String* s = m_parent->take();
			delete s;
		} while (1);
	}
private:
	LockConditionTest *m_parent;
};

LockConditionTest::LockConditionTest() {
	lock = new ReentrantLock();
	fullCondition = lock->newCondition();
	emptyCondition = lock->newCondition();
	maxSize = 10;
	bag = new LinkedList<String*>();
}
LockConditionTest::~LockConditionTest() {
	delete bag;
	delete fullCondition;
	delete emptyCondition;
	delete lock;
}

void LockConditionTest::put() {
	int n = 0;
	lock->lock();
	try {
		while (bag->size() >= maxSize)
			fullCondition->await();
		bag->push(new String(Integer::toString(n++)));
		printf("push: %d\n", bag->size());
		emptyCondition->signal();
	} catch (Exception& ex) {
		ex.printStackTrace();
	}
	lock->unlock();
}

String* LockConditionTest::take() {
	String* result = NULL;
	lock->lock();
	try {
		while (bag->size() == 0)
			emptyCondition->await();
		result = dynamic_cast<String*>(bag->pop());
		printf("pop: %d\n", bag->size());
		fullCondition->signal();
	} catch (Exception& e) {
		e.printStackTrace();
	}
	lock->unlock();
	return result;
}

static void test_condition()
{

	ArrayList<Thread*> arr;
	ArrayList<Runnable*> arr1;

	LockConditionTest *tct = new LockConditionTest();
	Runnable *r1 = new Producer(tct);
	Thread *t1 = new Thread(r1);
	t1->start();
	arr.add(t1);
	arr1.add(r1);

	Runnable *c1 = new Customer(tct);
	Thread *t2 = new Thread(c1);
	t2->start();
	arr.add(t2);
	arr1.add(c1);

	Runnable *r2 = new Producer(tct);
	Thread *t3 = new Thread(r2);
	t3->start();
	arr.add(t3);
	arr1.add(r2);

	Runnable *c2 = new Customer(tct);
	Thread *t4 = new Thread(c2);
	t4->start();
	arr.add(t4);
	arr1.add(c2);

	Runnable *r3 = new Producer(tct);
	Thread *t5 = new Thread(r3);
	t5->start();
	arr.add(t5);
	arr1.add(r3);

	Runnable *c3 = new Customer(tct);
	Thread *t6 = new Thread(c3);
	t6->start();
	arr.add(t1);
	arr1.add(c3);


	for (int i = 0; i < arr.size(); i++) {
		arr.get(i)->join();
	}
	delete tct;

	printf("end of test_condition.\n");
}

int main(int argc, const char** argv)
{
	activemq::library::ActiveMQCPP::initializeLibrary();

	test_condition();

	return 0;
}




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)