+ _dbus_assert (watch != NULL);
+
+ HAVE_LOCK_CHECK (server);
+ protected_change_watch (server, watch,
+ NULL, NULL,
+ _dbus_watch_list_toggle_watch,
+ enabled);
+}
+
+/** Function to be called in protected_change_timeout() with refcount held */
+typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
+ DBusTimeout *timeout);
+/** Function to be called in protected_change_timeout() with refcount held */
+typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
+ DBusTimeout *timeout);
+/** Function to be called in protected_change_timeout() with refcount held */
+typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
+
+
+static dbus_bool_t
+protected_change_timeout (DBusServer *server,
+ DBusTimeout *timeout,
+ DBusTimeoutAddFunction add_function,
+ DBusTimeoutRemoveFunction remove_function,
+ DBusTimeoutToggleFunction toggle_function,
+ dbus_bool_t enabled)
+{
+ DBusTimeoutList *timeouts;
+ dbus_bool_t retval;
+
+ HAVE_LOCK_CHECK (server);
+
+ /* This isn't really safe or reasonable; a better pattern is the "do everything, then
+ * drop lock and call out" one; but it has to be propagated up through all callers
+ */
+
+ timeouts = server->timeouts;
+ if (timeouts)
+ {
+ server->timeouts = NULL;
+ _dbus_server_ref_unlocked (server);
+ SERVER_UNLOCK (server);
+
+ if (add_function)
+ retval = (* add_function) (timeouts, timeout);
+ else if (remove_function)
+ {
+ retval = TRUE;
+ (* remove_function) (timeouts, timeout);
+ }
+ else
+ {
+ retval = TRUE;
+ (* toggle_function) (timeouts, timeout, enabled);
+ }
+
+ SERVER_LOCK (server);
+ server->timeouts = timeouts;
+ _dbus_server_unref_unlocked (server);
+
+ return retval;
+ }
+ else
+ return FALSE;