[Evolution-hackers] My ORBit2 Win32 problem today



I spent much time today debugging a problem related to
evolution-exchange. When quitting Evolution, and then after a while
starting it again, it hang. bonobo-activation-server was waiting for a
reply from evolution-exchange-storage.exe (which had been staying around
even after Evolution quit).

That process isn't actually supposed to stay around after Evolution
quits .(Unlike gconfd-2, evolution-data-server and
evolution-alarm-notify.) So, why didn't it go away? It actually was hung
in a quite spectacular fashion, so no wonder it couldn't be contacted.
(Its sockets were still in LISTEN and ESTABLISHED state, so
bonobo-activation-server didn't notice the process was in fact dead as a
dodo.)

Well, the root cause why it didn't go away was the atexit() call in
ORBit2's CORBA_ORB_init(). (Well, g_atexit(), but that is just a #define
for atexit() in Win32.)

The exact semantics for atexit() are hard to define on modern systems
with shared and dynamically loaded libraries. What if one DSO registers
an atexit() function that calls a function in another DSO? Apparently
especially on Windows the environment in which the functions registered
with atexit() eventually run can be rather random. My personal opinion
is that atexit() should be banned...

On Windows, atexit()-registered functions run when the registering DLL
is being unloaded. As far as I know, there is no way to be sure what
other DLLs are still present at the time. Apparently not even WinSock
necessarily works at all then. This was what caused the hang. Why
evolution-exchange-storage has affected but not other processes that
link to libORBit2, I don't know, probably just a coincidence. As I said,
atexit() behaviour has much randomness.

So, I simply ifdeffed out the atexit() usage on Windows... Just let the
process die, and any TCP peers should notice that the connections break
and act accordingly. Seems to work fine, although I guess there is a
risk that, like the comment in corba-orb.c says, the atexit()
functionality really is needed "to clean up any remaining UDS and to
flush any remaining oneway traffic in buffers".

A safe way around this would be to explicitly flush and shut down CORBA
and Bonobo before exiting main() in evolution-exchange/storage/main.c.
Unfortunately I couldn't find any API to do that cleanly. Calling
bonobo_debug_shutdown() (twice, as bonobo_init_full() apparently gets
called twice and bonobo_debug_shutdown() needs to be called as many
times to actually do anything...) causes a g_error() from
bonobo_context_shutdown(): "In-proc object has no servant association
this probably means you shutdown the ORB before you shutdown libbonobo".
I wonder if that is a bogus error message?

Anyway, there are now fresh zipfiles for ORBit2, libbonobo,
evolution-data-server and evolution in
http://ftp.gnome.org/pub/gnome/platform/2.14/2.14.2/win32/ and
http://ftp.gnome.org/pub/gnome/desktop/2.14/2.14.2/win32/ . In addition
to the fix for the problem described above, they also contain the fixes
mentioned in my recent mails:

- There is no absolute need any longer to kill the processes that stay
running when one quits Evolution, or to clean out state files.

- Evolution on Windows now works for users with any random Unicode
characters in their username, or if installed in a folder with spaces
(or any random Unicode character) in the pathname. (This of course is
one main point which the porting effort has had to take into
consideration from start; but only recently did I actually test it
thoroughly.) 

Enjoy,
--tml





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