added QSE_SECNSEC_TO_USEC()
removed qse_mtx_trylock() and added the waiting_time parameter to qse_mtx_lock()
This commit is contained in:
parent
74ab14974b
commit
49f4c3087f
@ -75,6 +75,9 @@
|
||||
#define QSE_SECNSEC_TO_MSEC(sec,nsec) \
|
||||
(((qse_long_t)(sec) * QSE_MSECS_PER_SEC) + ((qse_long_t)(nsec) / QSE_NSECS_PER_MSEC))
|
||||
|
||||
#define QSE_SECNSEC_TO_USEC(sec,nsec) \
|
||||
(((qse_long_t)(sec) * QSE_USECS_PER_SEC) + ((qse_long_t)(nsec) / QSE_NSECS_PER_USEC))
|
||||
|
||||
#define QSE_SEC_TO_MSEC(sec) ((sec) * QSE_MSECS_PER_SEC)
|
||||
#define QSE_MSEC_TO_SEC(sec) ((sec) / QSE_MSECS_PER_SEC)
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/cmn/time.h>
|
||||
|
||||
typedef struct qse_mtx_t qse_mtx_t;
|
||||
|
||||
@ -39,14 +40,19 @@ typedef struct qse_mtx_t qse_mtx_t;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
/* not implemented */
|
||||
# error not implemented
|
||||
/* typdef unsigned long ULONG;
|
||||
* typedef ULONG HMTX; */
|
||||
typedef unsigned long qse_mtx_hnd_t;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
/* not implemented */
|
||||
# error not implemented
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
/* typedef sem_id qse_mtx_hnd_t; */
|
||||
/* typedef int32 sem_id;
|
||||
* typedef sem_id qse_mtx_hnd_t; */
|
||||
typdef qse_int32_t qse_mtx_hnd_t;
|
||||
|
||||
#else
|
||||
|
||||
# if (QSE_SIZEOF_PTHREAD_MUTEX_T == 0)
|
||||
@ -113,16 +119,14 @@ void* qse_mtx_getxtn (
|
||||
);
|
||||
|
||||
int qse_mtx_lock (
|
||||
qse_mtx_t* mtx
|
||||
qse_mtx_t* mtx,
|
||||
qse_ntime_t* waiting_time
|
||||
);
|
||||
|
||||
int qse_mtx_unlock (
|
||||
qse_mtx_t* mtx
|
||||
);
|
||||
|
||||
int qse_mtx_trylock (
|
||||
qse_mtx_t* mtx
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#elif defined(__OS2__)
|
||||
/* implement this */
|
||||
@ -73,7 +74,7 @@ int qse_cnd_init (qse_cnd_t* cnd, qse_mmgr_t* mmgr)
|
||||
QSE_MEMSET (cnd, 0, QSE_SIZEOF(*cnd));
|
||||
cnd->mmgr = mmgr;
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
cnd->gone = 0;
|
||||
cnd->blocked = 0;
|
||||
cnd->waiting = 0;
|
||||
@ -86,8 +87,6 @@ int qse_cnd_init (qse_cnd_t* cnd, qse_mmgr_t* mmgr)
|
||||
cnd->queue == QSE_NULL ||
|
||||
cnd->mutex == QSE_NULL)
|
||||
{
|
||||
int num = qse_maperrno (GetLastError());
|
||||
|
||||
if (cnd->gate) CloseHandle (cnd->gate);
|
||||
if (cnd->queue) CloseHandle (cnd->queue);
|
||||
if (cnd->mutex) CloseHandle (cnd->mutex);
|
||||
@ -107,7 +106,7 @@ int qse_cnd_init (qse_cnd_t* cnd, qse_mmgr_t* mmgr)
|
||||
|
||||
void qse_cnd_fini (qse_cnd_t* cnd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
CloseHandle (cnd->gate);
|
||||
CloseHandle (cnd->queue);
|
||||
CloseHandle (cnd->mutex);
|
||||
@ -122,7 +121,7 @@ void qse_cnd_fini (qse_cnd_t* cnd)
|
||||
|
||||
void qse_cnd_signal (qse_cnd_t* cnd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
unsigned int signals = 0;
|
||||
|
||||
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
|
||||
@ -166,7 +165,7 @@ void qse_cnd_signal (qse_cnd_t* cnd)
|
||||
|
||||
void qse_cnd_broadcast (qse_cnd_t* cnd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
unsigned int signals = 0;
|
||||
|
||||
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
|
||||
@ -210,7 +209,7 @@ void qse_cnd_broadcast (qse_cnd_t* cnd)
|
||||
|
||||
void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
unsigned int was_waiting, was_gone;
|
||||
int signaled;
|
||||
|
||||
@ -222,7 +221,10 @@ void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
|
||||
|
||||
if (waiting_time)
|
||||
{
|
||||
signaled = (WaitForSingleObject((HANDLE)cnd->queue, (DWORD)waiting_time) == WAIT_OBJECT_0);
|
||||
DWORD msec;
|
||||
|
||||
msec = QSE_SECNSEC_TO_MSEC (waiting_time->sec, waiting_time->nsec);
|
||||
signaled = (WaitForSingleObject((HANDLE)cnd->queue, msec) == WAIT_OBJECT_0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -279,7 +281,7 @@ void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
|
||||
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
|
||||
}
|
||||
|
||||
qse_mtx_lock (mutex);
|
||||
qse_mtx_lock (mutex, QSE_NULL);
|
||||
#else
|
||||
if (waiting_time)
|
||||
{
|
||||
@ -302,82 +304,4 @@ void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
void qse_cnd_twait (
|
||||
qse_cnd_t* cnd, qse_mtx_t* mutex, qse_time_t waiting_time)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
qse_bool_t signaled;
|
||||
unsigned int was_waiting, was_gone;
|
||||
|
||||
WaitForSingleObject ((HANDLE)cnd->gate, INFINITE);
|
||||
++cnd->blocked;
|
||||
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
|
||||
|
||||
qse_mtx_unlock (mutex);
|
||||
|
||||
signaled = (WaitForSingleObject((HANDLE)cnd->queue, (DWORD)waiting_time) == WAIT_OBJECT_0);
|
||||
|
||||
was_waiting = 0;
|
||||
was_gone = 0;
|
||||
|
||||
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
|
||||
|
||||
was_waiting = cnd->waiting;
|
||||
was_gone = cnd->gone;
|
||||
|
||||
if (was_waiting != 0)
|
||||
{
|
||||
if (!signaled)
|
||||
{ /* timed out */
|
||||
if (cnd->blocked != 0) --(cnd->blocked);
|
||||
else ++(cnd->gone);
|
||||
}
|
||||
if (--(cnd->waiting) == 0)
|
||||
{
|
||||
if (cnd->blocked != 0)
|
||||
{
|
||||
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
|
||||
was_waiting = 0;
|
||||
}
|
||||
else if (cnd->gone != 0) cnd->gone = 0;
|
||||
}
|
||||
}
|
||||
else if (++(cnd->gone) == QSE_TYPE_MAX(unsigned int) / 2)
|
||||
{
|
||||
WaitForSingleObject ((HANDLE)cnd->gate, INFINITE);
|
||||
cnd->blocked -= cnd->gone;
|
||||
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
|
||||
cnd->gone = 0;
|
||||
}
|
||||
|
||||
ReleaseMutex ((HANDLE)cnd->mutex);
|
||||
|
||||
if (was_waiting == 1)
|
||||
{
|
||||
for (;was_gone; --was_gone)
|
||||
{
|
||||
WaitForSingleObject ((HANDLE)cnd->queue, INFINITE);
|
||||
}
|
||||
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
|
||||
}
|
||||
|
||||
qse_mtx_lock (mutex);
|
||||
#else
|
||||
qse_time_t now;
|
||||
qse_timespec_t timeout;
|
||||
|
||||
qse_gettime (&now);
|
||||
now += waiting_time;
|
||||
|
||||
QSE_TIME_TO_TIMESPEC (now, &timeout);
|
||||
|
||||
QSE_ASSERT (QSE_SIZEOF(timeout) == QSE_SIZEOF(struct timespec));
|
||||
pthread_cond_timedwait (&cnd->hnd, &mutex->hnd, &timeout);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -30,13 +30,19 @@
|
||||
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <process.h>
|
||||
#elif defined(__OS2__)
|
||||
/* implement this */
|
||||
|
||||
# define INCL_DOSSEMAPHORES
|
||||
# include <os2.h>
|
||||
|
||||
#elif defined(__DOS__)
|
||||
/* implement this */
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
# include <be/kernel/OS.h>
|
||||
|
||||
#else
|
||||
# if defined(AIX) && defined(__GNUC__)
|
||||
typedef int crid_t;
|
||||
@ -79,7 +85,17 @@ int qse_mtx_init (qse_mtx_t* mtx, qse_mmgr_t* mmgr)
|
||||
if (mtx->hnd == QSE_NULL) return -1;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
# error not implemented
|
||||
|
||||
{
|
||||
APIRET rc;
|
||||
HMTX m;
|
||||
|
||||
rc = DosCreateMutexSem (QSE_NULL, &m, DC_SEM_SHARED, FALSE);
|
||||
if (rc != NO_ERROR) return -1;
|
||||
|
||||
mtx->hnd = m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(__DOS__)
|
||||
# error not implemented
|
||||
@ -114,7 +130,7 @@ void qse_mtx_fini (qse_mtx_t* mtx)
|
||||
CloseHandle (mtx->hnd);
|
||||
|
||||
#elif defined(__OS2__)
|
||||
# error not implemented
|
||||
DosCloseMutexSem (mtx->hnd);
|
||||
|
||||
#elif defined(__DOS__)
|
||||
# error not implemented
|
||||
@ -138,7 +154,7 @@ void* qse_mtx_getxtn (qse_mtx_t* mtx)
|
||||
return QSE_XTN (mtx);
|
||||
}
|
||||
|
||||
int qse_mtx_lock (qse_mtx_t* mtx)
|
||||
int qse_mtx_lock (qse_mtx_t* mtx, qse_ntime_t* waiting_time)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
@ -153,15 +169,61 @@ int qse_mtx_lock (qse_mtx_t* mtx)
|
||||
* state is nonsignaled.
|
||||
* WAIT_FAILED An error occurred
|
||||
*/
|
||||
if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED)
|
||||
if (waiting_time)
|
||||
{
|
||||
qse_seterrno (qse_maperrno(GetLastError()));
|
||||
return -1;
|
||||
DWORD msec;
|
||||
msec = QSE_SECNSEC_TO_MSEC (waiting_time->sec, waiting_time->nsec);
|
||||
if (WaitForSingleObject(mtx->hnd, msec) != WAIT_OBJECT_0) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED) return -1;
|
||||
}
|
||||
|
||||
#elif defined(__OS2__)
|
||||
if (waiting_time)
|
||||
{
|
||||
ULONG msec;
|
||||
msec = QSE_SECNSEC_TO_MSEC (waiting_time->sec, waiting_time->nsec);
|
||||
if (DosRequestMutexSem (mtx->hnd, msec) != NO_ERROR) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DosRequestMutexSem (mtx->hnd, SEM_INDEFINITE_WAIT) != NO_ERROR) return -1;
|
||||
}
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
/* nothing to do */
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
if (waiting_time)
|
||||
{
|
||||
/* TODO: check for B_WOULD_BLOCK */
|
||||
/*if (acquire_sem_etc(mtx->hnd, 1, B_ABSOLUTE_TIMEOUT, 0) != B_NO_ERROR) return -1;*/
|
||||
bigtime_t usec;
|
||||
|
||||
usec = QSE_SECNSEC_TO_USEC (waiting_time->sec, waiting_time->nsec);
|
||||
if (acquire_sem_etc(mtx->hnd, 1, B_TIMEOUT, 0) != B_NO_ERROR) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (acquire_sem(mtx->hnd) != B_NO_ERROR) return -1;
|
||||
}
|
||||
#else
|
||||
|
||||
if (waiting_time)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = waiting_time->sec;
|
||||
ts.tv_nsec = waiting_time->nsec;
|
||||
if (pthread_mutex_timedlock ((pthread_mutex_t*)&mtx->hnd, &ts) != 0) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pthread_mutex_lock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -170,28 +232,21 @@ int qse_mtx_unlock (qse_mtx_t* mtx)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (ReleaseMutex (mtx->hnd) == FALSE) return -1;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
if (DosReleaseMutexSem (mtx->hnd) != NO_ERROR) return -1;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
/* nothing to do */
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
if (release_sem(mtx->hnd) != B_NO_ERROR) return -1;
|
||||
|
||||
#else
|
||||
if (pthread_mutex_unlock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_mtx_trylock (qse_mtx_t* mtx)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (WaitForSingleObject(mtx->hnd, 0) != WAIT_OBJECT_0) return -1;
|
||||
#elif defined(__BEOS__)
|
||||
if (acquire_sem_etc(mtx->hnd, 1, B_ABSOLUTE_TIMEOUT, 0) != B_NO_ERROR)
|
||||
{
|
||||
/* TODO: check for B_WOULD_BLOCK */
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (pthread_mutex_trylock((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -33,6 +33,7 @@
|
||||
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <process.h>
|
||||
# define QSE_THR_HND_INVALID INVALID_HANDLE_VALUE
|
||||
#elif defined(__OS2__)
|
||||
|
Loading…
Reference in New Issue
Block a user