[omniORB] deadlock with distributed callback application

Christof Meerwald cmeerw@web.de
Sun, 3 Jun 2001 02:11:49 +0200


On Thu, 31 May 2001 12:21:58 +0200, Lars Immisch wrote:
>> Hmm. There's clearly something bad going on. The use of LocateRequest
>> shouldn't cause any deadlocks. If possible, I think it would be worth
> I have tried to nail down the problem for two days, but I only managed to get  
> more confused. I mainly don't understand how omniORB manages connections when  
> the operations are oneways and the standard documentation does not say much

omniORB only creates one thread on the server side for each incoming
connection - this is fine as long as each client creates a new connection
for concurrent requests to the same server. But with oneway requests the
client side doesn't know when the server has finished processing the request
(as there is no reply) and AFAIK omniORB doesn't create a new connection for
oneways (or mark the connection as used) -- it just assumes that processing
of oneway requests doesn't take long on the server.

The problem starts when the server is still busy with processing a oneway
request while the client wants to send another two-way request (over the
same connection). The client then has to wait for the reply from the server,
but the server doesn't even see the request as it is still busy with
processing the oneway request.


> Our 'real' system deadlocks immediately when verifyObjectExistsAndType is  
> enabled. When I look where it is hanging, both processes are blocked on the  
> select in tcpSocketStrand::ll_recv called from the _locateRequest inside the  
> omniObjRef::_invoke.

And I guess they are processing oneway requests from each other...


> My suspicion was that in this case, the LocateRequest is sent over a reused  
> connection, and the other oneway invocation gets into the way. But I haven't  
> been able to verify that - mainly because my attempts to recreate the problem

Hmm, I have hacked together some simple Python scripts that show a possible
deadlock situation with oneways:


// deadlock.idl
module deadlock
{
  interface Test
  {
    oneway void op1(in Test ref);
    void op2(in Test ref);
    void op3();
  };
};



#!/usr/bin/python
# deadlock_impl.py
from omniORB import CORBA
import deadlock, deadlock__POA

class Deadlock_i(deadlock__POA.Test):
    def op1(self, ref):
        print "op1"
        ref.op2(self._this())
        print "op1 done"

    def op2(self, ref):
        print "op2"
        ref.op3()
        print "op2 done"

    def op3(self):
        print "op3"



#!/usr/bin/python
# deadlock_server.py
import sys

from omniORB import CORBA
import deadlock, deadlock__POA

from deadlock_impl import Deadlock_i


orb = CORBA.ORB_init(sys.argv)
poa = orb.resolve_initial_references("RootPOA")

server_obj = Deadlock_i()._this()
print orb.object_to_string(server_obj)


poaManager = poa._get_the_POAManager()
poaManager.activate()
orb.run()



#!/usr/bin/python
# deadlock_client.py
import sys

from omniORB import CORBA
import deadlock, deadlock__POA

from deadlock_impl import Deadlock_i


orb = CORBA.ORB_init(sys.argv)
poa = orb.resolve_initial_references("RootPOA")

client_obj = Deadlock_i()._this()


poaManager = poa._get_the_POAManager()
poaManager.activate()

server_obj = orb.string_to_object(sys.argv[1])
server_obj.op1(client_obj)

orb.run()


Just start the server (deadlock_server.py) and then the client
(deadlock_client.py) with the server IOR as its first command line
parameter.


bye, Christof

-- 
http://cmeerw.cjb.net                          Jabber: cmeerw@jabber.at
mailto cmeerw at web.de                   ICQ: 93773535, Yahoo!: cmeerw