<pre>So I&#39;ve been debugging a randomly occurring &quot;Out of Memory&quot; error.   In my trace of what is happening in my multithreaded program, I have come across this function below as my problem.<br><br>static dbus_bool_t
<br>protected_change_timeout (DBusConnection           *connection,<br>                          DBusTimeout              *timeout,<br>                          DBusTimeoutAddFunction    add_function,<br>                          DBusTimeoutRemoveFunction remove_function,
<br>                          DBusTimeoutToggleFunction toggle_function,<br>                          dbus_bool_t               enabled)<br>{<br>  DBusTimeoutList *timeouts;<br>  dbus_bool_t retval;<br>  <br>  HAVE_LOCK_CHECK (connection);
<br><br>  /* This isn&#39;t really safe or reasonable; a better pattern is the &quot;do everything, then<br>   * drop lock and call out&quot; one; but it has to be propagated up through all callers<br>   */<br>  <br>  timeouts = connection-&gt;timeouts;
<br>  if (timeouts)<br>    {<br>      connection-&gt;timeouts = NULL;<br>      _dbus_connection_ref_unlocked (connection);<br>      CONNECTION_UNLOCK (connection);<br><br>      if (add_function)<br>        retval = (* add_function) (timeouts, timeout);
<br>      else if (remove_function)<br>        {<br>          retval = TRUE;<br>          (* remove_function) (timeouts, timeout);<br>        }<br>      else<br>        {<br>          retval = TRUE;<br>          (* toggle_function) (timeouts, timeout, enabled);
<br>        }<br>      <br>      CONNECTION_LOCK (connection);<br>      connection-&gt;timeouts = timeouts;<br>      _dbus_connection_unref_unlocked (connection);<br><br>      return retval;<br>    }<br>  else<br>    return FALSE;
<br>}
<br>Apparently DBus sets the timeout list temporarily to NULL and drops the lock to the connection for changing the timeout .   However if another thread acquires the lock and happens to get to this function again, it fails out of the function because connection-&gt;timeouts is null.   This is proprogated down the stack and eventually turns up as an &quot;Out of Memory&quot; abort in the glib bindings.  So I have two questions.
<br><br>First does anyone know the designed purpose of this function and what would be a safe way to modify the function so that this case doesn&#39;t happen?   I can imply some meaning to the function, but hesitate to quickly change some locking scheme I am not completely familiar with.
<br>Secondly is there a good way we can modify the error return system to give better output of what actually happened?  We can&#39;t change api, but maybe FALSE can represent error, and whoever set FALSE can call a dbus_set_current_error_string(char *), and outside program can print out from dbus_get_current_error_string(char *)?
<br><br>Keith Preston<br><br></pre>