Ignore:
Timestamp:
Aug 14, 2009 10:41:00 AM (15 years ago)
Author:
bennylp
Message:

Fixed ticket #939: Throwing exception inside exception handler will cause infinite loop (thanks Roman Puls for the report)

  • exception handler is now popped from the stack immediately in PJ_THROW
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/include/pj/except.h

    r2394 r2878  
    5757 * The exception handling mechanism is completely thread safe, so the exception 
    5858 * thrown by one thread will not interfere with other thread. 
    59  * 
    60  * CAVEATS: 
    61  *  - unlike C++ exception, the scheme here won't call destructors of local 
    62  *    objects if exception is thrown. Care must be taken when a function 
    63  *    hold some resorce such as pool or mutex etc. 
    64  *  - You CAN NOT make nested exception in one single function without using 
    65  *    a nested PJ_USE_EXCEPTION. 
    66  *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH 
    67  *    and PJ_CATCH_ANY for a single PJ_TRY. 
    68  *  - Exceptions will always be caught by the first handler (unlike C++ where 
    69  *    exception is only caught if the type matches. 
    7059 * 
    7160 * The exception handling constructs are similar to C++. The blocks will be 
     
    128117 * ID is raised by default pool policy when it fails to allocate memory. 
    129118 * 
     119 * CAVEATS: 
     120 *  - unlike C++ exception, the scheme here won't call destructors of local 
     121 *    objects if exception is thrown. Care must be taken when a function 
     122 *    hold some resorce such as pool or mutex etc. 
     123 *  - You CAN NOT make nested exception in one single function without using 
     124 *    a nested PJ_USE_EXCEPTION. Samples: 
     125  \verbatim 
     126        void wrong_sample() 
     127        { 
     128            PJ_USE_EXCEPTION; 
     129 
     130            PJ_TRY { 
     131                // Do stuffs 
     132                ... 
     133            } 
     134            PJ_CATCH_ANY { 
     135                // Do other stuffs 
     136                .... 
     137                .. 
     138 
     139                // The following block is WRONG! You MUST declare  
     140                // PJ_USE_EXCEPTION once again in this block. 
     141                PJ_TRY { 
     142                    .. 
     143                } 
     144                PJ_CATCH_ANY { 
     145                    .. 
     146                } 
     147                PJ_END; 
     148            } 
     149            PJ_END; 
     150        } 
     151 
     152  \endverbatim 
     153 
     154 *  - You MUST NOT exit the function inside the PJ_TRY block. The correct way 
     155 *    is to return from the function after PJ_END block is executed.  
     156 *    For example, the following code will yield crash not in this code, 
     157 *    but rather in the subsequent execution of PJ_TRY block: 
     158  \verbatim 
     159        void wrong_sample() 
     160        { 
     161            PJ_USE_EXCEPTION; 
     162 
     163            PJ_TRY { 
     164                // do some stuffs 
     165                ... 
     166                return;         <======= DO NOT DO THIS! 
     167            } 
     168            PJ_CATCH_ANY { 
     169            } 
     170            PJ_END; 
     171        } 
     172  \endverbatim 
     173   
     174 *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH 
     175 *    and PJ_CATCH_ANY for a single PJ_TRY. 
     176 *  - Exceptions will always be caught by the first handler (unlike C++ where 
     177 *    exception is only caught if the type matches. 
     178 
    130179 * \section PJ_EX_KEYWORDS Keywords 
    131180 * 
     
    311360 * Pop exception handler. 
    312361 */ 
    313 PJ_DECL(void) pj_pop_exception_handler_(void); 
     362PJ_DECL(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec); 
    314363 
    315364/** 
     
    344393 * @hideinitializer 
    345394 */ 
    346 #define PJ_END                  pj_pop_exception_handler_(); \ 
     395#define PJ_END                  pj_pop_exception_handler_(&pj_x_except__); \ 
    347396                            } else {} 
    348397 
Note: See TracChangeset for help on using the changeset viewer.