[77] | 1 | /* $Id: exception.c 13 2011-04-20 15:41:43Z mmamonski $ */ |
---|
| 2 | /* |
---|
| 3 | * PSNC DRMAA 2.0 utilities library |
---|
| 4 | * Copyright (C) 2012 Poznan Supercomputing and Networking Center |
---|
| 5 | * |
---|
| 6 | * This program is free software: you can redistribute it and/or modify |
---|
| 7 | * it under the terms of the GNU General Public License as published by |
---|
| 8 | * the Free Software Foundation, either version 3 of the License, or |
---|
| 9 | * (at your option) any later version. |
---|
| 10 | * |
---|
| 11 | * This program is distributed in the hope that it will be useful, |
---|
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 14 | * GNU General Public License for more details. |
---|
| 15 | * |
---|
| 16 | * You should have received a copy of the GNU General Public License |
---|
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
| 18 | */ |
---|
| 19 | |
---|
| 20 | #ifdef HAVE_CONFIG_H |
---|
| 21 | # include <config.h> |
---|
| 22 | #endif |
---|
| 23 | |
---|
| 24 | #include <errno.h> |
---|
| 25 | #include <string.h> |
---|
| 26 | #include <stdlib.h> |
---|
| 27 | |
---|
| 28 | #include <pthread.h> |
---|
| 29 | |
---|
| 30 | #include <drmaa_utils/common.h> |
---|
| 31 | #include <drmaa_utils/exception.h> |
---|
| 32 | |
---|
| 33 | |
---|
| 34 | #ifndef lint |
---|
| 35 | static char rcsid[] |
---|
| 36 | # ifdef __GNUC__ |
---|
| 37 | __attribute__ ((unused)) |
---|
| 38 | # endif |
---|
| 39 | = "$Id: exception.c 13 2011-04-20 15:41:43Z mmamonski $"; |
---|
| 40 | #endif |
---|
| 41 | |
---|
| 42 | |
---|
| 43 | int fsd_exc_code( const fsd_exc_t *self ); |
---|
| 44 | const char *fsd_exc_message( const fsd_exc_t *self ); |
---|
| 45 | void fsd_exc_destroy( fsd_exc_t *self ); |
---|
| 46 | |
---|
| 47 | #define EXC_INITIALIZER( code, message ) \ |
---|
| 48 | { \ |
---|
| 49 | fsd_exc_code, fsd_exc_message, fsd_exc_destroy, \ |
---|
| 50 | code, message, false, false \ |
---|
| 51 | } |
---|
| 52 | |
---|
| 53 | static const fsd_exc_t no_memory_exception \ |
---|
| 54 | = EXC_INITIALIZER( FSD_ERRNO_NO_MEMORY, "Not enough memory." ); |
---|
| 55 | |
---|
| 56 | |
---|
| 57 | /** |
---|
| 58 | * Thread specific stack of restore points |
---|
| 59 | * @see fsd_exc_try_block_t |
---|
| 60 | */ |
---|
| 61 | typedef struct fsd_exc_stack_s { |
---|
| 62 | fsd_exc_try_block_t **restore_points; |
---|
| 63 | int n_restore_points; |
---|
| 64 | } fsd_exc_stack_t; |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | static pthread_key_t fsd_exc_stack; |
---|
| 68 | static pthread_once_t fsd_exc_init_once = PTHREAD_ONCE_INIT; |
---|
| 69 | |
---|
| 70 | |
---|
| 71 | static void |
---|
| 72 | fsd_exc_stack_destroy( fsd_exc_stack_t *stack ); |
---|
| 73 | |
---|
| 74 | |
---|
| 75 | void |
---|
| 76 | fsd_exc_init(void) |
---|
| 77 | { |
---|
| 78 | int rc; |
---|
| 79 | fsd_log_enter(("")); |
---|
| 80 | rc = pthread_key_create( |
---|
| 81 | &fsd_exc_stack, |
---|
| 82 | (void (*)(void*))fsd_exc_stack_destroy |
---|
| 83 | ); |
---|
| 84 | if( rc ) |
---|
| 85 | { |
---|
| 86 | char errbuf[256] = "InternalError"; |
---|
| 87 | (void)strerror_r(errno, errbuf, 256); |
---|
| 88 | fsd_log_fatal(( "pthread_key_create: %s",errbuf )); |
---|
| 89 | abort(); |
---|
| 90 | } |
---|
| 91 | fsd_log_return(("")); |
---|
| 92 | } |
---|
| 93 | |
---|
| 94 | |
---|
| 95 | fsd_exc_stack_t * |
---|
| 96 | fsd_exc_get_stack( bool create ) |
---|
| 97 | { |
---|
| 98 | fsd_exc_stack_t *stack = NULL; |
---|
| 99 | int rc; |
---|
| 100 | |
---|
| 101 | rc = pthread_once( &fsd_exc_init_once, fsd_exc_init ); |
---|
| 102 | if( rc ) |
---|
| 103 | { |
---|
| 104 | char errbuf[256] = "InternalError"; |
---|
| 105 | (void)strerror_r(errno, errbuf, 256); |
---|
| 106 | fsd_log_fatal(( "pthread_once: %s",errbuf)); |
---|
| 107 | abort(); |
---|
| 108 | } |
---|
| 109 | stack = (fsd_exc_stack_t*)pthread_getspecific( fsd_exc_stack ); |
---|
| 110 | if( stack == NULL && create ) |
---|
| 111 | { |
---|
| 112 | rc = fsd_malloc_noraise( stack, fsd_exc_stack_t ); |
---|
| 113 | if( rc ) return NULL; |
---|
| 114 | stack->restore_points = NULL; |
---|
| 115 | stack->n_restore_points = 0; |
---|
| 116 | rc = pthread_setspecific( fsd_exc_stack, stack ); |
---|
| 117 | if( rc && errno != ENOMEM ) |
---|
| 118 | { |
---|
| 119 | char errbuf[256] = "InternalError"; |
---|
| 120 | (void)strerror_r(errno, errbuf, 256); |
---|
| 121 | fsd_log_fatal(( "pthread_setspecific: %s",errbuf )); |
---|
| 122 | abort(); |
---|
| 123 | } |
---|
| 124 | else if( rc ) |
---|
| 125 | { |
---|
| 126 | fsd_exc_stack_destroy( stack ); |
---|
| 127 | } |
---|
| 128 | } |
---|
| 129 | else |
---|
| 130 | fsd_assert( stack != NULL ); |
---|
| 131 | return stack; |
---|
| 132 | } |
---|
| 133 | |
---|
| 134 | |
---|
| 135 | void |
---|
| 136 | fsd_exc_stack_destroy( fsd_exc_stack_t *stack ) |
---|
| 137 | { |
---|
| 138 | int i; |
---|
| 139 | fsd_log_enter(("")); |
---|
| 140 | for( i = 0; i < stack->n_restore_points; i++ ) |
---|
| 141 | { |
---|
| 142 | fsd_exc_try_block_t *b = stack->restore_points[i]; |
---|
| 143 | if( b->handled_exc != NULL ) |
---|
| 144 | b->handled_exc->destroy( b->handled_exc ); |
---|
| 145 | fsd_free( b ); |
---|
| 146 | } |
---|
| 147 | fsd_free( stack->restore_points ); |
---|
| 148 | fsd_free( stack ); |
---|
| 149 | fsd_log_return(("")); |
---|
| 150 | } |
---|
| 151 | |
---|
| 152 | |
---|
| 153 | fsd_exc_try_block_t * |
---|
| 154 | fsd_exc_try( const char *function, int lineno ) |
---|
| 155 | { |
---|
| 156 | fsd_exc_stack_t *stack = NULL; |
---|
| 157 | fsd_exc_try_block_t *p = NULL; |
---|
| 158 | int rc; |
---|
| 159 | |
---|
| 160 | /* fsd_log_enter(( "(%s, %d)", function, lineno )); */ |
---|
| 161 | stack = fsd_exc_get_stack( true ); |
---|
| 162 | if( stack == NULL ) |
---|
| 163 | return NULL; |
---|
| 164 | |
---|
| 165 | rc = fsd_realloc_noraise( |
---|
| 166 | stack->restore_points, stack->n_restore_points+1, |
---|
| 167 | fsd_exc_try_block_t* ); |
---|
| 168 | if( rc ) |
---|
| 169 | return NULL; |
---|
| 170 | rc = fsd_malloc_noraise( p, fsd_exc_try_block_t ); |
---|
| 171 | if( rc ) |
---|
| 172 | return NULL; |
---|
| 173 | p->handled_exc = NULL; |
---|
| 174 | p->state = FSD_EXC_ENTER; |
---|
| 175 | p->function = function; |
---|
| 176 | p->lineno = lineno; |
---|
| 177 | stack->restore_points[ stack->n_restore_points++ ] = p; |
---|
| 178 | /* fsd_log_return(( " =%p", (void*)p )); */ |
---|
| 179 | return p; |
---|
| 180 | } |
---|
| 181 | |
---|
| 182 | |
---|
| 183 | void |
---|
| 184 | fsd_exc_control( fsd_exc_try_block_t *block, int *rc ) |
---|
| 185 | { |
---|
| 186 | /* fsd_log_enter(( "(block=%p, rc=%d)", (void*)block, *rc )); */ |
---|
| 187 | if( block == NULL || *rc == FSD_ERRNO_EXC_END ) |
---|
| 188 | return; |
---|
| 189 | |
---|
| 190 | switch( block->state ) |
---|
| 191 | { |
---|
| 192 | case FSD_EXC_ENTER: |
---|
| 193 | block->state = FSD_EXC_TRY_BLOCK; |
---|
| 194 | fsd_assert( *rc == 0 ); |
---|
| 195 | /* fsd_log_return(( ": rc=%d => %s:%d", |
---|
| 196 | *rc, block->function, block->lineno )); */ |
---|
| 197 | return; |
---|
| 198 | |
---|
| 199 | case FSD_EXC_TRY_BLOCK: |
---|
| 200 | if( *rc == 0 ) |
---|
| 201 | { |
---|
| 202 | block->state = FSD_EXC_ELSE_BLOCK; |
---|
| 203 | /* fsd_log_return(( ": rc=FSD_ERRNO_EXC_ELSE => %s:%d", |
---|
| 204 | block->function, block->lineno )); */ |
---|
| 205 | *rc = FSD_ERRNO_EXC_ELSE; |
---|
| 206 | return; |
---|
| 207 | } |
---|
| 208 | else |
---|
| 209 | { |
---|
| 210 | fsd_assert( *rc > 0 ); |
---|
| 211 | block->state = FSD_EXC_EXCEPTION_HANDLE; |
---|
| 212 | /* fsd_log_return(( ": rc=%d => %s:%d", |
---|
| 213 | *rc, block->function, block->lineno )); */ |
---|
| 214 | return; |
---|
| 215 | } |
---|
| 216 | |
---|
| 217 | case FSD_EXC_EXCEPTION_HANDLE: |
---|
| 218 | case FSD_EXC_ELSE_BLOCK: |
---|
| 219 | block->state = FSD_EXC_FINALLY_BLOCK; |
---|
| 220 | /* fsd_log_return(( ": rc=FSD_ERRNO_EXC_FINALLY => %s:%d", |
---|
| 221 | block->function, block->lineno )); */ |
---|
| 222 | *rc = FSD_ERRNO_EXC_FINALLY; |
---|
| 223 | return; |
---|
| 224 | |
---|
| 225 | case FSD_EXC_FINALLY_BLOCK: |
---|
| 226 | { |
---|
| 227 | fsd_exc_try_block_t *current = NULL; |
---|
| 228 | fsd_exc_try_block_t *upper = NULL; |
---|
| 229 | fsd_exc_stack_t *stack = NULL; |
---|
| 230 | |
---|
| 231 | block->state = FSD_EXC_LEAVE; |
---|
| 232 | |
---|
| 233 | stack = fsd_exc_get_stack( false ); |
---|
| 234 | current = stack->restore_points[ stack->n_restore_points-1 ]; |
---|
| 235 | fsd_assert( block == current ); |
---|
| 236 | if( stack->n_restore_points > 1 ) |
---|
| 237 | upper = stack->restore_points[ stack->n_restore_points-2 ]; |
---|
| 238 | stack->n_restore_points --; |
---|
| 239 | |
---|
| 240 | if( current->handled_exc && upper ) |
---|
| 241 | { |
---|
| 242 | if( upper->handled_exc ) |
---|
| 243 | { |
---|
| 244 | fsd_assert( upper->state == FSD_EXC_EXCEPTION_HANDLE |
---|
| 245 | || upper->state == FSD_EXC_FINALLY_BLOCK ); |
---|
| 246 | if( upper->state == FSD_EXC_FINALLY_BLOCK ) |
---|
| 247 | fsd_log_warning(( |
---|
| 248 | "overriding previously raised exception: <%d:%s>", |
---|
| 249 | upper->handled_exc->_code, upper->handled_exc->_message )); |
---|
| 250 | upper->handled_exc->destroy( upper->handled_exc ); |
---|
| 251 | } |
---|
| 252 | upper->handled_exc = current->handled_exc; |
---|
| 253 | /* current->handled_exc = NULL; */ |
---|
| 254 | fsd_free_noraise( current ); |
---|
| 255 | /* fsd_log_return(( ": longjmp(..., %d) => %s:%d", |
---|
| 256 | upper->handled_exc->_code, upper->function, upper->lineno )); */ |
---|
| 257 | longjmp( upper->env, upper->handled_exc->_code ); |
---|
| 258 | } |
---|
| 259 | else |
---|
| 260 | { |
---|
| 261 | if( current->handled_exc ) |
---|
| 262 | current->handled_exc->destroy( current->handled_exc ); |
---|
| 263 | fsd_free_noraise( current ); |
---|
| 264 | /* fsd_log_return(( ": rc=FSD_ERRNO_EXC_END => %s:%d", |
---|
| 265 | block->function, block->lineno )); */ |
---|
| 266 | *rc = FSD_ERRNO_EXC_END; |
---|
| 267 | return; |
---|
| 268 | } |
---|
| 269 | } |
---|
| 270 | |
---|
| 271 | default: |
---|
| 272 | fsd_assert(false); |
---|
| 273 | } |
---|
| 274 | |
---|
| 275 | /* no return */ |
---|
| 276 | } |
---|
| 277 | |
---|
| 278 | |
---|
| 279 | const fsd_exc_t * |
---|
| 280 | fsd_exc_get(void) |
---|
| 281 | { |
---|
| 282 | fsd_exc_stack_t *stack; |
---|
| 283 | fsd_exc_try_block_t *block; |
---|
| 284 | stack = fsd_exc_get_stack( false ); |
---|
| 285 | fsd_assert( stack->n_restore_points > 0 ); |
---|
| 286 | block = stack->restore_points[ stack->n_restore_points-1 ]; |
---|
| 287 | return block->handled_exc; |
---|
| 288 | } |
---|
| 289 | |
---|
| 290 | |
---|
| 291 | void |
---|
| 292 | fsd_exc_clear(void) |
---|
| 293 | { |
---|
| 294 | fsd_exc_stack_t *stack; |
---|
| 295 | fsd_exc_try_block_t *block; |
---|
| 296 | fsd_log_enter(("")); |
---|
| 297 | stack = fsd_exc_get_stack( false ); |
---|
| 298 | fsd_assert( stack->n_restore_points > 0 ); |
---|
| 299 | block = stack->restore_points[ stack->n_restore_points-1 ]; |
---|
| 300 | if( block->handled_exc ) |
---|
| 301 | block->handled_exc->destroy( block->handled_exc ); |
---|
| 302 | block->handled_exc = NULL; |
---|
| 303 | fsd_log_return(("")); |
---|
| 304 | } |
---|
| 305 | |
---|
| 306 | |
---|
| 307 | fsd_exc_t * |
---|
| 308 | fsd_exc_new( int code, char *message, bool own_message ) |
---|
| 309 | { |
---|
| 310 | fsd_exc_t *exc = NULL; |
---|
| 311 | char *volatile message_buffer = NULL; |
---|
| 312 | |
---|
| 313 | if ( code == FSD_DRMAA_ERRNO_EXIT_TIMEOUT || code == FSD_ERRNO_STOP_ITERATION ) |
---|
| 314 | fsd_log_debug(("fsd_exc_new(%d,%s,%d)", code, message, own_message)); |
---|
| 315 | else |
---|
| 316 | fsd_log_error(("fsd_exc_new(%d,%s,%d)", code, message, own_message)); |
---|
| 317 | |
---|
| 318 | |
---|
| 319 | TRY |
---|
| 320 | { |
---|
| 321 | if( own_message ) |
---|
| 322 | message_buffer = message; |
---|
| 323 | fsd_malloc( exc, fsd_exc_t ); |
---|
| 324 | exc->_code = code; |
---|
| 325 | exc->_message = message; |
---|
| 326 | exc->_own_message = own_message; |
---|
| 327 | exc->_own_self = true; |
---|
| 328 | exc->code = fsd_exc_code; |
---|
| 329 | exc->message = fsd_exc_message; |
---|
| 330 | exc->destroy = fsd_exc_destroy; |
---|
| 331 | } |
---|
| 332 | EXCEPT_DEFAULT |
---|
| 333 | { |
---|
| 334 | fsd_free( message_buffer ); |
---|
| 335 | fsd_exc_reraise(); |
---|
| 336 | } |
---|
| 337 | END_TRY |
---|
| 338 | return exc; |
---|
| 339 | } |
---|
| 340 | |
---|
| 341 | int |
---|
| 342 | fsd_exc_code( const fsd_exc_t *self ) |
---|
| 343 | { |
---|
| 344 | return self->_code; |
---|
| 345 | } |
---|
| 346 | |
---|
| 347 | const char * |
---|
| 348 | fsd_exc_message( const fsd_exc_t *self ) |
---|
| 349 | { |
---|
| 350 | return self->_message; |
---|
| 351 | } |
---|
| 352 | |
---|
| 353 | void |
---|
| 354 | fsd_exc_destroy( fsd_exc_t *self ) |
---|
| 355 | { |
---|
| 356 | if( self->_own_message ) |
---|
| 357 | fsd_free_noraise( self->_message ); |
---|
| 358 | if( self->_own_self ) |
---|
| 359 | fsd_free_noraise( self ); |
---|
| 360 | } |
---|
| 361 | |
---|
| 362 | |
---|
| 363 | void |
---|
| 364 | fsd_exc_raise( fsd_exc_t *exc ) |
---|
| 365 | { |
---|
| 366 | fsd_exc_stack_t *stack = NULL; |
---|
| 367 | fsd_exc_try_block_t *block = NULL; |
---|
| 368 | fsd_assert(( exc->_code > 0 )); |
---|
| 369 | stack = fsd_exc_get_stack( false ); |
---|
| 370 | fsd_assert(( stack->n_restore_points > 0 )); |
---|
| 371 | block = stack->restore_points[ stack->n_restore_points - 1 ]; |
---|
| 372 | if( block->handled_exc ) |
---|
| 373 | block->handled_exc->destroy( block->handled_exc ); |
---|
| 374 | block->handled_exc = exc; |
---|
| 375 | longjmp( block->env, exc->_code ); |
---|
| 376 | } |
---|
| 377 | |
---|
| 378 | |
---|
| 379 | void |
---|
| 380 | fsd_exc_raise_code( int error_code ) |
---|
| 381 | { |
---|
| 382 | fsd_exc_t *exc; |
---|
| 383 | |
---|
| 384 | if( error_code == FSD_ERRNO_NO_MEMORY ) |
---|
| 385 | exc = (fsd_exc_t*)&no_memory_exception; |
---|
| 386 | else |
---|
| 387 | exc = fsd_exc_new( error_code, (char*)fsd_strerror(error_code), false ); |
---|
| 388 | fsd_exc_raise( exc ); |
---|
| 389 | } |
---|
| 390 | |
---|
| 391 | void |
---|
| 392 | fsd_exc_raise_msg( int error_code, const char *message ) |
---|
| 393 | { |
---|
| 394 | fsd_exc_raise( |
---|
| 395 | fsd_exc_new( error_code, fsd_strdup(message), true ) ); |
---|
| 396 | } |
---|
| 397 | |
---|
| 398 | void |
---|
| 399 | fsd_exc_raise_fmt( int error_code, const char *fmt, ... ) |
---|
| 400 | { |
---|
| 401 | va_list args; |
---|
| 402 | va_start( args, fmt ); |
---|
| 403 | fsd_exc_raise_fmtv( error_code, fmt, args ); |
---|
| 404 | va_end( args ); |
---|
| 405 | } |
---|
| 406 | |
---|
| 407 | void |
---|
| 408 | fsd_exc_raise_fmtv( int error_code, const char *fmt, va_list args ) |
---|
| 409 | { |
---|
| 410 | fsd_exc_t *exc = NULL; |
---|
| 411 | char *volatile message = NULL; |
---|
| 412 | TRY |
---|
| 413 | { |
---|
| 414 | message = fsd_vasprintf( fmt, args ); |
---|
| 415 | exc = fsd_exc_new( error_code, message, true ); |
---|
| 416 | message = NULL; |
---|
| 417 | } |
---|
| 418 | FINALLY |
---|
| 419 | { |
---|
| 420 | fsd_free( message ); |
---|
| 421 | } |
---|
| 422 | END_TRY |
---|
| 423 | fsd_exc_raise( exc ); |
---|
| 424 | } |
---|
| 425 | |
---|
| 426 | void |
---|
| 427 | fsd_exc_raise_sys( int errno_code ) |
---|
| 428 | { |
---|
| 429 | fsd_exc_t *exc = NULL; |
---|
| 430 | |
---|
| 431 | if( errno_code == 0 ) |
---|
| 432 | errno_code = errno; |
---|
| 433 | if( errno_code == ENOMEM ) |
---|
| 434 | exc = (fsd_exc_t*)&no_memory_exception; |
---|
| 435 | else |
---|
| 436 | { |
---|
| 437 | int code; |
---|
| 438 | char* volatile message = NULL; |
---|
| 439 | volatile bool own_message = false; |
---|
| 440 | TRY |
---|
| 441 | { |
---|
| 442 | switch( errno_code ) |
---|
| 443 | { |
---|
| 444 | case ETIMEDOUT: code = FSD_ERRNO_TIMEOUT; break; |
---|
| 445 | default: code = FSD_ERRNO_INTERNAL_ERROR; break; |
---|
| 446 | } |
---|
| 447 | message = (char*)fsd_astrerror( errno_code, (bool*)&own_message ); |
---|
| 448 | exc = fsd_exc_new( code, message, own_message ); |
---|
| 449 | } |
---|
| 450 | EXCEPT_DEFAULT |
---|
| 451 | { |
---|
| 452 | if( message && own_message ) |
---|
| 453 | fsd_free( message ); |
---|
| 454 | fsd_exc_reraise(); |
---|
| 455 | } |
---|
| 456 | END_TRY |
---|
| 457 | } |
---|
| 458 | fsd_exc_raise( exc ); |
---|
| 459 | } |
---|
| 460 | |
---|
| 461 | |
---|
| 462 | void |
---|
| 463 | fsd_exc_reraise(void) |
---|
| 464 | { |
---|
| 465 | fsd_exc_stack_t *stack = NULL; |
---|
| 466 | fsd_exc_try_block_t *block = NULL; |
---|
| 467 | stack = fsd_exc_get_stack( false ); |
---|
| 468 | fsd_assert(( stack->n_restore_points > 0 )); |
---|
| 469 | block = stack->restore_points[ stack->n_restore_points - 1 ]; |
---|
| 470 | fsd_assert(( block->handled_exc->_code > 0 )); |
---|
| 471 | longjmp( block->env, block->handled_exc->_code ); |
---|
| 472 | } |
---|
| 473 | |
---|
| 474 | |
---|
| 475 | const char * |
---|
| 476 | fsd_strerror( int error_code ) |
---|
| 477 | { |
---|
| 478 | switch( error_code ) |
---|
| 479 | { |
---|
| 480 | case FSD_ERRNO_SUCCESS: |
---|
| 481 | return "Success."; |
---|
| 482 | case FSD_ERRNO_INTERNAL_ERROR: |
---|
| 483 | return "Unexpected or internal error."; |
---|
| 484 | case FSD_ERRNO_NO_MEMORY: |
---|
| 485 | return "Not enough memory."; |
---|
| 486 | case FSD_ERRNO_INVALID_ARGUMENT: |
---|
| 487 | return "Invalid argument value."; |
---|
| 488 | case FSD_ERRNO_INVALID_VALUE: |
---|
| 489 | return "Invalid value."; |
---|
| 490 | case FSD_ERRNO_INVALID_VALUE_FORMAT: |
---|
| 491 | return "Invalid value format."; |
---|
| 492 | case FSD_ERRNO_STOP_ITERATION: |
---|
| 493 | return "Vector have no more elements."; |
---|
| 494 | case FSD_ERRNO_NOT_IMPLEMENTED: |
---|
| 495 | return "Functionality is not implemented."; |
---|
| 496 | case FSD_ERRNO_NOT_INITIALIZED: |
---|
| 497 | return "Library is not initialized"; |
---|
| 498 | case FSD_ERRNO_TIMEOUT: |
---|
| 499 | return "Routine returned due to time-out."; |
---|
| 500 | case FSD_ERRNO_AUTH_FAILURE: |
---|
| 501 | return "Authentication failure."; |
---|
| 502 | case FSD_ERRNO_AUTHZ_FAILURE: |
---|
| 503 | return "Authorization failure"; |
---|
| 504 | case FSD_ERRNO_TRY_LATER: |
---|
| 505 | return "System is overloaded. Try again later."; |
---|
| 506 | case FSD_ERRNO_DRM_COMMUNICATION_FAILURE: |
---|
| 507 | return "Could not contact DRM system for this request."; |
---|
| 508 | case FSD_ERRNO_DRMS_INIT_FAILED: |
---|
| 509 | return "Unable to initialize DRM system."; |
---|
| 510 | case FSD_ERRNO_DRMS_EXIT_ERROR: |
---|
| 511 | return "Disengagement from the DRM system failed."; |
---|
| 512 | case FSD_ERRNO_DENIED_BY_DRM: |
---|
| 513 | return "DRM rejected request due to its configuration " |
---|
| 514 | "or request attributes."; |
---|
| 515 | |
---|
| 516 | case FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION: |
---|
| 517 | return "No active DRMAA session."; |
---|
| 518 | case FSD_DRMAA_ERRNO_INVALID_CONTACT_STRING: |
---|
| 519 | return "Invalid contact string."; |
---|
| 520 | case FSD_DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR: |
---|
| 521 | return "Can not determine default contact to DRM system."; |
---|
| 522 | case FSD_DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED: |
---|
| 523 | return "Contact to DRM must be set explicitly " |
---|
| 524 | "because there is no default."; |
---|
| 525 | case FSD_DRMAA_ERRNO_ALREADY_ACTIVE_SESSION: |
---|
| 526 | return "DRMAA session already exist."; |
---|
| 527 | case FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT: |
---|
| 528 | return "Invalid format of job attribute."; |
---|
| 529 | case FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE: |
---|
| 530 | return "Invalid value of job attribute."; |
---|
| 531 | case FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES: |
---|
| 532 | return "Value of attribute conflicts with other attribute value."; |
---|
| 533 | case FSD_DRMAA_ERRNO_INVALID_JOB: |
---|
| 534 | return "Job does not exist in DRMs queue."; |
---|
| 535 | case FSD_DRMAA_ERRNO_RESUME_INCONSISTENT_STATE: |
---|
| 536 | return "Can not resume job (not in valid state)."; |
---|
| 537 | case FSD_DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE: |
---|
| 538 | return "Can not suspend job (not in valid state)."; |
---|
| 539 | case FSD_DRMAA_ERRNO_HOLD_INCONSISTENT_STATE: |
---|
| 540 | return "Can not hold job (not in valid state)."; |
---|
| 541 | case FSD_DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE: |
---|
| 542 | return "Can not release job (not in valid state)."; |
---|
| 543 | case FSD_DRMAA_ERRNO_EXIT_TIMEOUT: |
---|
| 544 | return "Waiting for job to terminate finished due to time-out."; |
---|
| 545 | case FSD_DRMAA_ERRNO_NO_RUSAGE: |
---|
| 546 | return "Job finished but resource usage information " |
---|
| 547 | "and/or termination status could not be provided."; |
---|
| 548 | |
---|
| 549 | case FSD_ARES_ERRNO_INVALID_CONTACT_STRING: |
---|
| 550 | return "Invalid contact string."; |
---|
| 551 | case FSD_ARES_ERRNO_INVALID_ATTRIBUTE_FORMAT: |
---|
| 552 | return "Invalid format of job attribute."; |
---|
| 553 | case FSD_ARES_ERRNO_INVALID_ATTRIBUTE_VALUE: |
---|
| 554 | return "Invalid value of job attribute."; |
---|
| 555 | case FSD_ARES_ERRNO_CONFLICTING_ATTRIBUTE_VALUES: |
---|
| 556 | return "Value of attribute conflicts with other attribute value."; |
---|
| 557 | case FSD_ARES_ERRNO_INVALID_ARES: |
---|
| 558 | return "Invalid advance reservation identifier.."; |
---|
| 559 | |
---|
| 560 | default: |
---|
| 561 | return "Unknown error code!?"; |
---|
| 562 | } |
---|
| 563 | } |
---|
| 564 | |
---|
| 565 | |
---|
| 566 | static const int fsd_stacktrace_length = 32; |
---|
| 567 | |
---|
| 568 | void |
---|
| 569 | fsd_assertion_failed( |
---|
| 570 | const char *file, int lineno, |
---|
| 571 | const char *function, const char *precondition |
---|
| 572 | ) |
---|
| 573 | { |
---|
| 574 | char *message = NULL; |
---|
| 575 | if( asprintf( &message, "%s:%d: %s: Assertion `%s' failed.", |
---|
| 576 | file, lineno, function, precondition ) == -1 ) |
---|
| 577 | message = NULL; |
---|
| 578 | if( message != NULL ) |
---|
| 579 | fsd_log_fatal(( "%s", message )); |
---|
| 580 | fsd_log_stacktrace( 1, fsd_stacktrace_length ); |
---|
| 581 | if( message != NULL ) |
---|
| 582 | free( message ); |
---|
| 583 | abort(); |
---|
| 584 | } |
---|
| 585 | |
---|
| 586 | |
---|
| 587 | void * |
---|
| 588 | fsd_exc_try_except( |
---|
| 589 | void*(*f)(void*), void *data, |
---|
| 590 | int *error_code, |
---|
| 591 | char **error_message |
---|
| 592 | ) |
---|
| 593 | { |
---|
| 594 | void *result = NULL; |
---|
| 595 | TRY |
---|
| 596 | { |
---|
| 597 | result = f( data ); |
---|
| 598 | } |
---|
| 599 | EXCEPT_DEFAULT |
---|
| 600 | { |
---|
| 601 | const fsd_exc_t *e = fsd_exc_get(); |
---|
| 602 | *error_code = e->code(e); |
---|
| 603 | *error_message = fsd_strdup( e->message(e) ); |
---|
| 604 | } |
---|
| 605 | ELSE |
---|
| 606 | { |
---|
| 607 | *error_code = FSD_ERRNO_SUCCESS; |
---|
| 608 | *error_message = NULL; |
---|
| 609 | } |
---|
| 610 | END_TRY |
---|
| 611 | return result; |
---|
| 612 | } |
---|
| 613 | |
---|
| 614 | |
---|