ALMA Computing Group

acsexmplErrorComponentImpl.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 *    ALMA - Atacama Large Millimiter Array
00003 *    (c) Associated Universities Inc., 2002 *
00004 *    (c) European Southern Observatory, 2002
00005 *    Copyright by ESO (in the framework of the ALMA collaboration)
00006 *    and Cosylab 2002, All rights reserved
00007 *
00008 *    This library is free software; you can redistribute it and/or
00009 *    modify it under the terms of the GNU Lesser General Public
00010 *    License as published by the Free Software Foundation; either
00011 *    version 2.1 of the License, or (at your option) any later version.
00012 *
00013 *    This library is distributed in the hope that it will be useful,
00014 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 *    Lesser General Public License for more details.
00017 *
00018 *    You should have received a copy of the GNU Lesser General Public
00019 *    License along with this library; if not, write to the Free Software
00020 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00021 *
00022 *
00023 *
00024 * "@(#) $Id: acsexmplErrorComponentImpl.cpp,v 1.14 2010/11/10 16:58:09 rbourtem Exp $"
00025 *
00026 * who       when      what
00027 * --------  --------  ----------------------------------------------
00028 * david 2002-09-26 added many more comments
00029 * david  25/09/02  created 
00030 */
00031  
00032 #include <acsexmplErrorComponentImpl.h>
00033 #include <ACSErrTypeCommon.h>
00034 #include <ACSErrTypeOK.h>
00035 #include <iostream>
00036 
00037 ACE_RCSID(acsexmpl, acsexmplErrorComponentImpl, "$Id: acsexmplErrorComponentImpl.cpp,v 1.14 2010/11/10 16:58:09 rbourtem Exp $")
00038 
00039 /* ----------------------------------------------------------------*/
00040 ErrorComponent::ErrorComponent( 
00041                        const ACE_CString &name,
00042                        maci::ContainerServices * containerServices) :
00043     ACSComponentImpl(name, containerServices)
00044 {
00045     // ACS_TRACE is used for debugging purposes
00046     ACS_TRACE("::ErrorComponent::ErrorComponent");
00047 }
00048 /* ----------------------------------------------------------------*/
00049 ErrorComponent::~ErrorComponent()
00050 {
00051     // ACS_TRACE is used for debugging purposes
00052     ACS_TRACE("::ErrorComponent::~ErrorComponent");
00053     ACS_DEBUG_PARAM("::ErrorComponent::~ErrorComponent", "Destroying %s...", name());
00054 }
00055 /* --------------------- [ CORBA interface ] ----------------------*/
00056 void
00057 ErrorComponent::displayMessage ()
00058 {
00059     ACS_LOG(LM_RUNTIME_CONTEXT, "ErrorComponent::displayMessage",
00060             (LM_INFO, "Hello World"));
00061 }
00062 
00063 /* ----------------------------------------------------------------*/
00064 void 
00065 ErrorComponent::badMethod(CORBA::Short depth) 
00066 {
00067         ACS_TRACE("::ErrorComponent::badMethod");
00068         if(depth>=1){
00069             try
00070                 {
00071                         // We decrement the depth, because we are going to add one
00072                         // error here in any case.
00073                         buildErrorTrace(depth-1);
00074                 }
00075                 catch(ACSErrTypeCommon::GenericErrorExImpl &ex)
00076                 {
00077                         ACSErrTypeCommon::GenericErrorExImpl ex2(ex, 
00078                                         __FILE__, __LINE__, 
00079                                         "ErrorComponent::badMethod");
00080                         ex2.setErrorDesc("Generated multi level exception");
00081                         throw ex2.getGenericErrorEx();
00082                 }
00083                 catch(...)
00084                 {
00085                         ACSErrTypeCommon::UnexpectedExceptionExImpl ex2(__FILE__, __LINE__, 
00086                                         "ErrorComponent::badMethod");
00087                         throw ex2.getUnexpectedExceptionEx();
00088                 }
00089 
00090                 /*
00091                  * We should get here only if a depth<=1 was requested.
00092                  */
00093                 ACSErrTypeCommon::GenericErrorExImpl ex(__FILE__, __LINE__, 
00094                                 "ErrorComponent::badMethod");
00095                 ex.setErrorDesc("An error trace with depth lower or equal to 1 was requested.");
00096                 throw ex.getGenericErrorEx();
00097         }
00098 }
00099 
00100 
00101 void ErrorComponent::typeException(CORBA::Short depth) 
00102 {
00103     ACS_TRACE("::ErrorComponent::typeException");
00104     if(depth>=1){
00105             try
00106             {
00107                     // We decrement the depth, because we are going to add one
00108                     // error here in any case.
00109                     buildErrorTrace(depth-1);
00110             }
00111             catch(ACSErrTypeCommon::GenericErrorExImpl &ex)
00112             {
00113                     ACSErrTypeCommon::GenericErrorExImpl ex2(ex, 
00114                                     __FILE__, __LINE__, 
00115                                     "ErrorComponent::badMethod");
00116                     ex2.setErrorDesc("Generated multi level exception");
00117                     throw ex2.getACSErrTypeCommonEx();
00118             }
00119             catch(...)
00120             {
00121                     ACSErrTypeCommon::UnexpectedExceptionExImpl ex2(__FILE__, __LINE__, 
00122                                     "ErrorComponent::badMethod");
00123                     throw ex2.getUnexpectedExceptionEx();
00124             }
00125 
00126             /*
00127              * We should get here only if a depth<=1 was requested.
00128              */
00129             ACSErrTypeCommon::GenericErrorExImpl ex(__FILE__, __LINE__, 
00130                             "ErrorComponent::badMethod");
00131             ex.setErrorDesc("An error trace with depth lower or equal to 1 was requested.");
00132             throw ex.getACSErrTypeCommonEx();
00133     }
00134 }//typeException
00135 
00136 
00137 void ErrorComponent::corbaSystemException() 
00138 {
00139     throw CORBA::BAD_PARAM ( /* CORBA::OMGVMCID | */ 2, CORBA::COMPLETED_NO);;
00140 }
00141 
00142 /* ----------------------------------------------------------------*/
00143 ACSErr::Completion *ErrorComponent::completionFromException(CORBA::Short depth) 
00144 {
00145     ACS_TRACE("::ErrorComponent::completionFromException");
00146     // here we get LOCAL (C++) completion 
00147     CompletionImpl *er = createCompletion(depth);
00148 
00149     // returnCompletion() automatically deletes er
00150     //   NOTE: you can use returnCompletion() 
00151     //   just if completion is allocated on the heap. 
00152     //   If completion is allocated on the stack
00153     //   returnCompletion(false) has to be used. 
00154     return er->returnCompletion();
00155 }//completionFromException
00156 
00157         ACSErr::Completion *ErrorComponent::completionOnStack(CORBA::Short depth) 
00158 {
00159     ACS_TRACE("::ErrorComponent::completionOnStack");
00160 
00161     // here we get LOCAL (C++) completion 
00162     CompletionImpl *comp = createCompletion(depth);
00163     
00164 
00165     // if comp does not contain error (=is error free) we return it 
00166     // otherwise we create a new completion which takes the error trace from a completion comp.
00167     if (comp->isErrorFree())
00168         {
00169         // memory for comp is released in the call 
00170         return comp->returnCompletion();
00171         }
00172     else
00173         {
00174         // The constructor takes care for the memory manamgent 
00175         // for the passed completion or exception.
00176         // If a completion or an exception is passed as pointer the constructor assumes that
00177         // completion was created on the heap and thus it deletes it afterwards,
00178         // so it MUST NOT be deleted by the user !
00179         // If a completion or an exception is passed as an object (or reference to it) 
00180         // the constructor assumes that the it was created on the stack 
00181         // and thus it does not delete it.
00182         //
00183         // NOTE: do not pass a pointer of a completion or an exception 
00184         // which was created on the stack !! In this case just send the completion object.
00185         ACSErrTypeCommon::GenericErrorCompletion erg(comp, 
00186                                                      __FILE__, __LINE__, 
00187                                                      "ErrorComponent::completionOnStack");
00188         erg.setErrorDesc("Put an error trace in completionOnStack");
00189         return erg.returnCompletion(false); 
00190         // With false flag we tell returnCompletion() 
00191         // not to delete its object
00192         // since it is automatically deleted when we go out of scope
00193         }//if
00194 }//completionOnStack
00195 
00196 void  ErrorComponent::exceptionFromCompletion(CORBA::Short depth) 
00197 {
00198         ACS_TRACE("ErrorComponent::exceptionFromCompletion");
00199         if(depth==1){
00200                 ACSErrTypeCommon::GenericErrorExImpl ex2(
00201                                 __FILE__, __LINE__,
00202                                 "ErrorComponent::exceptionFromCompletion");
00203                 ex2.setErrorDesc("Exception with trace of depth 1 (not generated from a completion)");
00204                 throw ex2.getGenericErrorEx();
00205         }    
00206 
00207 
00208         CompletionImpl *comp = createCompletion(depth>0?depth-1:0);
00209         ACS_DEBUG("ErrorComponent::exceptionFromCompletion","first step");
00210         // if comp does not conatin error (=is error free) we just return 
00211         // otherwise we create a new exception which takes the error trace from a completion comp.     
00212         if (!comp->isErrorFree())
00213         {
00214                ACS_DEBUG("ErrorComponent::exceptionFromCompletion","second step");
00215 
00216                 // The constructor takes care for the memory manamgent 
00217                 // for the passed completion or exception.
00218                 // If a completion or an exception is passed as pointer the constructor assumes that
00219                 // completion was created on the heap and thus it deletes it afterwards,
00220                 // so it MUST NOT be deleted by the user !
00221                 // If a completion or an exception is passed as an object (or reference to it) 
00222                 // the constructor assumes that the it was created on the stack 
00223                 // and thus it does not delete it.
00224                 //
00225                 // NOTE: do not pass a pointer of a completion or an exception 
00226                 // which was created on the stack !! In this case just send the completion object.
00227                 ACSErrTypeCommon::GenericErrorExImpl ex2(comp, 
00228                                 __FILE__, __LINE__, 
00229                                 "ErrorComponent::exceptionFromCompletion");
00230                 ex2.setErrorDesc("Exception generated by adding an error trace from a completion");
00231                 throw ex2.getGenericErrorEx();
00232         }//if
00233 }
00234 
00235 ACSErr::Completion *ErrorComponent::completionFromCompletion(CORBA::Short depth) 
00236 {
00237         ACS_TRACE("ErrorComponent::completionFromCompletion");
00238         CompletionImpl *comp;
00239         if(depth==1){
00240                 ACSErrTypeCommon::GenericErrorCompletion *erg =
00241                         new ACSErrTypeCommon::GenericErrorCompletion(
00242                                         __FILE__, __LINE__,
00243                                         "ErrorComponent::completionFromCompletion");
00244                 erg->setErrorDesc("Put an error trace in completionFromCompletion(depth 1, so not generated from another completion)");
00245                 comp = erg;
00246 
00247 
00248         }
00249         else{
00250                 comp = createCompletion(depth>0?depth-1:0);
00251 
00252                 // if comp does not conatin error (=is error free) we return it 
00253                 // otherwise we create a new completion which takes the error trace from a completion comp.
00254                 if (!comp->isErrorFree())
00255                 {
00256                         // comp is deleted inside the constructor
00257                         ACSErrTypeCommon::GenericErrorCompletion *erg = 
00258                                 new ACSErrTypeCommon::GenericErrorCompletion(comp, 
00259                                                 __FILE__, __LINE__, 
00260                                                 "ErrorComponent::completionFromCompletion");
00261                         erg->setErrorDesc("Put an error trace in completionFromCompletion");
00262                         comp = erg;
00263                 }//if
00264         }
00265         return comp->returnCompletion();
00266 }//completionFromCompletion
00267 
00268 void 
00269 ErrorComponent::outCompletion(ACSErr::Completion_out comp)
00270 {
00271         ACS_TRACE("ErrorComponent::outCompletion");
00272         ACSErrTypeOK::ACSErrOKCompletion c;
00273         comp = c.returnCompletion(false);
00274     
00275             //comp=new ACSErr::Completion();
00276         //comp=new ACSErrTypeCommon::GenericErrorCompletion(__FILE__, __LINE__,"ErrorComponent::outCompletion");
00277 
00278 }
00279 CompletionImpl *ErrorComponent::createCompletion(unsigned short depth)
00280 {
00281    ACS_TRACE("::ErrorComponent::createCompletion");
00282    CompletionImpl *er;
00283 
00284     if( depth <= 0 )
00285         {
00286         er = new ACSErrTypeOK::ACSErrOKCompletion();
00287         }
00288     else
00289         {
00290         try
00291             {
00292             buildErrorTrace(depth-1);
00293             ACSErrTypeCommon::GenericErrorCompletion *erg =
00294                 new ACSErrTypeCommon::GenericErrorCompletion(
00295                                                      __FILE__, __LINE__,
00296                                                      "ErrorComponent::createCompletion");
00297             erg->setErrorDesc("Building a Completion with an errorTrace");
00298             er = erg;
00299             }
00300         catch(ACSErrTypeCommon::GenericErrorExImpl &ex)
00301             {
00302             // Here we build a completion from an exception: 
00303             // we create a new completion where it is added the error trace from an exception.
00304             ACSErrTypeCommon::GenericErrorCompletion *erg = 
00305                 new ACSErrTypeCommon::GenericErrorCompletion(ex, 
00306                                                      __FILE__, __LINE__, 
00307                                                      "ErrorComponent::createCompletion");
00308             erg->setErrorDesc("Building a Completion with a previous errorTrace");
00309             er = erg;
00310             }
00311         catch(...)
00312             {
00313             ACSErrTypeCommon::UnexpectedExceptionCompletion *erg = 
00314                 new ACSErrTypeCommon::UnexpectedExceptionCompletion( 
00315                                                      __FILE__, __LINE__, 
00316                                                      "ErrorComponent::returncompletion");
00317             er=erg;
00318             }
00319         }  
00320     
00321     // we are in local case so caller has to do the memory managment 
00322     // i.e. release the memory of CompletionImpl !
00323     return er;
00324 }//createCompletion
00325 
00326 
00327 /************
00328  * Utility method to build a deep ErrorTrace
00329  ************/
00330 void
00331 ErrorComponent::buildErrorTrace(unsigned short depth) 
00332 {
00333     ACS_TRACE("::ErrorComponent::buildErrorTrace");
00334 
00335     /*
00336      * If depth is 1, we are at the bottom and 
00337      * we just have to throw an exception.
00338      * Going up the recursive chain this will be
00339      * atteched to all other exceptions
00340      */
00341     if(depth == 1)
00342         {
00343         ACSErrTypeCommon::GenericErrorExImpl ex(__FILE__, __LINE__, 
00344                                                 "ErrorComponent::buildErrorTrace");
00345         ex.setErrorDesc("Bottom of error trace");
00346         throw ex;
00347         }
00348             
00349     /*
00350      * If depth > 1, make a recursive call.
00351      * We will have to get back an exception with a trace with
00352      * a depth shorter by 1 element.
00353      */
00354     if(depth > 1)
00355         {
00356         try
00357             {
00358             buildErrorTrace(depth-1);
00359             }
00360         catch(ACSErrTypeCommon::GenericErrorExImpl &ex)
00361             {
00362             ACSErrTypeCommon::GenericErrorExImpl ex2(ex, 
00363                                                      __FILE__, __LINE__, 
00364                                                      "ErrorComponent::errorTrace");
00365 
00366             ex2.setErrorDesc("Generated multi level exception level");
00367             throw ex2;
00368             }
00369         catch(...) // This should never happen!!!!
00370             {
00371             ACSErrTypeCommon::UnexpectedExceptionExImpl ex2(__FILE__, __LINE__, 
00372                                                             "ErrorComponent::errorTrace");
00373             throw ex2.getUnexpectedExceptionEx();
00374             }
00375         }
00376     /*
00377      * We should get here only if depth <= 0,
00378      * I.e. if there is not exception to throw.
00379      */
00380     return;
00381 }
00382 
00383 
00384 void
00385 ErrorComponent::generateSIGFPE (CORBA::Short way)
00386 {
00387     switch(way)
00388     {
00389         case 0:
00390             {
00391                 // Send the SIGFPE signal
00392                 ACS_DEBUG("ErrorComponent::generateSIGFPE","Send SIGFPE signal");
00393                 pid_t myPid = getpid();
00394                 kill(myPid,SIGFPE);
00395             }
00396             break;
00397         case 1:
00398         default:
00399             {
00400                 // Division by 0
00401                 ACS_DEBUG("ErrorComponent::generateSIGFPE","Tries to divide by zero");
00402                 int zero = 0;
00403                 printf("5/0 = %d\n",5/zero);
00404             }
00405     } // switch(way)
00406 }
00407 
00408 
00409 void
00410 ErrorComponent::generateSIGSEGV (CORBA::Short way)
00411 {
00412     switch(way)
00413     {
00414         case 0:
00415             {
00416                 // Send the SIGSEGV signal
00417                 ACS_DEBUG("ErrorComponent::generateSIGSEGV","Send SIGSEGV signal");
00418                 pid_t myPid = getpid();
00419                 kill(myPid,SIGSEGV);
00420             }
00421             break;
00422         case 1:
00423         default:
00424             {
00425                 // Access to null pointer
00426                 ACS_DEBUG("ErrorComponent::generateSIGSEGV","Tries to access to null pointer");
00427                 int * badPointer = 0;
00428                 *badPointer = 42;
00429             }
00430     } // switch(way)
00431 }
00432 
00433 void
00434 ErrorComponent::sleepingCmd(CORBA::Short nb_seconds)
00435 {
00436         ACS_DEBUG_PARAM("ErrorComponent::sleepingCmd","Sleeping for %d second(s)",nb_seconds);
00437         sleep(nb_seconds);
00438         ACS_DEBUG("ErrorComponent::sleepingCmd","Exiting...");
00439         return;
00440 }
00441 
00442 
00443 /* --------------- [ MACI DLL support functions ] -----------------*/
00444 #include <maciACSComponentDefines.h>
00445 MACI_DLL_SUPPORT_FUNCTIONS(ErrorComponent)
00446 /* ----------------------------------------------------------------*/
00447 
00448 
00449 /*___oOo___*/
00450 
00451 
00452