LAL 7.7.0.1-678514e
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
103extern "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 */
111void
112LALGSLErrorHandler(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