IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Opened 20 years ago

Closed 20 years ago

#793 closed defect (fixed)

psError()'s errorStack is not thread safe

Reported by: jhoblitt Owned by: jhoblitt
Priority: high Milestone:
Component: sys Version: 0.12.99
Severity: normal Keywords:
Cc: rhl@…

Description

psError()'s thread safety is poorly designed.
Despite the fact that the psError*() funcs are spinning a mutex they are not
thread safe. The currently locking only protects us from memory
corruption/segvs. It does not prevent a thread from getting some other threads
error messages.

Change History (2)

comment:1 by eugene, 20 years ago

a workable solution is to have multiple error stacks, one for each thread. these
would be setup on init for each thread (and could be done automatically the
first time a thread calls an error). the thread should check its thread ID and
use the error stack assigned to it.

I've done similar things in the past:

/* code in the init function */

/* create two output streams for this thread: LOG and ERR */
id = pthread_self();
streams[N].dest = GP_LOG;
streams[N].file = stdout;
streams[N].mode = GP_FILE;
streams[N].thread = id;

...

/* code in the calling function */

id = pthread_self();

/* find the existing output stream which matches */
for (i = 0; i < Nstreams; i++) {

if (!pthread_equal (streams[i].thread, id)) continue;
return (&streams[i]);

}
fprintf (stderr, "programming error: gprintInit not called for thread\n");
abort ();

comment:2 by jhoblitt, 20 years ago

Resolution: fixed
Status: newclosed

I believe that the error stack(s) should now be thread safe (but obvously it's
very difficult to test this), although I implimented this with thread local
storage (TLS) instead of passing an error stack aroun as Gene suggested. To
pass an error stack into each spawned thread would require changes all over
pslib and I felt it would make the API even more tedious. The commit info is below.

change lockErrorStack mutex to be static
add errorStackKeyInitialized global
add errorStack_key global
remove errorStack global
remove errorStackSize global
add prototypes at the top of the file for all static functions
add psErrorStackAlloc()
add psErrorStackFree()
add psFreeWrapper()
add psErrorStackGet() - accesses/initialized the error stack in thread local
data and change all psErr* functions to access the error stack via this function
remove all mutex spins except from psErrorStackGet()
change psErrorStackPush() to call psAbort() when the stack is full
rename pushErrorStack() -> psErrorStackPush()
change errFree() to use psStringCopy instead of strcpy() & psAlloc()
rename errFree() -> psErrFree()
change p_psWarning() to use MAX_STRING_LENGTH instead of inline size values
change psErrorGet()'s which param from psS32 -> int for consistency
change psErrorGetStackSize() to return int instead of unsigned int for consitency
rename the rather silly use of 'lcv' as a loop index variable to be just 'i'

Note: See TracTickets for help on using tickets.