LAL  7.5.0.1-08ee4f4
LALGSL.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 /**
21  * \defgroup LALGSL_h Header LALGSL.h
22  * \ingroup lal_std
23  * \author Creighton, J. D. E.
24  *
25  * \brief Provides macros for integrating the GSL error handler with the LAL status structure.
26  *
27  * ### Synopsis ###
28  *
29  * \code
30  * #include <lal/LALGSL.h>
31  * \endcode
32  *
33  * This header provides macros and functions for tracking and
34  * reporting the runtime status of a GSL calls. The intent is
35  * simultaneously to standardize the error reporting, and to make the
36  * reporting as transparent as possible to people coding individual
37  * routines.
38  *
39  * <em>Please always use these macros when making a GSL call
40  * within LAL. This will ensure that the LAL functions always have the
41  * same behaviour and will also ensure that the LAL functions are reenterant
42  * and threadsafe (when LAL is configured appropriately).</em>
43  *
44  * ### GSL function calls ###
45  *
46  * The behaviour of GSL functions depends on the error handler that has been
47  * assigned. In order that LAL functions always have the same behaviour, it
48  * is necessary to use a LAL-specific GSL error handler. This error handler
49  * populates a LAL status structure with the GSL error message and code so that
50  * GSL functions behave much the same way as LAL functions. After the GSL
51  * functions are called, the error handler needs to be restored to the original
52  * handler so that the program calling the LAL routine has the same error handler
53  * after the LAL function was called as it did before the LAL function was called.
54  *
55  * This module provides a simple set of macros and the default LAL GSL error
56  * handler. The macros provide a standard way to assign the LAL GSL error
57  * handler before a GSL function call and to restore the original handler after
58  * the call.
59  *
60  * Note that changing the GSL error handler is \e not a thread-safe
61  * action. Therefore it is necessary to block other threads from performing
62  * GSL function calls while one thread has changed the handler. These macros
63  * ensure that such blocking is done for GSL function calls
64  * <em>within other LAL routines</em> if LAL is configured with the
65  * <tt>--enable-pthread-lock</tt> flag. See below for instructions on how
66  * to make other GSL function calls outside LAL thread-safe when used with LAL.
67  *
68  * \code
69  * ATTATCHSTATUSPTR( status );
70  * CALLGSL( gsl_function( x ), status );
71  * CHECKSTATUSPTR( status );
72  * DETATCHSTATUSPTR( status );
73  * \endcode
74  * Note that the LAL function must attach (and detach) a status pointer as if
75  * a LAL routine were called.
76  * Note also that you need to use the \c CHECKSTATUSPTR macro to check
77  * the status of the call. The equivalent to the \c TRY macro for GSL
78  * functions is the \c TRYGSL macro, which is used as follows:
79  * \code
80  * ATTATCHSTATUSPTR( status );
81  * TRYGSL( gsl_function( x ), status );
82  * DETATCHSTATUSPTR( status );
83  * \endcode
84  */
85 
86 #ifndef _LALGSL_H
87 #define _LALGSL_H
88 
89 #include <lal/LALConfig.h>
90 
91 #include <stdlib.h>
92 #include <string.h>
93 
94 #include <lal/LALMalloc.h>
95 #include <lal/LALDatatypes.h>
96 #include <lal/LALError.h>
97 
98 #include <lal/XLALGSL.h>
99 
100 #include <gsl/gsl_errno.h>
101 
102 #ifdef __cplusplus
103 extern "C" {
104 #elif 0
105 } /* so that editors will match preceding brace */
106 #endif
107 
108 #ifndef SWIG /* exclude from SWIG interface */
110 #endif /* SWIG */
111 void
112 LALGSLErrorHandler(const char *reason,
113  const char *file, int line, int errnum);
114 
115 #define CALLGSL( statement, statusptr ) \
116  if ( (statusptr) ) \
117  { \
118  LALStatus *saveLALGSLGlobalStatusPtr_; \
119  gsl_error_handler_t *saveGSLErrorHandler_; \
120  if ( !( (statusptr)->statusPtr ) ) \
121  { ABORT( (statusptr), -8, "CALLGSL: null status pointer pointer" ); } \
122  saveGSLErrorHandler_ = gsl_set_error_handler( LALGSLErrorHandler ); \
123  saveLALGSLGlobalStatusPtr_ = lalGSLGlobalStatusPtr; \
124  lalGSLGlobalStatusPtr = (statusptr)->statusPtr; \
125  statement; \
126  lalGSLGlobalStatusPtr = saveLALGSLGlobalStatusPtr_; \
127  gsl_set_error_handler( saveGSLErrorHandler_ ); \
128  } \
129  else \
130  lalAbortHook( "Abort: CALLGSL, file %s, line %d\n" \
131  " Null status pointer passed to CALLGSL\n", \
132  __FILE__, __LINE__ )
133 
134 
135 #define TRYGSL( statement, statusptr ) \
136  if ( (statusptr) ) \
137  { \
138  LALStatus *saveLALGSLGlobalStatusPtr_; \
139  gsl_error_handler_t *saveGSLErrorHandler_; \
140  if ( !( (statusptr)->statusPtr ) ) \
141  { ABORT( (statusptr), -8, "CALLGSL: null status pointer pointer" ); } \
142  saveGSLErrorHandler_ = gsl_set_error_handler( LALGSLErrorHandler ); \
143  saveLALGSLGlobalStatusPtr_ = lalGSLGlobalStatusPtr; \
144  lalGSLGlobalStatusPtr = (statusptr)->statusPtr; \
145  statement; \
146  lalGSLGlobalStatusPtr = saveLALGSLGlobalStatusPtr_; \
147  gsl_set_error_handler( saveGSLErrorHandler_ ); \
148  if ( (statusptr)->statusPtr->statusCode ) \
149  { \
150  SETSTATUS( statusptr, -1, "Recursive error" ); \
151  (void) LALError( statusptr, "Statement \"" #statement "\" failed:" ); \
152  (void) LALTrace( statusptr, 1 ); \
153  return; \
154  } \
155  } \
156  else \
157  lalAbortHook( "Abort: CALLGSL, file %s, line %d\n" \
158  " Null status pointer passed to CALLGSL\n", \
159  __FILE__, __LINE__ )
160 
161 #if 0
162 { /* so that editors will match succeeding brace */
163 #elif defined(__cplusplus)
164 }
165 #endif
166 #endif /* _LALGSL_H */
void LALGSLErrorHandler(const char *reason, const char *file, int line, int errnum)
LALStatus * lalGSLGlobalStatusPtr
Definition: LALGSL.c:24
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947