[rkward-cvs] SF.net SVN: rkward:[3164] branches/2010_10_18_backend_restructuring_branch/ rkward/rbackend
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Sat Oct 30 11:01:19 UTC 2010
Revision: 3164
http://rkward.svn.sourceforge.net/rkward/?rev=3164&view=rev
Author: tfry
Date: 2010-10-30 11:01:19 +0000 (Sat, 30 Oct 2010)
Log Message:
-----------
Correctly detect interrupted commands
Modified Paths:
--------------
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.cpp
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.h
branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp 2010-10-28 19:32:08 UTC (rev 3163)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp 2010-10-30 11:01:19 UTC (rev 3164)
@@ -19,7 +19,7 @@
// static
RThread *RThread::this_pointer = 0;
-RThread::RKReplStatus RThread::repl_status = { QByteArray (), 0, true, 0, 0, RThread::RKReplStatus::NoUserCommand, 0, false };
+RThread::RKReplStatus RThread::repl_status = { QByteArray (), 0, true, 0, 0, RThread::RKReplStatus::NoUserCommand, 0, false, false };
void* RThread::default_global_context = 0;
#include <qstring.h>
@@ -75,26 +75,26 @@
#include <Rinternals.h>
#include <R_ext/Parse.h>
#include <Rembedded.h>
+#include <Rinterface.h>
#ifdef Q_WS_WIN
# include <R_ext/RStartup.h>
# include <R_ext/Utils.h>
- void RK_scheduleIntr () {
- UserBreak = 1;
- }
-
- void RK_doIntr () {
- RK_scheduleIntr ();
- R_CheckUserInterrupt ();
- }
-
structRstart RK_R_Params;
-#else
-# define RK_doIntr Rf_onintr
-# include <Rinterface.h>
#endif
+void RK_scheduleIntr () {
+ RThread::this_pointer->repl_status.interrupted = true;
+ RKSignalSupport::callOldSigIntHandler ();
+}
+
+void RK_doIntr () {
+ RK_scheduleIntr ();
+ RThread::this_pointer->repl_status.interrupted = true;
+ R_CheckUserInterrupt ();
+}
+
// some functions we need that are not declared
extern void Rf_PrintWarnings (void);
extern void run_Rmainloop (void);
@@ -671,15 +671,26 @@
RThread::repl_status.eval_depth--;
}
+extern int R_interrupts_pending;
SEXP doError (SEXP call) {
RK_TRACE (RBACKEND);
if ((RThread::this_pointer->repl_status.eval_depth == 0) && (!RThread::repl_status.in_browser_context) && (!RThread::this_pointer->killed)) {
RThread::this_pointer->repl_status.user_command_status = RThread::RKReplStatus::UserCommandFailed;
}
- QString string = RKRSupport::SEXPToString (call);
- RThread::this_pointer->handleOutput (string, string.length (), ROutput::Error);
- RK_DO (qDebug ("error '%s'", qPrintable (string)), RBACKEND, DL_DEBUG);
+ if (RThread::this_pointer->repl_status.interrupted) {
+ // it is unlikely, but possible, that an interrupt signal was received, but the current command failed for some other reason, before processing was acutally interrupted. In this case, R_interrupts_pending if not yet cleared.
+ // NOTE: if R_interrupts_pending stops being exported one day, we might be able to use R_CheckUserInterrupt() inside an R_ToplevelExec() to find out, whether an interrupt was still pending.
+ if (!R_interrupts_pending) {
+ RThread::this_pointer->repl_status.interrupted = false;
+ foreach (RCommandProxy *command, RThread::this_pointer->all_current_commands) command->status |= RCommand::Canceled;
+ RK_DO (qDebug ("interrupted"), RBACKEND, DL_DEBUG);
+ }
+ } else {
+ QString string = RKRSupport::SEXPToString (call);
+ RThread::this_pointer->handleOutput (string, string.length (), ROutput::Error);
+ RK_DO (qDebug ("error '%s'", qPrintable (string)), RBACKEND, DL_DEBUG);
+ }
return R_NilValue;
}
@@ -822,7 +833,8 @@
RKWard_RData_Tag = Rf_install ("RKWard_RData_Tag");
R_LastvalueSymbol = Rf_install (".Last.value");
- RKSignalSupport::installSignalProxies ();
+ RKSignalSupport::installSignalProxies (); // for the crash signals
+ RKSignalSupport::installSigIntAndUsrHandlers (RK_scheduleIntr);
// register our functions
R_CallMethodDef callMethods [] = {
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h 2010-10-28 19:32:08 UTC (rev 3163)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.h 2010-10-30 11:01:19 UTC (rev 3164)
@@ -195,6 +195,7 @@
/** The command currently being executed. */
RCommandProxy *current_command;
+ QList<RCommandProxy*> all_current_commands;
void runCommand (RCommandProxy *command);
@@ -230,6 +231,7 @@
} user_command_status;
int eval_depth; // Number (depth) of non-user commands currently running. User commands can only run at depth 0
bool in_browser_context;
+ bool interrupted;
};
static RKReplStatus repl_status;
/** holds a copy of the default R_GlobalContext. Needed to find out, when a browser context has been left. */
@@ -263,7 +265,6 @@
QStringList global_env_toplevel_names;
/** check wether the object list / global environment / individual symbols have changed, and updates them, if needed */
void checkObjectUpdatesNeeded (bool check_list);
- QList<RCommandProxy*> all_current_commands;
/** current output */
ROutputList output_buffer;
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.cpp 2010-10-28 19:32:08 UTC (rev 3163)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.cpp 2010-10-30 11:01:19 UTC (rev 3164)
@@ -23,10 +23,8 @@
#include "../debug.h"
-#ifdef Q_WS_WIN
-# ifndef __sighandler_t
- typedef void (*__sighandler_t) (int);
-# endif
+#ifndef __sighandler_t
+ typedef void (*__sighandler_t) (int);
#endif
namespace RKSignalSupportPrivate {
@@ -45,6 +43,12 @@
struct sigaction r_sigabrt_handler;
struct sigaction default_sigabrt_handler;
#endif
+ __sighandler_t r_sigint_handler = 0;
+ void (*new_sigint_handler) (void) = 0;
+ void internal_sigint_handler (int num) {
+ new_sigint_handler ();
+ signal (num, internal_sigint_handler);
+ }
#ifdef Q_WS_WIN
void signal_proxy (int signum) {
@@ -153,3 +157,20 @@
sigaction (SIGABRT, &proxy_action, 0);
#endif
}
+
+void RKSignalSupport::installSigIntAndUsrHandlers (void (*handler) (void)) {
+ RK_TRACE (RBACKEND);
+
+ RK_ASSERT (!RKSignalSupportPrivate::r_sigint_handler);
+ RKSignalSupportPrivate::new_sigint_handler = handler;
+ RKSignalSupportPrivate::r_sigint_handler = signal (SIGINT, &RKSignalSupportPrivate::internal_sigint_handler);
+ // default action in R: save and quit. We use these as a proxy for SIGINT, instead.
+ signal (SIGUSR1, &RKSignalSupportPrivate::internal_sigint_handler);
+ signal (SIGUSR2, &RKSignalSupportPrivate::internal_sigint_handler);
+}
+
+void RKSignalSupport::callOldSigIntHandler () {
+ RK_TRACE (RBACKEND);
+
+ RKSignalSupportPrivate::r_sigint_handler (SIGINT);
+}
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.h 2010-10-28 19:32:08 UTC (rev 3163)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rksignalsupport.h 2010-10-30 11:01:19 UTC (rev 3164)
@@ -21,6 +21,9 @@
namespace RKSignalSupport {
void saveDefaultSignalHandlers ();
void installSignalProxies ();
+
+ void installSigIntAndUsrHandlers (void (*handler) (void));
+ void callOldSigIntHandler ();
};
#endif
Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp 2010-10-28 19:32:08 UTC (rev 3163)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rthread.cpp 2010-10-30 11:01:19 UTC (rev 3164)
@@ -48,7 +48,7 @@
#ifdef Q_WS_WIN
RK_scheduleIntr ();
#else
- pthread_kill ((pthread_t) thread_id, SIGINT);
+ pthread_kill ((pthread_t) thread_id, SIGUSR1); // relays to SIGINT
#endif
}
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