From 830ce1bef1ea878e5ecbea47c37fb3b0475652e3 Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Wed, 26 Jun 2019 17:09:08 +0200 Subject: [PATCH] Throw exceptions outside critical OpenMP region --- src/support/ctool.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------ 1 file changed, 69 insertions(+), 42 deletions(-) diff --git a/src/support/ctool.cpp b/src/support/ctool.cpp index 8b8b6cc..4444c8e 100755 --- a/src/support/ctool.cpp +++ b/src/support/ctool.cpp @@ -586,6 +586,9 @@ GEbounds ctool::create_ebounds(void) // Get filename GFilename ebinfile = (*this)["ebinfile"].filename(); + // Initialise exception message string + std::string msg; + // If no extension name was provided then use default extension names if (!ebinfile.has_extname()) { @@ -595,7 +598,9 @@ GEbounds ctool::create_ebounds(void) // Open energy boundary file using the EBOUNDS or ENERGYBINS // extension or energy values using the ENERGIES extension. - // Throw an exception if opening fails. + // If opening fails then set exception message. The + // exception is thrown later outside the critical OpenMP + // block. GFits file(ebinfile.url()); if (file.contains(gammalib::extname_ebounds)) { file.close(); @@ -612,13 +617,12 @@ GEbounds ctool::create_ebounds(void) } else { file.close(); - std::string msg = "No extension with name \""+ - gammalib::extname_ebounds+"\", " - "\"ENERGYBINS\" or \""+ - gammalib::extname_energies+"\" found in FITS " - "file \""+ebinfile+"\". Please specify a " - "valid energy binning file."; - throw GException::invalid_value(G_CREATE_EBOUNDS, msg); + msg = "No extension with name \""+ + gammalib::extname_ebounds+"\", " + "\"ENERGYBINS\" or \""+ + gammalib::extname_energies+"\" found in FITS " + "file \""+ebinfile+"\". Please specify a " + "valid energy binning file."; } } // end: omp critical section @@ -636,34 +640,46 @@ GEbounds ctool::create_ebounds(void) // Open energy boundary file GFits file(ebinfile.url()); - // If FITS file does not contain requested extension then throw - // an exception + // If FITS file does not contain requested extension then set + // exception message. The exception is thrown later outside the + // critical OpenMP if (!file.contains(ebinfile.extname())) { - std::string msg = "No extension \""+ebinfile.extname()+"\" " - "found in energy binning file \""+ - ebinfile.url()+"\". Please provide a valid " - "extension name."; - throw GException::invalid_value(G_CREATE_EBOUNDS, msg); + msg = "No extension \""+ebinfile.extname()+"\" " + "found in energy binning file \""+ + ebinfile.url()+"\". Please provide a valid " + "extension name."; } - // Get table extension - GFitsTable& table = *file.table(ebinfile.extname()); - - // If table contains one column then load energies, otherwise load - // energy boundaries. - if (table.ncols() == 1) { - file.close(); - ebounds.set(GEnergies(ebinfile)); - } + // ... otherwise load energy boundaries else { - file.close(); - ebounds.load(ebinfile); - } + + // Get table extension + GFitsTable& table = *file.table(ebinfile.extname()); + + // If table contains one column then load energies, otherwise load + // energy boundaries. + if (table.ncols() == 1) { + file.close(); + ebounds.set(GEnergies(ebinfile)); + } + else { + file.close(); + ebounds.load(ebinfile); + } + + } // endelse: extension name was present in FITS file } // end: omp critical section } // endelse: loaded energy boundaries from table extension + // If we have an exception message then throw an exception now. We + // have to do this since we should not throw exceptions inside OpenMP + // critical blocks + if (!msg.empty()) { + throw GException::invalid_value(G_CREATE_EBOUNDS, msg); + } + } // endif: ebinalg was "FILE" // ... otherwise use a linear or a logarithmically-spaced energy binning @@ -730,6 +746,9 @@ GEnergies ctool::create_energies(void) // Get filename GFilename ebinfile = (*this)["ebinfile"].filename(); + // Initialise exception message string + std::string msg; + // If no extension name was provided then use default extension names if (!ebinfile.has_extname()) { @@ -739,7 +758,9 @@ GEnergies ctool::create_energies(void) // Open energy boundary file using the EBOUNDS or ENERGYBINS // extension or energy values using the ENERGIES extension. - // Throw an exception if opening fails. + // If opening fails then set exception message. The + // exception is thrown later outside the critical OpenMP + // block. GFits file(ebinfile.url()); if (file.contains(gammalib::extname_energies)) { file.close(); @@ -756,13 +777,12 @@ GEnergies ctool::create_energies(void) } else { file.close(); - std::string msg = "No extension with name \""+ - gammalib::extname_energies+"\", " - "\"ENERGYBINS\" or \""+ - gammalib::extname_ebounds+"\" found in FITS " - "file \""+ebinfile+"\". Please specify a " - "valid energy binning file."; - throw GException::invalid_value(G_CREATE_ENERGIES, msg); + msg = "No extension with name \""+ + gammalib::extname_energies+"\", " + "\"ENERGYBINS\" or \""+ + gammalib::extname_ebounds+"\" found in FITS " + "file \""+ebinfile+"\". Please specify a " + "valid energy binning file."; } } // end: omp critical section @@ -780,14 +800,14 @@ GEnergies ctool::create_energies(void) // Open energy boundary file GFits file(ebinfile.url()); - // If FITS file does not contain requested extension then throw - // an exception + // If FITS file does not contain requested extension then set + // exception message. The exception is thrown later outside the + // critical OpenMP if (!file.contains(ebinfile.extname())) { - std::string msg = "No extension \""+ebinfile.extname()+"\" " - "found in energy node file \""+ - ebinfile.url()+"\". Please provide a valid " - "extension name."; - throw GException::invalid_value(G_CREATE_ENERGIES, msg); + msg = "No extension \""+ebinfile.extname()+"\" " + "found in energy node file \""+ + ebinfile.url()+"\". Please provide a valid " + "extension name."; } // Get table extension @@ -808,6 +828,13 @@ GEnergies ctool::create_energies(void) } // endelse: loaded energy boundaries from table extension + // If we have an exception message then throw an exception now. We + // have to do this since we should not throw exceptions inside OpenMP + // critical blocks + if (!msg.empty()) { + throw GException::invalid_value(G_CREATE_ENERGIES, msg); + } + } // endif: ebinalg was "FILE" // ... otherwise, if energy binning algorithm is of type "POW" (case -- libgit2 0.21.4