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)