From 7009949c96b52574750b58a5d41c5f976ddd0853 Mon Sep 17 00:00:00 2001 From: abn Date: Wed, 14 Oct 2015 16:24:42 +0200 Subject: [PATCH] New simpler test for GIL in paraview. --- test/standalone/CMakeLists.txt | 15 ++- test/standalone/{src => gui}/CMakeLists.txt | 0 test/standalone/{src => gui}/PLMainWindow.cxx | 0 test/standalone/{src => gui}/PLMainWindow.hxx | 0 test/standalone/{src => gui}/PLViewTab.cxx | 0 test/standalone/{src => gui}/PLViewTab.hxx | 0 .../{src => gui}/PVViewer_Behaviors.cxx | 0 .../{src => gui}/PVViewer_Behaviors.h | 0 .../standalone/{src => gui}/PVViewer_Core.cxx | 0 test/standalone/{src => gui}/PVViewer_Core.h | 0 .../{src => gui}/PVViewer_GUIElements.cxx | 0 .../{src => gui}/PVViewer_GUIElements.h | 0 test/standalone/{src => gui}/README.txt | 0 test/standalone/{src => gui}/main.cpp | 0 test/standalone/{src => gui}/ui/light_para.ui | 0 test/standalone/{src => gui}/ui/view_tab.ui | 0 .../{src => gui}/xml/ParaViewReaders.xml | 0 test/standalone/simple/CMakeLists.txt | 36 ++++++ .../simple/Container_init_python.cxx | 62 ++++++++++ .../simple/Container_init_python.hxx | 69 +++++++++++ test/standalone/simple/PyInterp.h | 64 ++++++++++ test/standalone/simple/PyInterp_Utils.h | 111 ++++++++++++++++++ test/standalone/simple/simple_gil.cxx | 61 ++++++++++ 23 files changed, 413 insertions(+), 5 deletions(-) rename test/standalone/{src => gui}/CMakeLists.txt (100%) rename test/standalone/{src => gui}/PLMainWindow.cxx (100%) rename test/standalone/{src => gui}/PLMainWindow.hxx (100%) rename test/standalone/{src => gui}/PLViewTab.cxx (100%) rename test/standalone/{src => gui}/PLViewTab.hxx (100%) rename test/standalone/{src => gui}/PVViewer_Behaviors.cxx (100%) rename test/standalone/{src => gui}/PVViewer_Behaviors.h (100%) rename test/standalone/{src => gui}/PVViewer_Core.cxx (100%) rename test/standalone/{src => gui}/PVViewer_Core.h (100%) rename test/standalone/{src => gui}/PVViewer_GUIElements.cxx (100%) rename test/standalone/{src => gui}/PVViewer_GUIElements.h (100%) rename test/standalone/{src => gui}/README.txt (100%) rename test/standalone/{src => gui}/main.cpp (100%) rename test/standalone/{src => gui}/ui/light_para.ui (100%) rename test/standalone/{src => gui}/ui/view_tab.ui (100%) rename test/standalone/{src => gui}/xml/ParaViewReaders.xml (100%) create mode 100644 test/standalone/simple/CMakeLists.txt create mode 100644 test/standalone/simple/Container_init_python.cxx create mode 100644 test/standalone/simple/Container_init_python.hxx create mode 100755 test/standalone/simple/PyInterp.h create mode 100644 test/standalone/simple/PyInterp_Utils.h create mode 100644 test/standalone/simple/simple_gil.cxx diff --git a/test/standalone/CMakeLists.txt b/test/standalone/CMakeLists.txt index f4e851b7..f8c18436 100644 --- a/test/standalone/CMakeLists.txt +++ b/test/standalone/CMakeLists.txt @@ -20,16 +20,21 @@ PROJECT(LightPARAVIS) CMAKE_MINIMUM_REQUIRED(VERSION 2.8.10) - SET(CMAKE_BUILD_TYPE "Debug") -FIND_PACKAGE(Qt4 REQUIRED) +OPTION(LIGHTPARAVIS_WITH_GUI "Build GUI test app" ON) +# Package detection +FIND_PACKAGE(Qt4 REQUIRED) LIST(APPEND CMAKE_PREFIX_PATH "$ENV{PARAVIEW_ROOT_DIR}") -FIND_PACKAGE(ParaView 4.3 REQUIRED) +FIND_PACKAGE(ParaView REQUIRED) INCLUDE(${PARAVIEW_USE_FILE}) INCLUDE(ParaViewMacros) +SET(CMAKE_INCLUDE_CURRENT_DIR ON) -# Main application -ADD_SUBDIRECTORY(src) +# Main applications +IF(LIGHTPARAVIS_WITH_GUI) + ADD_SUBDIRECTORY(gui) +ENDIF() +ADD_SUBDIRECTORY(simple) diff --git a/test/standalone/src/CMakeLists.txt b/test/standalone/gui/CMakeLists.txt similarity index 100% rename from test/standalone/src/CMakeLists.txt rename to test/standalone/gui/CMakeLists.txt diff --git a/test/standalone/src/PLMainWindow.cxx b/test/standalone/gui/PLMainWindow.cxx similarity index 100% rename from test/standalone/src/PLMainWindow.cxx rename to test/standalone/gui/PLMainWindow.cxx diff --git a/test/standalone/src/PLMainWindow.hxx b/test/standalone/gui/PLMainWindow.hxx similarity index 100% rename from test/standalone/src/PLMainWindow.hxx rename to test/standalone/gui/PLMainWindow.hxx diff --git a/test/standalone/src/PLViewTab.cxx b/test/standalone/gui/PLViewTab.cxx similarity index 100% rename from test/standalone/src/PLViewTab.cxx rename to test/standalone/gui/PLViewTab.cxx diff --git a/test/standalone/src/PLViewTab.hxx b/test/standalone/gui/PLViewTab.hxx similarity index 100% rename from test/standalone/src/PLViewTab.hxx rename to test/standalone/gui/PLViewTab.hxx diff --git a/test/standalone/src/PVViewer_Behaviors.cxx b/test/standalone/gui/PVViewer_Behaviors.cxx similarity index 100% rename from test/standalone/src/PVViewer_Behaviors.cxx rename to test/standalone/gui/PVViewer_Behaviors.cxx diff --git a/test/standalone/src/PVViewer_Behaviors.h b/test/standalone/gui/PVViewer_Behaviors.h similarity index 100% rename from test/standalone/src/PVViewer_Behaviors.h rename to test/standalone/gui/PVViewer_Behaviors.h diff --git a/test/standalone/src/PVViewer_Core.cxx b/test/standalone/gui/PVViewer_Core.cxx similarity index 100% rename from test/standalone/src/PVViewer_Core.cxx rename to test/standalone/gui/PVViewer_Core.cxx diff --git a/test/standalone/src/PVViewer_Core.h b/test/standalone/gui/PVViewer_Core.h similarity index 100% rename from test/standalone/src/PVViewer_Core.h rename to test/standalone/gui/PVViewer_Core.h diff --git a/test/standalone/src/PVViewer_GUIElements.cxx b/test/standalone/gui/PVViewer_GUIElements.cxx similarity index 100% rename from test/standalone/src/PVViewer_GUIElements.cxx rename to test/standalone/gui/PVViewer_GUIElements.cxx diff --git a/test/standalone/src/PVViewer_GUIElements.h b/test/standalone/gui/PVViewer_GUIElements.h similarity index 100% rename from test/standalone/src/PVViewer_GUIElements.h rename to test/standalone/gui/PVViewer_GUIElements.h diff --git a/test/standalone/src/README.txt b/test/standalone/gui/README.txt similarity index 100% rename from test/standalone/src/README.txt rename to test/standalone/gui/README.txt diff --git a/test/standalone/src/main.cpp b/test/standalone/gui/main.cpp similarity index 100% rename from test/standalone/src/main.cpp rename to test/standalone/gui/main.cpp diff --git a/test/standalone/src/ui/light_para.ui b/test/standalone/gui/ui/light_para.ui similarity index 100% rename from test/standalone/src/ui/light_para.ui rename to test/standalone/gui/ui/light_para.ui diff --git a/test/standalone/src/ui/view_tab.ui b/test/standalone/gui/ui/view_tab.ui similarity index 100% rename from test/standalone/src/ui/view_tab.ui rename to test/standalone/gui/ui/view_tab.ui diff --git a/test/standalone/src/xml/ParaViewReaders.xml b/test/standalone/gui/xml/ParaViewReaders.xml similarity index 100% rename from test/standalone/src/xml/ParaViewReaders.xml rename to test/standalone/gui/xml/ParaViewReaders.xml diff --git a/test/standalone/simple/CMakeLists.txt b/test/standalone/simple/CMakeLists.txt new file mode 100644 index 00000000..3ae3cecb --- /dev/null +++ b/test/standalone/simple/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (C) 2010-2015 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author: Adrien Bruneton (CEA) + +SET(pl_SOURCES + simple_gil.cxx + #PyInterp_Interp.cxx + #SUITApp_init_python.cxx + Container_init_python.cxx + ) + +INCLUDE_DIRECTORIES( + ${PARAVIEW_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIRS} + ${QT_INCLUDE_DIRS} + ) + +ADD_EXECUTABLE(paraCmdLine ${pl_SOURCES}) +TARGET_LINK_LIBRARIES(paraCmdLine ${PYTHON_LIBRARIES} ${QT_LIBRARIES} pqApplicationComponents) + diff --git a/test/standalone/simple/Container_init_python.cxx b/test/standalone/simple/Container_init_python.cxx new file mode 100644 index 00000000..ed720f1b --- /dev/null +++ b/test/standalone/simple/Container_init_python.cxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SALOME Container : implementation of container and engine for Kernel +// File : Container_init_python.cxx +// Author : Paul RASCLE, EDF +// Module : KERNEL +// $Header$ +// +#include +#ifndef WIN32 + #include +#endif +#include + +//#include "utilities.h" +#define MESSAGE(a) + +#include "Container_init_python.hxx" + +void KERNEL_PYTHON::init_python(int argc, char **argv) +{ + if (Py_IsInitialized()) + { + MESSAGE("Python already initialized"); + return; + } + MESSAGE("================================================================="); + MESSAGE("Python Initialization..."); + MESSAGE("================================================================="); + // set stdout to line buffering (aka C++ std::cout) + setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); + char* salome_python=getenv("SALOME_PYTHON"); + if(salome_python != 0) + Py_SetProgramName(salome_python); + Py_Initialize(); // Initialize the interpreter + PySys_SetArgv(argc, argv); + PyRun_SimpleString("import threading\n"); + PyEval_InitThreads(); // Create (and acquire) the interpreter lock + PyThreadState *pts = PyGILState_GetThisThreadState(); + PyEval_ReleaseThread(pts); +} + diff --git a/test/standalone/simple/Container_init_python.hxx b/test/standalone/simple/Container_init_python.hxx new file mode 100644 index 00000000..f1f02fee --- /dev/null +++ b/test/standalone/simple/Container_init_python.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SALOME Container : implementation of container and engine for Kernel +// File : Container_init_python.hxx +// Author : Paul RASCLE, EDF +// Module : KERNEL +// $Header$ +// +#ifndef _CONTAINER_INIT_PYTHON_HXX_ +#define _CONTAINER_INIT_PYTHON_HXX_ + +//#include "SALOME_Container.hxx" +//#include + +#include // must be before Python.h ! + +#ifdef _XOPEN_SOURCE +#undef _XOPEN_SOURCE +#endif +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif +#include + + +// next two MACRO must be used together only once inside a block +// ------------------------------------------------------------- +// protect a sequence of Python calls: +// - Python lock must be acquired for these calls +// - new Python thread state allows multi thread use of the sequence: +// - Python may release the lock within the sequence, so multiple +// thread execution of the sequence may occur. +// - For that case, each sequence call must use a specific Python +// thread state. +// - There is no need of C Lock protection of the sequence. + + +#define Py_ACQUIRE_NEW_THREAD \ + PyGILState_STATE gil_state = PyGILState_Ensure(); + +#define Py_RELEASE_NEW_THREAD \ + PyGILState_Release(gil_state); + +struct KERNEL_PYTHON +{ + static void init_python(int argc, char **argv); +}; + +#endif diff --git a/test/standalone/simple/PyInterp.h b/test/standalone/simple/PyInterp.h new file mode 100755 index 00000000..5bfedf34 --- /dev/null +++ b/test/standalone/simple/PyInterp.h @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : PyInterp.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// +#if !defined ( PYINTERP_H ) +#define PYINTERP_H + +// ======================================================== +// set dllexport type for Win platform +#ifdef WIN32 +# if defined PYINTERP_EXPORTS || defined PyInterp_EXPORTS +# define PYINTERP_EXPORT __declspec(dllexport) +# else +# define PYINTERP_EXPORT __declspec(dllimport) +# endif +#else // WIN32 +# define PYINTERP_EXPORT +#endif // WIN32 + +// ======================================================== +// little trick - if we do not have debug python libraries +#ifdef _DEBUG + #ifndef HAVE_DEBUG_PYTHON + #undef _DEBUG + #endif +#endif + +#include + +#ifdef _DEBUG + #ifndef HAVE_DEBUG_PYTHON + #define _DEBUG + #endif +#endif + +// ======================================================== +// avoid warning messages +#ifdef WIN32 +#pragma warning (disable : 4786) +#pragma warning (disable : 4251) +#endif + +#endif // PYINTERP_H diff --git a/test/standalone/simple/PyInterp_Utils.h b/test/standalone/simple/PyInterp_Utils.h new file mode 100644 index 00000000..31bbd9f1 --- /dev/null +++ b/test/standalone/simple/PyInterp_Utils.h @@ -0,0 +1,111 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Adrien BRUNETON +// + +#ifndef PYINTERP_UTILS_H +#define PYINTERP_UTILS_H + +#include "PyInterp.h" +#include +#ifdef _DEBUG_ + #include +#endif + +/** + * \class PyLockWrapper + * \brief Python GIL wrapper. + * + * Utility class wrapping the Python GIL acquisition. This makes use of the high level + * API (PyGILState_Ensure and PyGILState_Release), and is hence compatible with only + * one running Python interpreter (no call to Py_NewInterpreter()). + * When the class is instanciated the lock is acquired. It is released at destruction time. + * Copy construction (and hence assignation) is forbidden. + */ +class PYINTERP_EXPORT PyLockWrapper +{ + +public: + /** + * \brief Constructor. Automatically acquires GIL. + */ + PyLockWrapper() + { + _gil_state = PyGILState_Ensure(); + // Save current thread state for later comparison + _state = PyGILState_GetThisThreadState(); + } + + /** + * \brief Destructor. Automatically releases GIL. + */ + ~PyLockWrapper() + { + PyThreadState* _currState = PyGILState_GetThisThreadState(); +#ifdef _DEBUG_ + if (_currState != _state) + { + std::cout << "!!!!!!!!! PyLockWrapper inconsistency - now entering infinite loop for debugging\n"; + while(1); + } +#endif + PyGILState_Release(_gil_state); + } + +private: + PyGILState_STATE _gil_state; + PyThreadState* _state; + + // "Rule of 3" - Forbid usage of copy operator and copy-constructor + PyLockWrapper(const PyLockWrapper & another); + const PyLockWrapper & operator=(const PyLockWrapper & another); +}; + + +/** + * \class PyObjWrapper + * \brief Utility class to properly handle the reference counting required on Python objects. + */ +class PYINTERP_EXPORT PyObjWrapper +{ + PyObject* myObject; +public: + PyObjWrapper(PyObject* theObject) : myObject(theObject) {} + PyObjWrapper() : myObject(0) {} + virtual ~PyObjWrapper() { Py_XDECREF(myObject); } + + operator PyObject*() { return myObject; } + PyObject* operator->() { return myObject; } + PyObject* get() { return myObject; } + bool operator!() { return !myObject; } + bool operator==(PyObject* theObject) { return myObject == theObject; } + PyObject** operator&() { return &myObject; } + PyObjWrapper& operator=(PyObjWrapper* theObjWrapper) + { + Py_XDECREF(myObject); + myObject = theObjWrapper->myObject; + return *this; + } +}; + +#endif + diff --git a/test/standalone/simple/simple_gil.cxx b/test/standalone/simple/simple_gil.cxx new file mode 100644 index 00000000..0fdc6cbe --- /dev/null +++ b/test/standalone/simple/simple_gil.cxx @@ -0,0 +1,61 @@ +// Copyright (C) 2010-2015 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Adrien Bruneton (CEA) +// +#include +#include +#include +#include "PyInterp_Utils.h" +#include "Container_init_python.hxx" + +#include + +int main(int argc, char ** argv) +{ + // Initialize Python in the way SALOME does: + KERNEL_PYTHON::init_python(argc,argv); + + // The below should always work (illustration of SALOME lock protection) + { + PyLockWrapper lock; // if commented, the below will crash: + + // Nothing important, just a bunch of calls to some Py* functions! + PyRun_SimpleString("import base64"); + PyObject * sysmod = PyImport_AddModule("sys"); + PyObject* sysdict = PyModule_GetDict(sysmod); + PyObject* tmp = PyDict_GetItemString(sysdict, "modules"); + } + std::cout << "Done with Py call" << std::endl; + + // Now the Qt part: + QApplication qtapp(argc, argv); + std::cout << "Done with Qt init" << std::endl; + + // And finally the ParaView part: + pqPVApplicationCore* myCoreApp = new pqPVApplicationCore (argc, argv); + std::cout << "Done with PV init" << std::endl; + // Make sure compilation of ParaView was made with Python support: + if (!myCoreApp->pythonManager()) + return -1; + delete myCoreApp; + + std::cout << "Done with PV deletion" << std::endl; + + return 0; +} -- 2.39.2