📄 private.c
字号:
*assocP = assoc;
return (result);
/*
* -------------
* Failure Code
* -------------
*/
FAIL2:
pthread_mutex_destroy (&(assoc->lock));
free (assoc);
FAIL0:
return (result);
} /* ptw32_tkAssocCreate */
void
ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc)
/*
* -------------------------------------------------------------------
* This routine releases all resources for the given ThreadKeyAssoc
* once it is no longer being referenced
* ie) both the key and thread have stopped referencing it.
*
* Parameters:
* assoc
* an instance of ThreadKeyAssoc.
* Returns:
* N/A
* -------------------------------------------------------------------
*/
{
if ((assoc != NULL) &&
(assoc->key == NULL && assoc->thread == NULL))
{
pthread_mutex_destroy (&(assoc->lock));
free (assoc);
}
} /* ptw32_tkAssocDestroy */
void
ptw32_callUserDestroyRoutines (pthread_t thread)
/*
* -------------------------------------------------------------------
* DOCPRIVATE
*
* This the routine runs through all thread keys and calls
* the destroy routines on the user's data for the current thread.
* It simulates the behaviour of POSIX Threads.
*
* PARAMETERS
* thread
* an instance of pthread_t
*
* RETURNS
* N/A
* -------------------------------------------------------------------
*/
{
ThreadKeyAssoc **nextP;
ThreadKeyAssoc *assoc;
if (thread != NULL)
{
/*
* Run through all Thread<-->Key associations
* for the current thread.
* If the pthread_key_t still exits (ie the assoc->key
* is not NULL) then call the user's TSD destroy routine.
* Notes:
* If assoc->key is NULL, then the user previously called
* PThreadKeyDestroy. The association is now only referenced
* by the current thread and must be released; otherwise
* the assoc will be destroyed when the key is destroyed.
*/
nextP = (ThreadKeyAssoc **) & (thread->keys);
assoc = *nextP;
while (assoc != NULL)
{
if (pthread_mutex_lock (&(assoc->lock)) == 0)
{
pthread_key_t k;
if ((k = assoc->key) != NULL)
{
/*
* Key still active; pthread_key_delete
* will block on this same mutex before
* it can release actual key; therefore,
* key is valid and we can call the destroy
* routine;
*/
void *value = NULL;
value = pthread_getspecific (k);
if (value != NULL && k->destructor != NULL)
{
#if defined(_MSC_VER) && !defined(__cplusplus)
__try
{
/*
* Run the caller's cleanup routine.
*/
(*(k->destructor)) (value);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
/*
* A system unexpected exception had occurred
* running the user's destructor.
* We get control back within this block.
*/
}
#else /* _MSC_VER && !__cplusplus */
#ifdef __cplusplus
try
{
/*
* Run the caller's cleanup routine.
*/
(*(k->destructor)) (value);
}
catch (...)
{
/*
* A system unexpected exception had occurred
* running the user's destructor.
* We get control back within this block.
*/
}
#else /* __cplusplus */
/*
* Run the caller's cleanup routine.
*/
(*(k->destructor)) (value);
#endif /* __cplusplus */
#endif /* _MSC_VER */
}
}
/*
* mark assoc->thread as NULL to indicate the
* thread no longer references this association
*/
assoc->thread = NULL;
/*
* Remove association from the pthread_t chain
*/
*nextP = assoc->nextKey;
pthread_mutex_unlock (&(assoc->lock));
ptw32_tkAssocDestroy (assoc);
assoc = *nextP;
}
}
}
} /* ptw32_callUserDestroyRoutines */
#ifdef NEED_FTIME
/*
* time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds
*/
#define TIMESPEC_TO_FILETIME_OFFSET \
( ((LONGLONG) 27111902 << 32) + (LONGLONG) 3577643008 )
static void
timespec_to_filetime(const struct timespec *ts, FILETIME *ft)
/*
* -------------------------------------------------------------------
* converts struct timespec
* where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
* into FILETIME (as set by GetSystemTimeAsFileTime), where the time is
* expressed in 100 nanoseconds from Jan 1, 1601,
* -------------------------------------------------------------------
*/
{
*(LONGLONG *)ft = ts->tv_sec * 10000000 + (ts->tv_nsec + 50) / 100 + TIMESPEC_TO_FILETIME_OFFSET;
}
static void
filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
/*
* -------------------------------------------------------------------
* converts FILETIME (as set by GetSystemTimeAsFileTime), where the time is
* expressed in 100 nanoseconds from Jan 1, 1601,
* into struct timespec
* where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
* -------------------------------------------------------------------
*/
{
ts->tv_sec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
ts->tv_nsec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET - ((LONGLONG)ts->tv_sec * (LONGLONG)10000000)) * 100);
}
#endif /* NEED_FTIME */
int
ptw32_sem_timedwait (sem_t * sem, const struct timespec * abstime)
/*
* ------------------------------------------------------
* DOCPUBLIC
* This function waits on a semaphore possibly until
* 'abstime' time.
*
* PARAMETERS
* sem
* pointer to an instance of sem_t
*
* abstime
* pointer to an instance of struct timespec
*
* DESCRIPTION
* This function waits on a semaphore. If the
* semaphore value is greater than zero, it decreases
* its value by one. If the semaphore value is zero, then
* the calling thread (or process) is blocked until it can
* successfully decrease the value or until interrupted by
* a signal.
*
* If 'abstime' is a NULL pointer then this function will
* block until it can successfully decrease the value or
* until interrupted by a signal.
*
* RESULTS
* 0 successfully decreased semaphore,
* -1 failed, error in errno
* ERRNO
* EINVAL 'sem' is not a valid semaphore,
* ENOSYS semaphores are not supported,
* EINTR the function was interrupted by a signal,
* EDEADLK a deadlock condition was detected.
* ETIMEDOUT abstime elapsed before success.
*
* ------------------------------------------------------
*/
{
int result = 0;
#ifdef NEED_FTIME
struct timespec currSysTime;
#else /* NEED_FTIME */
struct _timeb currSysTime;
#endif /* NEED_FTIME */
const DWORD NANOSEC_PER_MILLISEC = 1000000;
const DWORD MILLISEC_PER_SEC = 1000;
DWORD milliseconds;
if (sem == NULL)
{
result = EINVAL;
}
else
{
if (abstime == NULL)
{
milliseconds = INFINITE;
}
else
{
/*
* Calculate timeout as milliseconds from current system time.
*/
/* get current system time */
#ifdef NEED_FTIME
{
FILETIME ft;
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
/*
* GetSystemTimeAsFileTime(&ft); would be faster,
* but it does not exist on WinCE
*/
filetime_to_timespec(&ft, &currSysTime);
}
/*
* subtract current system time from abstime
*/
milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC;
milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
#else /* NEED_FTIME */
_ftime(&currSysTime);
/*
* subtract current system time from abstime
*/
milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC;
milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) -
currSysTime.millitm;
#endif /* NEED_FTIME */
if (((int) milliseconds) < 0)
milliseconds = 0;
}
#ifdef NEED_SEM
result = (pthreadCancelableTimedWait (sem->event, milliseconds));
#else /* NEED_SEM */
result = (pthreadCancelableTimedWait (*sem, milliseconds));
#endif
}
if (result != 0)
{
errno = result;
return -1;
}
#ifdef NEED_SEM
ptw32_decrease_semaphore(sem);
#endif /* NEED_SEM */
return 0;
} /* ptw32_sem_timedwait */
DWORD
ptw32_get_exception_services_code(void)
{
#if defined(_MSC_VER) && !defined(__cplusplus)
return EXCEPTION_PTW32_SERVICES;
#else
return (DWORD) NULL;
#endif
}
void
ptw32_throw(DWORD exception)
{
#if defined(_MSC_VER) && !defined(__cplusplus)
DWORD exceptionInformation[3];
#endif
if (exception != PTW32_EPS_CANCEL &&
exception != PTW32_EPS_EXIT)
{
/* Should never enter here */
exit(1);
}
#if defined(_MSC_VER) && !defined(__cplusplus)
exceptionInformation[0] = (DWORD) (exception);
exceptionInformation[1] = (DWORD) (0);
exceptionInformation[2] = (DWORD) (0);
RaiseException (
EXCEPTION_PTW32_SERVICES,
0,
3,
exceptionInformation);
#else /* _MSC_VER && ! __cplusplus */
# ifdef __cplusplus
switch (exception)
{
case PTW32_EPS_CANCEL:
throw ptw32_exception_cancel();
break;
case PTW32_EPS_EXIT:
throw ptw32_exception_exit();
break;
}
# endif /* __cplusplus */
#endif /* _MSC_VER && ! __cplusplus */
/* Never reached */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -