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)

Reply via email to