src/lib/errCatch.c 1.7
1.7 2010/04/01 16:35:37 markd
fixed 3264bit portability issue the right way
Index: src/lib/errCatch.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/errCatch.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -b -B -U 1000000 -r1.6 -r1.7
--- src/lib/errCatch.c 5 Mar 2010 02:52:17 -0000 1.6
+++ src/lib/errCatch.c 1 Apr 2010 16:35:37 -0000 1.7
@@ -1,121 +1,121 @@
/* errCatch - help catch errors so that errAborts aren't
* fatal, and warn's don't necessarily get printed immediately.
* Note that error conditions caught this way will tend to
* leak resources unless there are additional wrappers.
*
* Typical usage is
* errCatch = errCatchNew();
* if (errCatchStart(errCatch))
* doFlakyStuff();
* errCatchEnd(errCatch);
* if (errCatch->gotError)
* warn(errCatch->message->string);
* errCatchFree(&errCatch);
* cleanupFlakyStuff();
*/
#include "common.h"
#include "errabort.h"
#include "dystring.h"
#include "hash.h"
#include <pthread.h>
#include "errCatch.h"
static char const rcsid[] = "$Id$";
struct errCatch *errCatchNew()
/* Return new error catching structure. */
{
struct errCatch *errCatch;
AllocVar(errCatch);
errCatch->message = dyStringNew(0);
return errCatch;
}
void errCatchFree(struct errCatch **pErrCatch)
/* Free up resources associated with errCatch */
{
struct errCatch *errCatch = *pErrCatch;
if (errCatch != NULL)
{
dyStringFree(&errCatch->message);
freez(pErrCatch);
}
}
static struct errCatch **getStack()
/* Return a pointer to the errCatch object stack for the current pthread. */
{
static struct hash *perThreadStacks = NULL;
pthread_t pid = pthread_self(); // can be a pointer or a number
// A true integer has function would be nicer, but this will do.
// Don't safef, theoretically that could abort.
char key[64];
-snprintf(key, sizeof(key), "%lld", (long long)pid);
+snprintf(key, sizeof(key), "%lld", ptrToLL(pid));
key[ArraySize(key)-1] = '\0';
if (perThreadStacks == NULL)
perThreadStacks = hashNew(0);
struct hashEl *hel = hashLookup(perThreadStacks, key);
if (hel == NULL)
hel = hashAdd(perThreadStacks, key, NULL);
return (struct errCatch **)(&hel->val);
}
static void errCatchAbortHandler()
/* semiAbort */
{
struct errCatch **pErrCatchStack = getStack(), *errCatchStack = *pErrCatchStack;
errCatchStack->gotError = TRUE;
longjmp(errCatchStack->jmpBuf, -1);
}
static void errCatchWarnHandler(char *format, va_list args)
/* Write an error to top of errCatchStack. */
{
struct errCatch **pErrCatchStack = getStack(), *errCatchStack = *pErrCatchStack;
dyStringVaPrintf(errCatchStack->message, format, args);
dyStringAppendC(errCatchStack->message, '\n');
}
boolean errCatchPushHandlers(struct errCatch *errCatch)
/* Push error handlers. Not usually called directly. */
{
pushAbortHandler(errCatchAbortHandler);
pushWarnHandler(errCatchWarnHandler);
struct errCatch **pErrCatchStack = getStack();
slAddHead(pErrCatchStack, errCatch);
return TRUE;
}
void errCatchEnd(struct errCatch *errCatch)
/* Restore error handlers and pop self off of catching stack. */
{
popWarnHandler();
popAbortHandler();
struct errCatch **pErrCatchStack = getStack(), *errCatchStack = *pErrCatchStack;
if (errCatch != errCatchStack)
errAbort("Mismatch betweene errCatch and errCatchStack");
*pErrCatchStack = errCatch->next;
}
boolean errCatchFinish(struct errCatch **pErrCatch)
/* Finish up error catching. Report error if there is a
* problem and return FALSE. If no problem return TRUE.
* This handles errCatchEnd and errCatchFree. */
{
struct errCatch *errCatch = *pErrCatch;
boolean ok = TRUE;
if (errCatch != NULL)
{
errCatchEnd(errCatch);
if (errCatch->gotError)
{
ok = FALSE;
warn("%s", errCatch->message->string);
}
errCatchFree(pErrCatch);
}
return ok;
}