epicsStdio.c allow stderr from inside epicsThreadInit()

Circular initialization problem that Murali discovered when you
try to fprintf(stderr) from the posix/osdThread.c once() routine.
This change lets the stderr stream through in that case.
This commit is contained in:
Andrew Johnson
2014-08-26 16:40:02 -07:00
parent 83d22ce164
commit 0d33e8a872
+18 -5
View File
@@ -27,7 +27,7 @@
static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT;
static epicsThreadPrivateId stdinThreadPrivateId;
static epicsThreadPrivateId stdoutThreadPrivateId;
static epicsThreadPrivateId stderrThreadPrivateId;
static epicsThreadPrivateId stderrThreadPrivateId = 0;
static void once(void *junk)
{
@@ -39,21 +39,27 @@ static void once(void *junk)
FILE * epicsShareAPI epicsGetStdin(void)
{
FILE *fp = epicsGetThreadStdin();
if(!fp) fp = stdin;
if (!fp)
fp = stdin;
return fp;
}
FILE * epicsShareAPI epicsGetStdout(void)
{
FILE *fp = epicsGetThreadStdout();
if(!fp) fp = stdout;
if (!fp)
fp = stdout;
return fp;
}
FILE * epicsShareAPI epicsGetStderr(void)
{
FILE *fp = epicsGetThreadStderr();
if(!fp) fp = stderr;
if (!fp)
fp = stderr;
return fp;
}
@@ -71,7 +77,14 @@ FILE * epicsShareAPI epicsGetThreadStdout(void)
FILE * epicsShareAPI epicsGetThreadStderr(void)
{
epicsThreadOnce(&onceId,once,0);
/* Deliberately don't do the epicsThreadOnce() here; epicsThreadInit()
* is allowed to use stderr inside its once() routine, in which case we
* must return the OS's stderr instead. There may be a tiny chance of a
* race happening here during initialization for some architectures, so
* we only use it for stderr to reduce the chance of that happening.
*/
if (!stderrThreadPrivateId)
return NULL;
return epicsThreadPrivateGet(stderrThreadPrivateId);
}