[rkward-cvs] SF.net SVN: rkward: [2269] branches/KDE4_port/rkward/rbackend

tfry at users.sourceforge.net tfry at users.sourceforge.net
Thu Nov 22 23:14:32 UTC 2007


Revision: 2269
          http://rkward.svn.sourceforge.net/rkward/?rev=2269&view=rev
Author:   tfry
Date:     2007-11-22 15:14:31 -0800 (Thu, 22 Nov 2007)

Log Message:
-----------
Refine SIGSEGV handling. Looking pretty good, now

Modified Paths:
--------------
    branches/KDE4_port/rkward/rbackend/rembedinternal.cpp
    branches/KDE4_port/rkward/rbackend/rksignalsupport.cpp
    branches/KDE4_port/rkward/rbackend/rthread.cpp

Modified: branches/KDE4_port/rkward/rbackend/rembedinternal.cpp
===================================================================
--- branches/KDE4_port/rkward/rbackend/rembedinternal.cpp	2007-11-22 22:19:42 UTC (rev 2268)
+++ branches/KDE4_port/rkward/rbackend/rembedinternal.cpp	2007-11-22 23:14:31 UTC (rev 2269)
@@ -148,6 +148,7 @@
 	args.chars_a = &message;
 	REmbedInternal::this_pointer->handleStandardCallback (&args);
 	REmbedInternal::this_pointer->shutdown (true);
+	Rf_error ("Backend dead");	// this jumps us out of the REPL.
 }
 
 void RShowMessage (char* message) {
@@ -254,16 +255,16 @@
 		if(saveact == SA_DEFAULT) saveact = SA_SAVE;
 		if (saveact == SA_SAVE) {
 				if (RunLast) R_dot_Last ();
-				if( R_DirtyImage) R_SaveGlobalEnv ();
+				if (R_DirtyImage) R_SaveGlobalEnv ();
 		} else {
 				if (RunLast) R_dot_Last ();
 		}
 
 		REmbedInternal::this_pointer->shutdown (false);
+	} else {
+		REmbedInternal::this_pointer->shutdown (true);
 	}
-	/*else {
-		we've already informed the user, and shut down the backend in RSuicide
-	}*/
+	Rf_error ("Backend dead");	// this jumps us out of the REPL.
 }
 
 int RShowFiles (int nfile, char **file, char **headers, char *wtitle, Rboolean del, char *pager) {
@@ -395,7 +396,8 @@
 void REmbedInternal::shutdown (bool suicidal) {
 	RK_TRACE (RBACKEND);
 
-	if (!REmbedInternal::this_pointer->r_running) return;		// already shut down
+	if (!r_running) return;		// already shut down
+	r_running = false;
 
 // Code-recipe below essentially copied from http://stat.ethz.ch/R-manual/R-devel/doc/manual/R-exts.html#Linking-GUIs-and-other-front_ends-to-R
 // modified quite a bit for our needs.
@@ -420,8 +422,6 @@
 	/* close all the graphics devices */
 	if (!suicidal) KillAllDevices ();
 	fpu_setup ((Rboolean) FALSE);
-
-	REmbedInternal::this_pointer->r_running = false;
 }
 
 static int timeout_counter = 0;

Modified: branches/KDE4_port/rkward/rbackend/rksignalsupport.cpp
===================================================================
--- branches/KDE4_port/rkward/rbackend/rksignalsupport.cpp	2007-11-22 22:19:42 UTC (rev 2268)
+++ branches/KDE4_port/rkward/rbackend/rksignalsupport.cpp	2007-11-22 23:14:31 UTC (rev 2269)
@@ -28,27 +28,39 @@
 #endif
 
 namespace RKSignalSupportPrivate {
-	__sighandler_t r_sigsegv_handler = 0;
-	__sighandler_t default_sigsegv_handler = 0;
+	struct sigaction r_sigsegv_action;
+	struct sigaction default_sigsegv_action;
 
-	void sigsegv_proxy (int signum) {
+/*	__sighandler_t r_sigsegv_handler = 0;
+	__sighandler_t default_sigsegv_handler = 0; */
+
+	void sigsegv_proxy (int signum, siginfo_t *info, void *context) {
 		RK_ASSERT (signum == SIGSEGV);
 	
 		// if we are not in the R thread, handling the signal in R does more harm than good.
 		if (RInterface::inRThread ()) {
-			if (r_sigsegv_handler) {
-				r_sigsegv_handler (signum);
+			if (r_sigsegv_action.sa_sigaction) {
+				r_sigsegv_action.sa_sigaction (signum, info, context);
 				return;
+			} else if (r_sigsegv_action.sa_handler) {
+				r_sigsegv_action.sa_handler (signum);
+				return;
 			}
 		}
 	
-		// this might be a Qt/KDE override
-		if (default_sigsegv_handler) {
-			default_sigsegv_handler (signum);
+		// this might be a Qt/KDE override or default handling
+		if (default_sigsegv_action.sa_sigaction) {
+			default_sigsegv_action.sa_sigaction (signum, info, context);
 			return;
+		} else if (default_sigsegv_action.sa_handler) {
+			default_sigsegv_action.sa_handler (signum);
+			return;
 		}
-	
-		// do the default handling
+
+		// not handled? should not happen
+		RK_ASSERT (false);
+
+		// do the default fallback handling
 		signal (SIGSEGV, SIG_DFL);
 		raise (SIGSEGV);
 	}
@@ -57,11 +69,23 @@
 void RKSignalSupport::saveDefaultSigSegvHandler () {
 	RK_TRACE (RBACKEND);
 
-	RKSignalSupportPrivate::default_sigsegv_handler = signal (SIGSEGV, SIG_DFL);
+	sigaction (SIGSEGV, 0, &RKSignalSupportPrivate::default_sigsegv_action);
+//	RKSignalSupportPrivate::default_sigsegv_handler = signal (SIGSEGV, SIG_DFL);
 }
 
 void RKSignalSupport::installSigSegvProxy () {
 	RK_TRACE (RBACKEND);
 
-	RKSignalSupportPrivate::r_sigsegv_handler = signal (SIGSEGV, &RKSignalSupportPrivate::sigsegv_proxy);
+	// retrieve R signal handler
+	sigaction (SIGSEGV, 0, &RKSignalSupportPrivate::r_sigsegv_action);
+
+	struct sigaction proxy_action;
+	proxy_action = RKSignalSupportPrivate::r_sigsegv_action;
+	proxy_action.sa_flags |= SA_SIGINFO;
+	proxy_action.sa_sigaction = &RKSignalSupportPrivate::sigsegv_proxy;
+
+	// set new proxy handler
+	sigaction (SIGSEGV, &proxy_action, 0);
+
+//	RKSignalSupportPrivate::r_sigsegv_handler = signal (SIGSEGV, &RKSignalSupportPrivate::sigsegv_proxy);
 }

Modified: branches/KDE4_port/rkward/rbackend/rthread.cpp
===================================================================
--- branches/KDE4_port/rkward/rbackend/rthread.cpp	2007-11-22 22:19:42 UTC (rev 2268)
+++ branches/KDE4_port/rkward/rbackend/rthread.cpp	2007-11-22 23:14:31 UTC (rev 2269)
@@ -461,9 +461,9 @@
 	while (!(*done)) {
 		msleep (10); // callback not done yet? Sleep for a while
 
-		if (!locked) {			// what's with that lock? If the current command is cancelled, while we're in this loop, we must not lock the mutex and/or call anything in R. We may get long-jumped out of the loop before we get a chance to unlock
+		if (!(locked || killed)) {			// what's with that lock? If the current command is cancelled, while we're in this loop, we must not lock the mutex and/or call anything in R. We may get long-jumped out of the loop before we get a chance to unlock
 			MUTEX_LOCK;
-			if (!locked) processX11Events ();
+			if (!(locked || killed)) processX11Events ();
 			MUTEX_UNLOCK;
 		}
 	}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list