[kupfer: 13/41] vim: Respawn service child if it dies with a signal



commit eac74e2a0e1dd399aa1c630260f94669ee807c02
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Tue Apr 26 18:44:00 2011 +0200

    vim: Respawn service child if it dies with a signal
    
    We respawn if the child dies, with a 10 second interval.

 kupfer/plugin/vim/plugin.py |   39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)
---
diff --git a/kupfer/plugin/vim/plugin.py b/kupfer/plugin/vim/plugin.py
index a424a01..eec4f11 100644
--- a/kupfer/plugin/vim/plugin.py
+++ b/kupfer/plugin/vim/plugin.py
@@ -121,9 +121,9 @@ def get_plugin_service_obj(plugin_id, activate=True):
 	try:
 		proxy_obj = bus.get_object(service_name, object_name)
 	except dbus.DBusException as exc:
-		pretty.print_debug(__name__, exc)
 		if activate:
-			return start_plugin_helper("kupfer.plugin.%s.service" % plugin_id)
+			service_id = "kupfer.plugin.%s.service" % plugin_id
+			return start_plugin_helper(service_id, True)
 		return None
 	proxy_iface = dbus.Interface(proxy_obj, interface_name)
 	return proxy_iface
@@ -137,11 +137,42 @@ def stop_plugin_service(plugin_id):
 		plug_iface.Exit(reply_handler=_dummy_handler,
 		                error_handler=_dummy_handler)
 
-def start_plugin_helper(name):
+def on_child_exit(pid, condition, user_data):
+	# @condition is the &status field of waitpid(2) (C library)
+	import os
+	argv, respawn = user_data
+	if respawn:
+		is_signal = os.WIFSIGNALED(condition)
+		if is_signal and respawn:
+			glib.timeout_add_seconds(10, spawn_child, argv, respawn)
+
+def spawn_child(argv, respawn=True):
+	"""
+	Spawn argv in the mainloop and keeping it as a child process
+	(so that it exits with the parent).
+
+	@respawn: If True, respawn if child dies abnormally
+
+	raises utils.SpawnError
+	"""
+	flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD)
+	try:
+		pid, stdin_fd, stdout_fd, stderr_fd = \
+			glib.spawn_async(argv, flags=flags)
+	except glib.GError as exc:
+		raise utils.SpawnError(unicode(exc))
+	if pid:
+		glib.child_watch_add(pid, on_child_exit, (argv, respawn))
+
+def start_plugin_helper(name, respawn):
+	"""
+	@respawn: If True, respawn if child dies abnormally
+	"""
 	argv = [sys.executable]
 	argv.extend(sys.argv)
 	argv.append('--exec-helper=%s' % name)
-	utils.spawn_async(argv)
+	pretty.print_debug(__name__, "Spawning", argv)
+	spawn_child(argv, respawn)
 
 def _dummy_handler(*args):
 	pass



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