Re: [Evolution-hackers] EDS API calls hang when EDS dies - how to detect that?



On Sun, 2007-09-23 at 22:21 +0200, Patrick Ohly wrote:
> Looking at the current libebook API documentation [1] I see a
> "backend-died" signal prototype. I don't remember having seen that
> before - was the signal or its documentation added recently?
> 
> I suppose I can call g_signal_connect(ebook, "backend-died", mycallback,
> NULL), then in mycallback print an error and abort the process, right?

I tried that, but although the evolution-data-server process is gone the
signal wasn't delivered.

My actual code is:
    g_signal_connect_after(m_calendar,
                           "backend-died",
                           G_CALLBACK(EvolutionSyncClient::fatalError),
                           (void *)"Evolution Data Server has died unexpectedly, database no longer available.");

I saw in the code that (backend_died" (BTW, why the underscore instead
of the hyphen used elsewhere?) is hooked to component_died in
e-component-listener.c which in turn depends on
ORBit_small_listen_for_broken(). Somehow the callback given to
ORBit_small_listen_for_broken() is never called: I have a breakpoint
there in a debugger.

[a bit later]

Tracing through it in the debugger I see that orbit2-2.14.7/linc2 is
responsible for monitoring the file descriptor. linc notices that the
link goes down (LINK_DISCONNECTED in link_connection_state_changed_T_R)
and it schedules an idle callback which would have raised the
necesessary signals (g_idle_add (link_connection_broken_idle, cnx)).

The problem now is: this idle callback is not invoked.

[yet a bit later]

I stepped through g_idle_add(). The idle callback is attached to the
default context returned by g_main_context_default():
(gdb) p *default_main_context
$16 = {mutex = {runtime_mutex = 0x0, static_mutex = {
      pad = "\001\000\000\000\000\000\000\0005U\000\000\000\000\000\000\001\000\000\000\000\000\000", 
      dummy_double = 4.9406564584124654e-324, dummy_pointer = 0x1, dummy_long = 1}}, cond = 0x0, owner = 0x0, 
  owner_count = 0, waiters = 0x0, ref_count = 1, pending_dispatches = 0x8198010, timeout = 0, next_id = 5, 
  source_list = 0x81983a0, in_check_or_prepare = 0, poll_records = 0x8198020, n_poll_records = 2, 
  cached_poll_array = 0x0, cached_poll_array_size = 0, wake_up_pipe = {9, 10}, wake_up_rec = {fd = 9, events = 1, 
    revents = 0}, poll_waiting = 0, poll_changed = 1, poll_func = 0xb73fc7c0 <poll>, current_time = {tv_sec = 0, 
    tv_usec = 0}, time_is_current = 0}
(gdb) p default_main_context
$17 = (GMainContext *) 0x81982e8

This is not the context of the thread which runs the orbit loop:
g_main_context_iterate (context=0x81a0528, ...

So if I understand this correctly, the problem with the synchronous EDS
API calls is that no thread drives the default event loop unless the
application does that.

[trying it out in SyncEvolution]

Adding a background thread which runs an event loop in the default
context indeed caused the "backend-died" signal to be emitted. I thought
that maybe now the API functions would also return an error, but not so:
unless I terminate the process in my own "backend-died" signal handler
the process remains stuck in the synchronous API call.

Enough for now: I have a solution which is good enough for
SyncEvolution. I still wonder if and how the problem could be fixed in
the EDS libs, but this is out of scope for me - sorry!

-- 
Bye, Patrick Ohly
--  
Patrick Ohly gmx de
http://www.estamos.de/


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