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 586 // Get filename
587 587 GFilename ebinfile = (*this)["ebinfile"].filename();
588 588  
  589 + // Initialise exception message string
  590 + std::string msg;
  591 +
589 592 // If no extension name was provided then use default extension names
590 593 if (!ebinfile.has_extname()) {
591 594  
... ... @@ -595,7 +598,9 @@ GEbounds ctool::create_ebounds(void)
595 598  
596 599 // Open energy boundary file using the EBOUNDS or ENERGYBINS
597 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 604 GFits file(ebinfile.url());
600 605 if (file.contains(gammalib::extname_ebounds)) {
601 606 file.close();
... ... @@ -612,13 +617,12 @@ GEbounds ctool::create_ebounds(void)
612 617 }
613 618 else {
614 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 628 } // end: omp critical section
... ... @@ -636,34 +640,46 @@ GEbounds ctool::create_ebounds(void)
636 640 // Open energy boundary file
637 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 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 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 672 } // end: omp critical section
664 673  
665 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 683 } // endif: ebinalg was "FILE"
668 684  
669 685 // ... otherwise use a linear or a logarithmically-spaced energy binning
... ... @@ -730,6 +746,9 @@ GEnergies ctool::create_energies(void)
730 746 // Get filename
731 747 GFilename ebinfile = (*this)["ebinfile"].filename();
732 748  
  749 + // Initialise exception message string
  750 + std::string msg;
  751 +
733 752 // If no extension name was provided then use default extension names
734 753 if (!ebinfile.has_extname()) {
735 754  
... ... @@ -739,7 +758,9 @@ GEnergies ctool::create_energies(void)
739 758  
740 759 // Open energy boundary file using the EBOUNDS or ENERGYBINS
741 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 764 GFits file(ebinfile.url());
744 765 if (file.contains(gammalib::extname_energies)) {
745 766 file.close();
... ... @@ -756,13 +777,12 @@ GEnergies ctool::create_energies(void)
756 777 }
757 778 else {
758 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 788 } // end: omp critical section
... ... @@ -780,14 +800,14 @@ GEnergies ctool::create_energies(void)
780 800 // Open energy boundary file
781 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 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 813 // Get table extension
... ... @@ -808,6 +828,13 @@ GEnergies ctool::create_energies(void)
808 828  
809 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 838 } // endif: ebinalg was "FILE"
812 839  
813 840 // ... otherwise, if energy binning algorithm is of type "POW" (case
... ...