qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rob Springer <rsprin...@etinternational.com>
Subject Potential deadlock with LocalQueue::get() / Session::close()?
Date Tue, 03 Mar 2009 22:27:38 GMT
Hey all - I've noticed a problem when debugging some code, and it looks
to my eyes like there's a potential deadlock situation using the timed
LocalQueue::get() command when a fatal interrupt occurs.  I've posted
what I hope is clear reproducer code below.  Could someone else take a
quick look at it and tell me if I'm crazy or correct?  The long and the
short of it looks to be that, when a timed LocalQueue::get() is called,
a particular mutex is held.  When the flow of execution is altered by an
interrupt, if Session::close() is called (in, say, a cleanup routine),
that mutex need to again be held, but since it is already being held, a
deadlock occurs.

Really, I assume the "no-deadlock" case is just as susceptible, but the
dangerous window is just smaller.  Is there a workaround to force an
unlock?

Thanks for the help!
-rob

#include <iostream>
#include <string>
#include <qpid/client/Connection.h>
#include <qpid/client/Session.h>
#include <qpid/client/SubscriptionManager.h>
#include <qpid/client/Subscription.h>
#include <qpid/client/LocalQueue.h>
#include <qpid/client/Message.h>
#include <signal.h>

using namespace qpid;
using namespace client;

Session* globalSession = NULL;

void intHandler(int signum)
{
    std::cout << "IN INTERRUPT HANDLER" << std::endl;
    if(globalSession)
        globalSession->close();
    std::cout << "SESSION CLOSED" << std::endl;
    exit(0);
}

int main(int argc, char** argv)
{
    signal(SIGINT, intHandler);
    Connection conn;
    conn.open("localhost", 5672);
    Session session = conn.newSession();
    globalSession = &session;
    SubscriptionManager subMgr(session);
    session.queueDeclare(arg::queue="asdf");
    session.exchangeBind(arg::exchange="amq.topic",
                         arg::queue="asdf",
                         arg::bindingKey="a.b.c");
    LocalQueue lq;
    Subscription sub = subMgr.subscribe(lq, "asdf");
    Message msg;
    #ifdef DEADLOCK
        msg = lq.get(5000000000000000000LL);
    #else
        int i=0;
        while(i < 5000000)
        {
            lq.get(msg);
            sleep(1);
            i++;
        }
    #endif
}



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:users-subscribe@qpid.apache.org


Mime
View raw message