ORBit blocking in connect(). And how to deal with SIGPIPE.




Hello Elliot,

    As you know, we're using a hack called gnome_unknown_ping() in
Bonobo to see if a remote CORBA object is still alive.  It's a very
simple hack; it just tries to ref and unref the remote object -- two
corba method invocations.  Unfortunately, ORBit seems to have some
problems with trying to talk to a dead remote object.  In particular,
when I call gnome_unknown_ping() on a dead remote server, the client
blocks in connect() for a long, long time.  Here's the stack trace:

(gdb) bt
#0  0x40517d72 in __libc_connect ()
#1  0x40317e30 in iiop_connection_new (host=0x8084f78 "retrans.mit.edu", port=1075) at connection.c:841
#2  0x40317d11 in iiop_connection_get (host=0x8084f78 "retrans.mit.edu", port=1075, existing_only=0) at connection.c:792
#3  0x402f32d4 in ORBit_parse_inet (obj=0x8083694, hostname=0x8084f78 "retrans.mit.edu", port=1075, existing_only=0) at orbit.c:330
#4  0x402f6e05 in ORBit_activate_profile (item=0x8084f40, data=0x8083694) at orbit_object.c:563
#5  0x401e9c30 in g_slist_foreach (list=0x8055250, func=0x402f6dbc <ORBit_activate_profile>, user_data=0x8083694) at gslist.c:493
#6  0x402f6e9a in _ORBit_object_get_connection (obj=0x8083694) at orbit_object.c:581
#7  0x402c78ed in GNOME_Unknown_ref (_obj=0x8083694, ev=0xbffff0c0) at gnome-unknown-stubs.c:31
#8  0x40045a27 in gnome_unknown_ping (object=0x8083694) at gnome-object.c:572

    So this is pretty nasty.  It seems to only happen if the client
has never called into that server before.  Which makes sense.

    Three's another, perhaps more harrowing thing I wanted to bring
up, while I've got the floor.  Often, when you try to invoke a method
on a remote server, ORBit triggers a SIGPIPE on writev().  This is bad
for Bonobo components, which aren't supposed to crash if the remote
end goes down.

    Currently, what Bonobo does to "solve" this problem is to ignore
SIGPIPE everywhere.  The problem with this is that other parts of your
program may genuinely generate SIGPIPEs which will be ignored (not so
bad -- the system calls will return -EPIPE), or, if you want to setup
a custom SIGPIPE handler, you're out of luck.

    So what I suggest is that the call to writev() in ORBit
(giop-msg-buffer.c:197 or so) be surrounded with something like this:

        orbit_ignore_sigpipe = 1;

        result = writev ( ... );

        orbit_ignore_sigpipe = 0;

And have orbit_ignore_sigpipe be publicly exported.  So when Bonobo
sets up a signal handler, it can cache a pointer to the user's
previously-set signal handler.  Then, when SIGPIPE is raised, it can
chain to the user's handler if orbit_ignore_sigpipe is 0.

    What do you think?  Too gross?  Reentrancy/thread problems?

Nat



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]