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) \
|
#define QSE_SECNSEC_TO_MSEC(sec,nsec) \
|
||||||
(((qse_long_t)(sec) * QSE_MSECS_PER_SEC) + ((qse_long_t)(nsec) / QSE_NSECS_PER_MSEC))
|
(((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_SEC_TO_MSEC(sec) ((sec) * QSE_MSECS_PER_SEC)
|
||||||
#define QSE_MSEC_TO_SEC(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/types.h>
|
||||||
#include <qse/macros.h>
|
#include <qse/macros.h>
|
||||||
|
#include <qse/cmn/time.h>
|
||||||
|
|
||||||
typedef struct qse_mtx_t qse_mtx_t;
|
typedef struct qse_mtx_t qse_mtx_t;
|
||||||
|
|
||||||
@ -39,14 +40,19 @@ typedef struct qse_mtx_t qse_mtx_t;
|
|||||||
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
|
|
||||||
/* not implemented */
|
/* typdef unsigned long ULONG;
|
||||||
# error not implemented
|
* typedef ULONG HMTX; */
|
||||||
|
typedef unsigned long qse_mtx_hnd_t;
|
||||||
|
|
||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
/* not implemented */
|
/* not implemented */
|
||||||
# error not implemented
|
# error not implemented
|
||||||
|
|
||||||
#elif defined(__BEOS__)
|
#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;
|
typdef qse_int32_t qse_mtx_hnd_t;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# if (QSE_SIZEOF_PTHREAD_MUTEX_T == 0)
|
# if (QSE_SIZEOF_PTHREAD_MUTEX_T == 0)
|
||||||
@ -113,16 +119,14 @@ void* qse_mtx_getxtn (
|
|||||||
);
|
);
|
||||||
|
|
||||||
int qse_mtx_lock (
|
int qse_mtx_lock (
|
||||||
qse_mtx_t* mtx
|
qse_mtx_t* mtx,
|
||||||
|
qse_ntime_t* waiting_time
|
||||||
);
|
);
|
||||||
|
|
||||||
int qse_mtx_unlock (
|
int qse_mtx_unlock (
|
||||||
qse_mtx_t* mtx
|
qse_mtx_t* mtx
|
||||||
);
|
);
|
||||||
|
|
||||||
int qse_mtx_trylock (
|
|
||||||
qse_mtx_t* mtx
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
/* implement this */
|
/* 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));
|
QSE_MEMSET (cnd, 0, QSE_SIZEOF(*cnd));
|
||||||
cnd->mmgr = mmgr;
|
cnd->mmgr = mmgr;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32)
|
||||||
cnd->gone = 0;
|
cnd->gone = 0;
|
||||||
cnd->blocked = 0;
|
cnd->blocked = 0;
|
||||||
cnd->waiting = 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->queue == QSE_NULL ||
|
||||||
cnd->mutex == QSE_NULL)
|
cnd->mutex == QSE_NULL)
|
||||||
{
|
{
|
||||||
int num = qse_maperrno (GetLastError());
|
|
||||||
|
|
||||||
if (cnd->gate) CloseHandle (cnd->gate);
|
if (cnd->gate) CloseHandle (cnd->gate);
|
||||||
if (cnd->queue) CloseHandle (cnd->queue);
|
if (cnd->queue) CloseHandle (cnd->queue);
|
||||||
if (cnd->mutex) CloseHandle (cnd->mutex);
|
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)
|
void qse_cnd_fini (qse_cnd_t* cnd)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32)
|
||||||
CloseHandle (cnd->gate);
|
CloseHandle (cnd->gate);
|
||||||
CloseHandle (cnd->queue);
|
CloseHandle (cnd->queue);
|
||||||
CloseHandle (cnd->mutex);
|
CloseHandle (cnd->mutex);
|
||||||
@ -122,7 +121,7 @@ void qse_cnd_fini (qse_cnd_t* cnd)
|
|||||||
|
|
||||||
void qse_cnd_signal (qse_cnd_t* cnd)
|
void qse_cnd_signal (qse_cnd_t* cnd)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32)
|
||||||
unsigned int signals = 0;
|
unsigned int signals = 0;
|
||||||
|
|
||||||
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
|
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)
|
void qse_cnd_broadcast (qse_cnd_t* cnd)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32)
|
||||||
unsigned int signals = 0;
|
unsigned int signals = 0;
|
||||||
|
|
||||||
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
|
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)
|
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;
|
unsigned int was_waiting, was_gone;
|
||||||
int signaled;
|
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)
|
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
|
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);
|
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_mtx_lock (mutex);
|
qse_mtx_lock (mutex, QSE_NULL);
|
||||||
#else
|
#else
|
||||||
if (waiting_time)
|
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
|
#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
|
#endif
|
||||||
|
@ -30,13 +30,19 @@
|
|||||||
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
# include <windows.h>
|
||||||
# include <process.h>
|
# include <process.h>
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
/* implement this */
|
|
||||||
|
# define INCL_DOSSEMAPHORES
|
||||||
|
# include <os2.h>
|
||||||
|
|
||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
/* implement this */
|
/* implement this */
|
||||||
|
|
||||||
#elif defined(__BEOS__)
|
#elif defined(__BEOS__)
|
||||||
# include <be/kernel/OS.h>
|
# include <be/kernel/OS.h>
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# if defined(AIX) && defined(__GNUC__)
|
# if defined(AIX) && defined(__GNUC__)
|
||||||
typedef int crid_t;
|
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;
|
if (mtx->hnd == QSE_NULL) return -1;
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
#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__)
|
#elif defined(__DOS__)
|
||||||
# error not implemented
|
# error not implemented
|
||||||
@ -114,7 +130,7 @@ void qse_mtx_fini (qse_mtx_t* mtx)
|
|||||||
CloseHandle (mtx->hnd);
|
CloseHandle (mtx->hnd);
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
# error not implemented
|
DosCloseMutexSem (mtx->hnd);
|
||||||
|
|
||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
# error not implemented
|
# error not implemented
|
||||||
@ -138,7 +154,7 @@ void* qse_mtx_getxtn (qse_mtx_t* mtx)
|
|||||||
return QSE_XTN (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)
|
#if defined(_WIN32)
|
||||||
/*
|
/*
|
||||||
@ -153,15 +169,61 @@ int qse_mtx_lock (qse_mtx_t* mtx)
|
|||||||
* state is nonsignaled.
|
* state is nonsignaled.
|
||||||
* WAIT_FAILED An error occurred
|
* WAIT_FAILED An error occurred
|
||||||
*/
|
*/
|
||||||
if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED)
|
if (waiting_time)
|
||||||
{
|
{
|
||||||
qse_seterrno (qse_maperrno(GetLastError()));
|
DWORD msec;
|
||||||
return -1;
|
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__)
|
#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;
|
if (acquire_sem(mtx->hnd) != B_NO_ERROR) return -1;
|
||||||
|
}
|
||||||
#else
|
#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;
|
if (pthread_mutex_lock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -170,28 +232,21 @@ int qse_mtx_unlock (qse_mtx_t* mtx)
|
|||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (ReleaseMutex (mtx->hnd) == FALSE) return -1;
|
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__)
|
#elif defined(__BEOS__)
|
||||||
if (release_sem(mtx->hnd) != B_NO_ERROR) return -1;
|
if (release_sem(mtx->hnd) != B_NO_ERROR) return -1;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (pthread_mutex_unlock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
|
if (pthread_mutex_unlock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
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
|
#endif
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
# include <windows.h>
|
||||||
# include <process.h>
|
# include <process.h>
|
||||||
# define QSE_THR_HND_INVALID INVALID_HANDLE_VALUE
|
# define QSE_THR_HND_INVALID INVALID_HANDLE_VALUE
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
|
Loading…
Reference in New Issue
Block a user