Changeset 8792 for trunk/psLib/src/sys/psError.c
- Timestamp:
- Sep 11, 2006, 5:16:51 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/sys/psError.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psError.c
r8603 r8792 8 8 * of error detected. 9 9 * 10 * @author Joshua Hoblitt, University of Hawaii 10 11 * @author Eric Van Alst, MHPCC 11 12 * 12 * @version $Revision: 1.3 4$ $Name: not supported by cvs2svn $13 * @date $Date: 2006-0 8-25 22:04:03$13 * @version $Revision: 1.35 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2006-09-12 03:16:51 $ 14 15 * 15 16 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 25 26 #include "psString.h" 26 27 #include "psTrace.h" 28 #include "psAbort.h" 27 29 28 30 #define MAX_STRING_LENGTH 2048 29 30 31 31 #define MAX_ERROR_STACK_SIZE 64 32 static psErr* errorStack[MAX_ERROR_STACK_SIZE]; 33 static psU32 errorStackSize = 0; 34 pthread_mutex_t lockErrorStack = PTHREAD_MUTEX_INITIALIZER; 35 36 static void pushErrorStack(psErr* err); 37 38 static void pushErrorStack(psErr* err) 39 { 40 32 33 static pthread_mutex_t lockErrorStack = PTHREAD_MUTEX_INITIALIZER; 34 static bool errorStackKeyInitialized = false; 35 static pthread_key_t errorStack_key; 36 37 typedef struct 38 { 39 int n; 40 psErr **stack; 41 } 42 psErrorStack; 43 44 static psErrorStack *psErrorStackAlloc(void); 45 static void psErrorStackFree(psErrorStack *errorStack); 46 static void psFreeWrapper(void *ptr); 47 static void psErrorStackPush(psErr* err); 48 static psErrorStack *psErrorStackGet(void); 49 static void psErrFree(psErr* err); 50 51 static psErrorStack *psErrorStackAlloc(void) 52 { 53 psErrorStack *errorStack = psAlloc(sizeof(psErrorStack)); 54 errorStack->n = 0; 55 errorStack->stack = psAlloc(sizeof(psErr*) * MAX_ERROR_STACK_SIZE); 56 57 psMemSetDeallocator(errorStack, (psFreeFunc)psErrorStackFree); 58 59 return errorStack; 60 } 61 62 static void psErrorStackFree(psErrorStack *errorStack) 63 { 64 if (!errorStack) { 65 return; 66 } 67 68 psFree(errorStack->stack); 69 } 70 71 // needed for pthread_key_create() because p_psFree() does not match free()'s 72 // prototype 73 // XXX does something like this need to be global in psMmemory.h 74 static void psFreeWrapper(void *ptr) 75 { 76 psFree(ptr); 77 } 78 79 static void psErrorStackPush(psErr* err) 80 { 81 psErrorStack *errorStack = psErrorStackGet(); 82 83 // push the item onto the stack and increment the error count 84 if (errorStack->n < MAX_ERROR_STACK_SIZE) { 85 errorStack->stack[errorStack->n] = psMemIncrRefCounter(err); 86 (errorStack->n)++; 87 p_psMemSetPersistent(err, true); 88 p_psMemSetPersistent(err->msg, true); 89 p_psMemSetPersistent(err->name, true); 90 } else { 91 psAbort(__func__, "attempt to exceed maximum error stack depth of %d", 92 MAX_ERROR_STACK_SIZE); 93 } 94 } 95 96 static psErrorStack *psErrorStackGet(void) 97 { 98 // check to see if the error stack key has been initialized 41 99 pthread_mutex_lock(&lockErrorStack); 42 43 if (errorStackSize < MAX_ERROR_STACK_SIZE) { 44 errorStack[errorStackSize] = psMemIncrRefCounter(err); 45 errorStackSize++; 46 p_psMemSetPersistent(err,true); 47 p_psMemSetPersistent(err->msg,true); 48 p_psMemSetPersistent(err->name,true); 49 } 50 100 if (errorStackKeyInitialized == false) { 101 // note that each error stack will automatically be free'd when it's 102 // thread exits 103 if (pthread_key_create(&errorStack_key, psFreeWrapper)) { 104 psAbort(__func__, "pthread_key_create() failed"); 105 } 106 errorStackKeyInitialized = true; 107 } 51 108 pthread_mutex_unlock(&lockErrorStack); 52 } 53 54 static void errFree(psErr* err) 109 110 // check to see if the error stack for this thread has been allocated 111 psErrorStack *errorStack = NULL; 112 if ((errorStack = pthread_getspecific(errorStack_key)) == NULL) { 113 // allocate the error stack 114 errorStack = psErrorStackAlloc(); 115 p_psMemSetPersistent(errorStack, true); 116 p_psMemSetPersistent(errorStack->stack, true); 117 // store this threads error stack 118 // note that pthread_setspecifc() does not take a pointer as the first 119 // param 120 if (pthread_setspecific(errorStack_key, errorStack)) { 121 psAbort(__func__, "pthread_setspecific() failed"); 122 } 123 } 124 125 return errorStack; 126 } 127 128 static void psErrFree(psErr* err) 55 129 { 56 130 if (err != NULL) { … … 63 137 { 64 138 psErr* err = psAlloc(sizeof(psErr)); 65 err->msg = strcpy(psAlloc(strlen(msg) + 1),msg);66 err->name = strcpy(psAlloc(strlen(name) + 1),name);139 err->msg = psStringCopy(msg); 140 err->name = psStringCopy(name); 67 141 err->code = code; 68 142 69 psMemSetDeallocator(err,(psFreeFunc) errFree);143 psMemSetDeallocator(err,(psFreeFunc)psErrFree); 70 144 71 145 return err; … … 84 158 char msgName[MAX_STRING_LENGTH]; 85 159 160 // XXX a VLA should be used here instead of a fixed size buffer 86 161 snprintf(msgName, MAX_STRING_LENGTH, "%s (%s:%d)", func, filename, lineno); 87 162 … … 90 165 } 91 166 92 // Get the variable list parameters to pass to logging function 167 //XXX this could go away if we had a p_psTraceV() that accept file, 168 //lieno, etc. Get the variable list parameters to pass to logging function 93 169 va_list argPtr; // variable list arguement pointer 94 170 va_start(argPtr, format); … … 104 180 105 181 err = psErrAlloc(msgName,code,errMsg); 106 p ushErrorStack(err);182 psErrorStackPush(err); 107 183 108 184 #ifndef PS_NO_TRACE … … 125 201 ...) 126 202 { 127 char msgName[ 1024];128 129 snprintf(msgName, 1024,"%s (%s:%d)",func,file,lineno);203 char msgName[MAX_STRING_LENGTH]; 204 205 snprintf(msgName, MAX_STRING_LENGTH, "%s (%s:%d)", func, file, lineno); 130 206 131 207 va_list argPtr; // variable list argument pointer … … 142 218 } 143 219 144 psErr* psErrorGet( psS32which)220 psErr* psErrorGet(int which) 145 221 { 146 222 psErr* result; 147 223 148 p thread_mutex_lock(&lockErrorStack);224 psErrorStack *errorStack = psErrorStackGet(); 149 225 150 226 // Check for negative reference and if found return PS_ERR_NONE … … 153 229 } else { 154 230 155 which = errorStack Size-1-which; // the which input is from the end of errorStack156 if (which < 0 || which >= errorStack Size) {231 which = errorStack->n - 1 - which; // the which input is from the end of errorStack 232 if (which < 0 || which >= errorStack->n) { 157 233 result = psErrAlloc("",PS_ERR_NONE,""); // no error at the given location 158 234 } else { 159 result = psMemIncrRefCounter(errorStack [which]); // a new reference passed back235 result = psMemIncrRefCounter(errorStack->stack[which]); // a new reference passed back 160 236 } 161 237 } 162 238 163 pthread_mutex_unlock(&lockErrorStack);164 165 239 return result; 166 240 } 167 241 168 unsigned int psErrorGetStackSize() 169 { 170 return errorStackSize; 242 int psErrorGetStackSize() 243 { 244 psErrorStack *errorStack = psErrorStackGet(); 245 246 return errorStack->n; 171 247 } 172 248 … … 187 263 void psErrorClear(void) 188 264 { 189 pthread_mutex_lock(&lockErrorStack); 190 191 for (int lcv=0;lcv < errorStackSize; lcv++) { 192 p_psMemSetPersistent(errorStack[lcv],false); 193 p_psMemSetPersistent(errorStack[lcv]->msg,false); 194 p_psMemSetPersistent(errorStack[lcv]->name,false); 195 psFree(errorStack[lcv]); 196 } 197 errorStackSize = 0; 198 199 pthread_mutex_unlock(&lockErrorStack); 200 201 } 265 psErrorStack *errorStack = psErrorStackGet(); 266 267 for (int i = 0; i < errorStack->n; i++) { 268 p_psMemSetPersistent(errorStack->stack[i], false); 269 p_psMemSetPersistent((errorStack->stack[i])->msg, false); 270 p_psMemSetPersistent((errorStack->stack[i])->name, false); 271 psFree(errorStack->stack[i]); 272 } 273 274 errorStack->n = 0; 275 } 276 202 277 void psErrorStackPrint(FILE *fd, const char *format, ...) 203 278 { … … 214 289 void psErrorStackPrintV(FILE *fd, const char *format, va_list va) 215 290 { 216 217 pthread_mutex_lock(&lockErrorStack); 218 219 if (errorStackSize > 0) { 291 psErrorStack *errorStack = psErrorStackGet(); 292 293 if (errorStack->n > 0) { 220 294 vfprintf(fd,format,va); 221 295 222 for ( psS32 lcv=0;lcv<errorStackSize;lcv++) {223 if(errorStack [lcv]->code >= PS_ERR_BASE) {296 for (int i = 0; i < errorStack->n; i++) { 297 if(errorStack->stack[i]->code >= PS_ERR_BASE) { 224 298 fprintf(fd," -> %s: %s\n %s\n", 225 errorStack [lcv]->name,226 psErrorCodeString(errorStack [lcv]->code),227 errorStack [lcv]->msg);299 errorStack->stack[i]->name, 300 psErrorCodeString(errorStack->stack[i]->code), 301 errorStack->stack[i]->msg); 228 302 } else { 229 303 fprintf(fd," -> %s: %s\n %s\n", 230 errorStack [lcv]->name,231 strerror(errorStack [lcv]->code),232 errorStack [lcv]->msg);304 errorStack->stack[i]->name, 305 strerror(errorStack->stack[i]->code), 306 errorStack->stack[i]->msg); 233 307 } 234 308 } 235 309 } 236 237 pthread_mutex_unlock(&lockErrorStack); 238 } 239 310 } 311
Note:
See TracChangeset
for help on using the changeset viewer.
