Commit 830ce1bef1ea878e5ecbea47c37fb3b0475652e3

Authored by Jürgen Knödlseder
1 parent a2c378d3

Throw exceptions outside critical OpenMP region

Showing 1 changed file with 69 additions and 42 deletions
src/support/ctool.cpp
@@ -586,6 +586,9 @@ GEbounds ctool::create_ebounds(void) @@ -586,6 +586,9 @@ GEbounds ctool::create_ebounds(void)
586 // Get filename 586 // Get filename
587 GFilename ebinfile = (*this)["ebinfile"].filename(); 587 GFilename ebinfile = (*this)["ebinfile"].filename();
588 588
  589 + // Initialise exception message string
  590 + std::string msg;
  591 +
589 // If no extension name was provided then use default extension names 592 // If no extension name was provided then use default extension names
590 if (!ebinfile.has_extname()) { 593 if (!ebinfile.has_extname()) {
591 594
@@ -595,7 +598,9 @@ GEbounds ctool::create_ebounds(void) @@ -595,7 +598,9 @@ GEbounds ctool::create_ebounds(void)
595 598
596 // Open energy boundary file using the EBOUNDS or ENERGYBINS 599 // Open energy boundary file using the EBOUNDS or ENERGYBINS
597 // extension or energy values using the ENERGIES extension. 600 // extension or energy values using the ENERGIES extension.
598 - // Throw an exception if opening fails. 601 + // If opening fails then set exception message. The
  602 + // exception is thrown later outside the critical OpenMP
  603 + // block.
599 GFits file(ebinfile.url()); 604 GFits file(ebinfile.url());
600 if (file.contains(gammalib::extname_ebounds)) { 605 if (file.contains(gammalib::extname_ebounds)) {
601 file.close(); 606 file.close();
@@ -612,13 +617,12 @@ GEbounds ctool::create_ebounds(void) @@ -612,13 +617,12 @@ GEbounds ctool::create_ebounds(void)
612 } 617 }
613 else { 618 else {
614 file.close(); 619 file.close();
615 - std::string msg = "No extension with name \""+  
616 - gammalib::extname_ebounds+"\", "  
617 - "\"ENERGYBINS\" or \""+  
618 - gammalib::extname_energies+"\" found in FITS "  
619 - "file \""+ebinfile+"\". Please specify a "  
620 - "valid energy binning file.";  
621 - throw GException::invalid_value(G_CREATE_EBOUNDS, msg); 620 + msg = "No extension with name \""+
  621 + gammalib::extname_ebounds+"\", "
  622 + "\"ENERGYBINS\" or \""+
  623 + gammalib::extname_energies+"\" found in FITS "
  624 + "file \""+ebinfile+"\". Please specify a "
  625 + "valid energy binning file.";
622 } 626 }
623 627
624 } // end: omp critical section 628 } // end: omp critical section
@@ -636,34 +640,46 @@ GEbounds ctool::create_ebounds(void) @@ -636,34 +640,46 @@ GEbounds ctool::create_ebounds(void)
636 // Open energy boundary file 640 // Open energy boundary file
637 GFits file(ebinfile.url()); 641 GFits file(ebinfile.url());
638 642
639 - // If FITS file does not contain requested extension then throw  
640 - // an exception 643 + // If FITS file does not contain requested extension then set
  644 + // exception message. The exception is thrown later outside the
  645 + // critical OpenMP
641 if (!file.contains(ebinfile.extname())) { 646 if (!file.contains(ebinfile.extname())) {
642 - std::string msg = "No extension \""+ebinfile.extname()+"\" "  
643 - "found in energy binning file \""+  
644 - ebinfile.url()+"\". Please provide a valid "  
645 - "extension name.";  
646 - throw GException::invalid_value(G_CREATE_EBOUNDS, msg); 647 + msg = "No extension \""+ebinfile.extname()+"\" "
  648 + "found in energy binning file \""+
  649 + ebinfile.url()+"\". Please provide a valid "
  650 + "extension name.";
647 } 651 }
648 652
649 - // Get table extension  
650 - GFitsTable& table = *file.table(ebinfile.extname());  
651 -  
652 - // If table contains one column then load energies, otherwise load  
653 - // energy boundaries.  
654 - if (table.ncols() == 1) {  
655 - file.close();  
656 - ebounds.set(GEnergies(ebinfile));  
657 - } 653 + // ... otherwise load energy boundaries
658 else { 654 else {
659 - file.close();  
660 - ebounds.load(ebinfile);  
661 - } 655 +
  656 + // Get table extension
  657 + GFitsTable& table = *file.table(ebinfile.extname());
  658 +
  659 + // If table contains one column then load energies, otherwise load
  660 + // energy boundaries.
  661 + if (table.ncols() == 1) {
  662 + file.close();
  663 + ebounds.set(GEnergies(ebinfile));
  664 + }
  665 + else {
  666 + file.close();
  667 + ebounds.load(ebinfile);
  668 + }
  669 +
  670 + } // endelse: extension name was present in FITS file
662 671
663 } // end: omp critical section 672 } // end: omp critical section
664 673
665 } // endelse: loaded energy boundaries from table extension 674 } // endelse: loaded energy boundaries from table extension
666 675
  676 + // If we have an exception message then throw an exception now. We
  677 + // have to do this since we should not throw exceptions inside OpenMP
  678 + // critical blocks
  679 + if (!msg.empty()) {
  680 + throw GException::invalid_value(G_CREATE_EBOUNDS, msg);
  681 + }
  682 +
667 } // endif: ebinalg was "FILE" 683 } // endif: ebinalg was "FILE"
668 684
669 // ... otherwise use a linear or a logarithmically-spaced energy binning 685 // ... otherwise use a linear or a logarithmically-spaced energy binning
@@ -730,6 +746,9 @@ GEnergies ctool::create_energies(void) @@ -730,6 +746,9 @@ GEnergies ctool::create_energies(void)
730 // Get filename 746 // Get filename
731 GFilename ebinfile = (*this)["ebinfile"].filename(); 747 GFilename ebinfile = (*this)["ebinfile"].filename();
732 748
  749 + // Initialise exception message string
  750 + std::string msg;
  751 +
733 // If no extension name was provided then use default extension names 752 // If no extension name was provided then use default extension names
734 if (!ebinfile.has_extname()) { 753 if (!ebinfile.has_extname()) {
735 754
@@ -739,7 +758,9 @@ GEnergies ctool::create_energies(void) @@ -739,7 +758,9 @@ GEnergies ctool::create_energies(void)
739 758
740 // Open energy boundary file using the EBOUNDS or ENERGYBINS 759 // Open energy boundary file using the EBOUNDS or ENERGYBINS
741 // extension or energy values using the ENERGIES extension. 760 // extension or energy values using the ENERGIES extension.
742 - // Throw an exception if opening fails. 761 + // If opening fails then set exception message. The
  762 + // exception is thrown later outside the critical OpenMP
  763 + // block.
743 GFits file(ebinfile.url()); 764 GFits file(ebinfile.url());
744 if (file.contains(gammalib::extname_energies)) { 765 if (file.contains(gammalib::extname_energies)) {
745 file.close(); 766 file.close();
@@ -756,13 +777,12 @@ GEnergies ctool::create_energies(void) @@ -756,13 +777,12 @@ GEnergies ctool::create_energies(void)
756 } 777 }
757 else { 778 else {
758 file.close(); 779 file.close();
759 - std::string msg = "No extension with name \""+  
760 - gammalib::extname_energies+"\", "  
761 - "\"ENERGYBINS\" or \""+  
762 - gammalib::extname_ebounds+"\" found in FITS "  
763 - "file \""+ebinfile+"\". Please specify a "  
764 - "valid energy binning file.";  
765 - throw GException::invalid_value(G_CREATE_ENERGIES, msg); 780 + msg = "No extension with name \""+
  781 + gammalib::extname_energies+"\", "
  782 + "\"ENERGYBINS\" or \""+
  783 + gammalib::extname_ebounds+"\" found in FITS "
  784 + "file \""+ebinfile+"\". Please specify a "
  785 + "valid energy binning file.";
766 } 786 }
767 787
768 } // end: omp critical section 788 } // end: omp critical section
@@ -780,14 +800,14 @@ GEnergies ctool::create_energies(void) @@ -780,14 +800,14 @@ GEnergies ctool::create_energies(void)
780 // Open energy boundary file 800 // Open energy boundary file
781 GFits file(ebinfile.url()); 801 GFits file(ebinfile.url());
782 802
783 - // If FITS file does not contain requested extension then throw  
784 - // an exception 803 + // If FITS file does not contain requested extension then set
  804 + // exception message. The exception is thrown later outside the
  805 + // critical OpenMP
785 if (!file.contains(ebinfile.extname())) { 806 if (!file.contains(ebinfile.extname())) {
786 - std::string msg = "No extension \""+ebinfile.extname()+"\" "  
787 - "found in energy node file \""+  
788 - ebinfile.url()+"\". Please provide a valid "  
789 - "extension name.";  
790 - throw GException::invalid_value(G_CREATE_ENERGIES, msg); 807 + msg = "No extension \""+ebinfile.extname()+"\" "
  808 + "found in energy node file \""+
  809 + ebinfile.url()+"\". Please provide a valid "
  810 + "extension name.";
791 } 811 }
792 812
793 // Get table extension 813 // Get table extension
@@ -808,6 +828,13 @@ GEnergies ctool::create_energies(void) @@ -808,6 +828,13 @@ GEnergies ctool::create_energies(void)
808 828
809 } // endelse: loaded energy boundaries from table extension 829 } // endelse: loaded energy boundaries from table extension
810 830
  831 + // If we have an exception message then throw an exception now. We
  832 + // have to do this since we should not throw exceptions inside OpenMP
  833 + // critical blocks
  834 + if (!msg.empty()) {
  835 + throw GException::invalid_value(G_CREATE_ENERGIES, msg);
  836 + }
  837 +
811 } // endif: ebinalg was "FILE" 838 } // endif: ebinalg was "FILE"
812 839
813 // ... otherwise, if energy binning algorithm is of type "POW" (case 840 // ... otherwise, if energy binning algorithm is of type "POW" (case