/*
The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef OSIP_MT
#ifdef ENABLE_MPATROL
#include <mpatrol.h>
#endif
#include <osip2/internal.h>
#include <osip2/osip_mt.h>
#include <osip2/osip_condv.h>
#if !defined(__VXWORKS_OS__) && !defined(__PSOS__) && \
!defined(WIN32) && !defined(_WIN32_WCE) && !defined(HAVE_PTHREAD_WIN32) && \
!defined(HAVE_PTHREAD) && !defined(HAVE_PTH_PTHREAD_H)
#error No thread implementation found!
#endif
#if defined(HAVE_PTHREAD) || defined(HAVE_PTH_PTHREAD_H) || defined(HAVE_PTHREAD_WIN32)
/*
#include <sys/types.h>
#include <sys/timeb.h>
*/
#include <pthread.h>
struct osip_cond *
osip_cond_init ()
{
osip_cond_t *cond = (osip_cond_t *) osip_malloc (sizeof (osip_cond_t));
if (cond && (pthread_cond_init (&cond->cv, NULL) == 0))
{
return (struct osip_cond *) (cond);
}
osip_free (cond);
return NULL;
}
int
osip_cond_destroy (struct osip_cond *_cond)
{
int ret;
if (!_cond)
return -1;
ret = pthread_cond_destroy (&_cond->cv);
osip_free (_cond);
return ret;
}
int
osip_cond_signal (struct osip_cond *_cond)
{
if (!_cond)
return -1;
return pthread_cond_signal (&_cond->cv);
}
int
osip_cond_wait (struct osip_cond *_cond, struct osip_mutex *_mut)
{
if (!_cond)
return -1;
return pthread_cond_wait (&_cond->cv, (pthread_mutex_t *) _mut);
}
int
osip_cond_timedwait (struct osip_cond *_cond, struct osip_mutex *_mut,
const struct timespec *abstime)
{
if (!_cond)
return -1;
return pthread_cond_timedwait (&_cond->cv, (pthread_mutex_t *) _mut,
(const struct timespec *) abstime);
}
#endif
#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32)
#include <sys/types.h>
#include <sys/timeb.h>
struct osip_cond *
osip_cond_init ()
{
osip_cond_t *cond = (osip_cond_t *) osip_malloc (sizeof (osip_cond_t));
if (cond && (cond->mut = osip_mutex_init ()) != NULL)
{
cond->sem = osip_sem_init (0); /* initially locked */
return (struct osip_cond *) (cond);
}
osip_free (cond);
return NULL;
}
int
osip_cond_destroy (struct osip_cond *_cond)
{
if (!_cond)
return 0;
if (_cond->sem == NULL)
return 0;
osip_sem_destroy (_cond->sem);
if (_cond->mut == NULL)
return 0;
osip_mutex_destroy (_cond->mut);
osip_free (_cond);
return (0);
}
int
osip_cond_signal (struct osip_cond *_cond)
{
if (!_cond)
return -1;
return osip_sem_post (_cond->sem);
}
int
osip_cond_wait (struct osip_cond *_cond, struct osip_mutex *_mut)
{
int ret1 = 0, ret2 = 0, ret3 = 0;
if (!_cond)
return -1;
if (osip_mutex_lock (_cond->mut))
return -1;
if (osip_mutex_unlock (_mut))
return -1;
ret1 = osip_sem_wait (_cond->sem);
ret2 = osip_mutex_lock (_mut);
ret3 = osip_mutex_unlock (_cond->mut);
if (ret1 || ret2 || ret3)
return -1;
return 0;
}
#define OSIP_CLOCK_REALTIME 4002
int
__osip_clock_gettime (unsigned int clock_id, struct timespec *tp)
{
struct _timeb time_val;
if (clock_id != OSIP_CLOCK_REALTIME)
return -1;
if (tp == NULL)
return -1;
_ftime (&time_val);
tp->tv_sec = (long) time_val.time;
tp->tv_nsec = time_val.millitm * 1000000;
return 0;
}
static int
_delta_time (const struct timespec *start, const struct timespec *end)
{
int difx;
if (start == NULL || end == NULL)
return 0;
difx = ((end->tv_sec - start->tv_sec) * 1000) +
((end->tv_nsec - start->tv_nsec) / 1000000);
return difx;
}
int
osip_cond_timedwait (struct osip_cond *_cond, struct osip_mutex *_mut,
const struct timespec *abstime)
{
DWORD dwRet;
struct timespec now;
int timeout_ms;
HANDLE sem;
if (!_cond)
return -1;
sem = *((HANDLE *) _cond->sem);
if (sem == NULL)
return -1;
if (abstime == NULL)
return -1;
__osip_clock_gettime (OSIP_CLOCK_REALTIME, &now);
timeout_ms = _delta_time (&now, abstime);
if (timeout_ms <= 0)
return 1; /* ETIMEDOUT; */
if (osip_mutex_unlock (_mut))
return -1;
dwRet = WaitForSingleObject (sem, timeout_ms);
if (osip_mutex_lock (_mut))
return -1;
switch (dwRet)
{
case WAIT_OBJECT_0:
return 0;
break;
case WAIT_TIMEOUT:
return 1; /* ETIMEDOUT; */
break;
default:
return -1;
break;
}
}
#endif
#ifdef __PSOS__
/*TODO*/
#endif
/* use VxWorks implementation */
#ifdef __VXWORKS_OS__
struct osip_cond *
osip_cond_init ()
{
osip_cond_t *cond = (osip_cond_t *) osip_malloc (sizeof (osip_cond_t));
if ((cond->sem = osip_sem_init (0)) != NULL)
{
return (struct osip_cond *) (cond);
}
osip_free (cond);
return NULL;
}
int
osip_cond_destroy (struct osip_cond *_cond)
{
if (_cond->sem == NULL)
return 0;
osip_sem_destroy (_cond->sem);
osip_free (_cond);
return (0);
}
int
osip_cond_signal (struct osip_cond *_cond)
{
return osip_sem_post (_cond->sem);
}
+static int
_cond_wait (struct osip_cond *_cond, struct osip_mutex *_mut, int ticks)
{
int ret;
if (osip_mutex_unlock (_mut) != 0)
{
return -1;
}
ret = semTake (((osip_sem_t *) _cond->sem)->semId, ticks);
if (ret != OK)
{
switch (errno)
{
case S_objLib_OBJ_ID_ERROR:
/* fall through */
case S_objLib_OBJ_UNAVAILABLE:
/* fall through */
#if 0
case S_intLib_NOT_ISR_CALLABLE:
#endif
ret = -1;
break;
case S_objLib_OBJ_TIMEOUT:
ret = 1;
break;
default: /* vxworks has bugs */
ret = 1;
break;
}
}
if (osip_mutex_lock (_mut))
{
ret = -1;
}
return ret;
}
int
osip_cond_wait (struct osip_cond *_cond, struct osip_mutex *_mut)
{
return _cond_wait (_cond, _mut, WAIT_FOREVER);
}
int
osip_cond_timedwait (struct osip_cond *_cond, struct osip_mutex *_mut,
const struct timespec *abstime)
{
int rate = sysClkRateGet ();
struct timespec now;
long sec, nsec;
int ticks;
SEM_ID sem;
if (_cond == NULL)
return -1;
sem = ((osip_sem_t *) _cond->sem)->semId;
if (sem == NULL)
return -1;
if (abstime == NULL)
return -1;
clock_gettime (CLOCK_REALTIME, &now);
sec = abstime->tv_sec - now.tv_sec;
nsec = abstime->tv_nsec - now.tv_nsec;
while ((sec > 0) && (nsec < 0))
{
--sec;
nsec += 1000000000;
}
if (nsec < 0)
return 1; /*ETIMEDOUT; */
ticks = (sec * rate) + (nsec / 1000 * rate / 1000000);
return _cond_wait (_cond, _mut, ticks);
}
#endif
#endif /* #ifdef OSIP_MT */
syntax highlighted by Code2HTML, v. 0.9.1