fixed bug in osdThreadOnce

This commit is contained in:
Jeff Hill
2002-02-08 23:15:05 +00:00
parent 7398914536
commit 7185b540b1
2 changed files with 98 additions and 91 deletions

View File

@@ -742,8 +742,8 @@ epicsShareFunc void epicsShareAPI epicsThreadOnceOsd (
assert ( stat == WAIT_OBJECT_0 );
if ( ! *id ) {
*id = 1;
( *func ) ( arg );
*id = 1;
}
success = ReleaseMutex ( win32ThreadGlobalMutex );

View File

@@ -68,8 +68,7 @@ static CRITICAL_SECTION osdTimeCriticalSection;
static bool osdTimeSyncThreadExit = false;
static LONGLONG epicsEpoch;
static int osdTimeSych ();
static void osdTimeInit ( void * );
/*
* osdTimeExit ()
@@ -80,91 +79,10 @@ static void osdTimeExit ()
osdTimeSyncThreadExit = true;
}
/*
* epicsWin32ThreadEntry()
*/
static unsigned __stdcall osdTimeSynchThreadEntry (LPVOID)
{
static const DWORD tmoTenSec = 10 * epicsTime::mSecPerSec;
int status;
while ( ! osdTimeSyncThreadExit ) {
Sleep (tmoTenSec);
status = osdTimeSych ();
if (status!=epicsTimeOK) {
errlogPrintf ("osdTimeSych (): failed?\n");
}
}
return 0u;
}
//
// osdTimeInit ()
// osdTimeSychPvt ()
//
static void osdTimeInit ( void * )
{
LARGE_INTEGER parm;
BOOL success;
int unixStyleStatus;
HANDLE osdTimeThread;
unsigned threadAddr;
FILETIME epicsEpochFT;
InitializeCriticalSection ( & osdTimeCriticalSection );
//
// initialize elapsed time counters
//
// All CPUs running win32 currently have HR
// counters (Intel and Mips processors do)
//
if ( QueryPerformanceFrequency (&parm) == 0 ) {
DeleteCriticalSection ( & osdTimeCriticalSection );
return;
}
perf_freq = parm.QuadPart;
//
// convert the EPICS epoch to file time
//
success = SystemTimeToFileTime (&epicsEpochST, &epicsEpochFT);
if ( ! success ) {
DeleteCriticalSection ( & osdTimeCriticalSection );
return;
}
parm.LowPart = epicsEpochFT.dwLowDateTime;
parm.HighPart = epicsEpochFT.dwHighDateTime;
epicsEpoch = parm.QuadPart;
// set here to avoid recursion problems
osdTimeInitSuccess = true;
unixStyleStatus = osdTimeSych ();
if ( unixStyleStatus != epicsTimeOK ) {
DeleteCriticalSection ( & osdTimeCriticalSection );
return;
}
//
// spawn off a thread which periodically resynchronizes the offset
//
osdTimeThread = (HANDLE) _beginthreadex ( NULL, 4096, osdTimeSynchThreadEntry,
0, 0, &threadAddr );
if ( osdTimeThread == NULL ) {
errlogPrintf ( "osdTimeInit(): unable to start time synch thread\n" );
}
else {
assert ( CloseHandle ( osdTimeThread ) );
}
atexit ( osdTimeExit );
}
//
// osdTimeSych ()
//
static int osdTimeSych ()
static int osdTimeSychPvt ()
{
static const DWORD tmoTwentySec = 20 * epicsTime::mSecPerSec;
LONGLONG new_sec_offset, new_frac_offset;
@@ -173,11 +91,6 @@ static int osdTimeSych ()
FILETIME currentTimeFT;
LONGLONG currentTime;
epicsThreadOnce ( &osdTimeOnceFlag, osdTimeInit, 0 );
if ( ! osdTimeInitSuccess ) {
return epicsTimeERROR;
}
//
// its important that the following two time queries
// are close together (immediately adjacent to each
@@ -277,6 +190,100 @@ static int osdTimeSych ()
return epicsTimeOK;
}
//
// osdTimeSych ()
//
static int osdTimeSych ()
{
epicsThreadOnce ( &osdTimeOnceFlag, osdTimeInit, 0 );
if ( ! osdTimeInitSuccess ) {
return epicsTimeERROR;
}
return osdTimeSychPvt ();
}
/*
* osdTimeSynchThreadEntry()
*/
static unsigned __stdcall osdTimeSynchThreadEntry (LPVOID)
{
static const DWORD tmoTenSec = 10 * epicsTime::mSecPerSec;
int status;
while ( ! osdTimeSyncThreadExit ) {
Sleep (tmoTenSec);
status = osdTimeSych ();
if ( status != epicsTimeOK ) {
errlogPrintf ( "osdTimeSych (): failed?\n" );
}
}
return 0u;
}
//
// osdTimeInit ()
//
static void osdTimeInit ( void * )
{
LARGE_INTEGER parm;
BOOL success;
int unixStyleStatus;
HANDLE osdTimeThread;
unsigned threadAddr;
FILETIME epicsEpochFT;
InitializeCriticalSection ( & osdTimeCriticalSection );
//
// initialize elapsed time counters
//
// All CPUs running win32 currently have HR
// counters (Intel and Mips processors do)
//
if ( QueryPerformanceFrequency (&parm) == 0 ) {
DeleteCriticalSection ( & osdTimeCriticalSection );
return;
}
perf_freq = parm.QuadPart;
//
// convert the EPICS epoch to file time
//
success = SystemTimeToFileTime (&epicsEpochST, &epicsEpochFT);
if ( ! success ) {
DeleteCriticalSection ( & osdTimeCriticalSection );
return;
}
parm.LowPart = epicsEpochFT.dwLowDateTime;
parm.HighPart = epicsEpochFT.dwHighDateTime;
epicsEpoch = parm.QuadPart;
// set here to avoid recursion problems
osdTimeInitSuccess = true;
unixStyleStatus = osdTimeSychPvt ();
if ( unixStyleStatus != epicsTimeOK ) {
DeleteCriticalSection ( & osdTimeCriticalSection );
return;
}
//
// spawn off a thread which periodically resynchronizes the offset
//
osdTimeThread = (HANDLE) _beginthreadex ( NULL, 4096, osdTimeSynchThreadEntry,
0, 0, &threadAddr );
if ( osdTimeThread == NULL ) {
errlogPrintf ( "osdTimeInit(): unable to start time synch thread\n" );
}
else {
assert ( CloseHandle ( osdTimeThread ) );
}
atexit ( osdTimeExit );
}
//
// epicsTime::osdGetCurrent ()
//