← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] Signal handlers for SINGLE_TOP and KICAD

 

And here is the patch with the class name in capitals and a class
comment block. Sorry!

On Wed, Jan 11, 2017 at 11:26 PM, John Beard <john.j.beard@xxxxxxxxx> wrote:
> Hi,
>
> None of the KiCad programs appear to implement any signal handlers.
> This means that some of them (e.g. pcbnew) don't respond to things
> like SIGINT generated by a Ctrl-C in the console its running from
> (very annoying when running up and down repeatedly), and others (e.g.
> eeschema) terminate immediately, rather than shutting down.
>
> The attached patch implements a graceful shutdown on SIGINT for all of
> the SINGLE_TOP programs as well as KICAD.
>
> I have put it in a separate class (static members because the handlers
> have to be that way), so that 1) the same handler can be used in both
> places and 2) in future if the signal handlers grow, any complexity is
> contained.
>
> I have tested this on Linux, and since it's using the standard C++
> <csignal> stuff, I assume it works (or at least compiles) on all
> platforms, but I can't prove it!
>
> Cheers,
>
> John
From 3923fc6e7e4e63c4853da9c906180e88c28ce04d Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Wed, 11 Jan 2017 22:48:57 +0800
Subject: [PATCH] Signal handlers for Kicad and Single-Top programs

This allows Kicad programs to be terminated with Ctrl-C (or SIGINT in
general) and still execute the correct shutodwn procedure. Previously,
Pcbnew wouldn't respond and eeschema would terminate immediately.

This is done in a new class with static functions, because C signal
handling only really works with static callbacks. This was done, rather
than just providing a single static function and wxApp pointer in
kicad.cpp and single_top.cpp, because this way allows for more code
reuse, and also hides future complexity if more signals are handled.
---
 common/CMakeLists.txt         |  1 +
 common/app_signal_handler.cpp | 56 +++++++++++++++++++++++++++++++
 common/single_top.cpp         |  4 +++
 include/app_signal_handler.h  | 77 +++++++++++++++++++++++++++++++++++++++++++
 kicad/kicad.cpp               |  6 +++-
 5 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 common/app_signal_handler.cpp
 create mode 100644 include/app_signal_handler.h

diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index ca460d2b4..134a01236 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -180,6 +180,7 @@ set( COMMON_SRCS
     ${COMMON_DLG_SRCS}
     ${COMMON_WIDGET_SRCS}
     ${COMMON_PAGE_LAYOUT_SRCS}
+    app_signal_handler.cpp
     base_struct.cpp
     basicframe.cpp
     bezier_curves.cpp
diff --git a/common/app_signal_handler.cpp b/common/app_signal_handler.cpp
new file mode 100644
index 000000000..bc91a90ad
--- /dev/null
+++ b/common/app_signal_handler.cpp
@@ -0,0 +1,56 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see CHANGELOG.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <app_signal_handler.h>
+
+#include <csignal>
+
+
+// Initialise static members
+wxApp* APP_SIGNAL_HANDLER::m_app = nullptr;
+
+
+void APP_SIGNAL_HANDLER::SetSignalledApp( wxApp* app )
+{
+    m_app = app;
+}
+
+
+void APP_SIGNAL_HANDLER::RegisterSignalHandler( int sig,
+        SigHandler handler )
+{
+    signal( sig, handler );
+}
+
+
+void APP_SIGNAL_HANDLER::FatalSignalHandler( int    /*sig*/ )
+{
+    if( m_app )
+    {
+        m_app->ExitMainLoop();
+    }
+    else
+    {
+        exit( 1 );
+    }
+}
diff --git a/common/single_top.cpp b/common/single_top.cpp
index 38ed55f89..8a4ca9eca 100644
--- a/common/single_top.cpp
+++ b/common/single_top.cpp
@@ -45,6 +45,7 @@
 #include <pgm_base.h>
 #include <kiway_player.h>
 #include <confirm.h>
+#include <app_signal_handler.h>
 
 
 // Only a single KIWAY is supported in this single_top top level component,
@@ -110,6 +111,9 @@ struct APP_SINGLE_TOP : public wxApp
 #if defined (__LINUX__)
     APP_SINGLE_TOP(): wxApp()
     {
+        // Register for signals
+        APP_SIGNAL_HANDLER::SetSignalledApp( this );
+        APP_SIGNAL_HANDLER::RegisterSignalHandler( SIGINT, APP_SIGNAL_HANDLER::FatalSignalHandler );
         // Disable proxy menu in Unity window manager. Only usual menubar works with wxWidgets (at least <= 3.1)
         // When the proxy menu menubar is enable, some important things for us do not work: menuitems UI events and shortcuts.
         wxString wm;
diff --git a/include/app_signal_handler.h b/include/app_signal_handler.h
new file mode 100644
index 000000000..ce2be16b6
--- /dev/null
+++ b/include/app_signal_handler.h
@@ -0,0 +1,77 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see CHANGELOG.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef APP_SIGNAL_HANDLER_H_
+#define APP_SIGNAL_HANDLER_H_
+
+#include <wx/app.h>
+
+/**
+ * Class APP_SIGNAL_HANDLER
+ *
+ * Contains functions for registering signal handlers to run against
+ * a wxApp instance.
+ *
+ * There can only be one of these per program, as the signal handler
+ * callbacks have to be static. You can still register for signals
+ * elesewhere if you do not want to handle them here.
+ *
+ * Also includes common signal handlers such as
+ * APP_SIGNAL_HANDLER::FatalSigalHandler,
+ * which can be used to register common actions against signals.
+ */
+class APP_SIGNAL_HANDLER
+{
+public:
+    /*!
+     * Function signature of a signal handler
+     */
+    typedef void ( * SigHandler )( int );
+
+    /*!
+     * Set the app that the signals will be directed to
+     */
+    static void SetSignalledApp( wxApp* app );
+
+    /*!
+     * Function registerSignalHandler
+     *
+     * Register a signal handler for a set of signals
+     *
+     * @param sig the signal number to registr against
+     * @param handler the handler to register for that signal
+     */
+    static void RegisterSignalHandler( int sig, SigHandler handler );
+
+    /*!
+     * Signal handler that gracefully shuts down the wxApp,
+     * or exits immediately if no app is set
+     */
+    static void FatalSignalHandler( int sig );
+
+private:
+
+    static wxApp* m_app;
+};
+
+#endif
diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp
index 8dc657fe2..7bef6e8b4 100644
--- a/kicad/kicad.cpp
+++ b/kicad/kicad.cpp
@@ -38,12 +38,12 @@
 #include <kiway.h>
 #include <richio.h>
 #include <wildcards_and_files_ext.h>
+#include <app_signal_handler.h>
 
 #include "pgm_kicad.h"
 
 #include "kicad.h"
 
-
 // a dummy to quiet linking with EDA_BASE_FRAME::config();
 #include <kiface_i.h>
 KIFACE_I& Kiface()
@@ -223,6 +223,10 @@ struct APP_KICAD : public wxApp
 #if defined (__LINUX__)
     APP_KICAD(): wxApp()
     {
+        // register for signals
+        APP_SIGNAL_HANDLER::SetSignalledApp( this );
+        APP_SIGNAL_HANDLER::RegisterSignalHandler( SIGINT, APP_SIGNAL_HANDLER::FatalSignalHandler );
+
         // Disable proxy menu in Unity window manager. Only usual menubar works with wxWidgets (at least <= 3.1)
         // When the proxy menu menubar is enable, some important things for us do not work: menuitems UI events and shortcuts.
         wxString wm;
-- 
2.11.0


Follow ups

References