summaryrefslogtreecommitdiff
path: root/pjlib/src/pj
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-05-10 19:24:40 +0000
committerBenny Prijono <bennylp@teluu.com>2006-05-10 19:24:40 +0000
commit50a501dbe89ec8f9a76540015890dd361f1ec8a1 (patch)
treea45dac4292320647ed297b35239fccf38eb5885b /pjlib/src/pj
parent5f10c756ac9d5f48efe2adbcccf5d54634540d61 (diff)
Merge-in RTEMS port patch by Phil Torre <ptorre@zetron.com>, alpha release.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@433 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pj')
-rw-r--r--pjlib/src/pj/hash.c7
-rw-r--r--pjlib/src/pj/ioqueue_common_abs.c2
-rw-r--r--pjlib/src/pj/ioqueue_select.c48
-rw-r--r--pjlib/src/pj/os_core_unix.c127
-rw-r--r--pjlib/src/pj/os_rwmutex.c162
-rw-r--r--pjlib/src/pj/os_time_unix.c15
-rw-r--r--pjlib/src/pj/os_timestamp_posix.c (renamed from pjlib/src/pj/os_timestamp_linux.c)0
-rw-r--r--pjlib/src/pj/pool.c5
-rw-r--r--pjlib/src/pj/sock_bsd.c6
9 files changed, 338 insertions, 34 deletions
diff --git a/pjlib/src/pj/hash.c b/pjlib/src/pj/hash.c
index 0495fadc..1f86317b 100644
--- a/pjlib/src/pj/hash.c
+++ b/pjlib/src/pj/hash.c
@@ -49,20 +49,21 @@ struct pj_hash_table_t
-PJ_DEF(pj_uint32_t) pj_hash_calc(pj_uint32_t hash, const void *key, unsigned keylen)
+PJ_DEF(pj_uint32_t) pj_hash_calc(pj_uint32_t hash, const void *key,
+ unsigned keylen)
{
PJ_CHECK_STACK();
if (keylen==PJ_HASH_KEY_STRING) {
const unsigned char *p = key;
for ( ; *p; ++p ) {
- hash = hash * PJ_HASH_MULTIPLIER + *p;
+ hash = (hash * PJ_HASH_MULTIPLIER) + *p;
}
} else {
const unsigned char *p = key,
*end = p + keylen;
for ( ; p!=end; ++p) {
- hash = hash * PJ_HASH_MULTIPLIER + *p;
+ hash = (hash * PJ_HASH_MULTIPLIER) + *p;
}
}
return hash;
diff --git a/pjlib/src/pj/ioqueue_common_abs.c b/pjlib/src/pj/ioqueue_common_abs.c
index b128d810..60a2b21d 100644
--- a/pjlib/src/pj/ioqueue_common_abs.c
+++ b/pjlib/src/pj/ioqueue_common_abs.c
@@ -237,7 +237,7 @@ void ioqueue_dispatch_write_event(pj_ioqueue_t *ioqueue, pj_ioqueue_key_t *h)
socklen_t addrlen = sizeof(addr);
gp_rc = getpeername(h->fd, (struct sockaddr*)&addr, &addrlen);
- bytes_transfered = gp_rc;
+ bytes_transfered = (gp_rc < 0) ? gp_rc : -gp_rc;
}
#endif
diff --git a/pjlib/src/pj/ioqueue_select.c b/pjlib/src/pj/ioqueue_select.c
index 4aa4f910..33fcae7d 100644
--- a/pjlib/src/pj/ioqueue_select.c
+++ b/pjlib/src/pj/ioqueue_select.c
@@ -93,6 +93,12 @@ PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp);
*/
#define VALIDATE_FD_SET 0
+#if 0
+# define TRACE__(args) PJ_LOG(3,args)
+#else
+# define TRACE__(args)
+#endif
+
/*
* This describes each key.
*/
@@ -108,8 +114,9 @@ struct pj_ioqueue_t
{
DECLARE_COMMON_IOQUEUE
- unsigned max, count;
- pj_ioqueue_key_t active_list;
+ unsigned max, count; /* Max and current key count */
+ int nfds; /* The largest fd value (for select)*/
+ pj_ioqueue_key_t active_list; /* List of active keys. */
pj_fd_set_t rfdset;
pj_fd_set_t wfdset;
#if PJ_HAS_TCP
@@ -136,6 +143,32 @@ PJ_DEF(const char*) pj_ioqueue_name(void)
return "select";
}
+/*
+ * Scan the socket descriptor sets for the largest descriptor.
+ * This value is needed by select().
+ */
+#if defined(PJ_SELECT_NEEDS_NFDS) && PJ_SELECT_NEEDS_NFDS!=0
+static void rescan_fdset(pj_ioqueue_t *ioqueue)
+{
+ pj_ioqueue_key_t *key = ioqueue->active_list.next;
+ int max = 0;
+
+ while (key != &ioqueue->active_list) {
+ if (key->fd > max)
+ max = key->fd;
+ key = key->next;
+ }
+
+ ioqueue->nfds = max;
+}
+#else
+static void rescan_fdset(pj_ioqueue_t *ioqueue)
+{
+ ioqueue->nfds = FD_SETSIZE-1;
+}
+#endif
+
+
/*
* pj_ioqueue_create()
*
@@ -172,6 +205,8 @@ PJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,
#endif
pj_list_init(&ioqueue->active_list);
+ rescan_fdset(ioqueue);
+
#if PJ_IOQUEUE_HAS_SAFE_UNREG
/* When safe unregistration is used (the default), we pre-create
* all keys and put them in the free list.
@@ -332,6 +367,9 @@ PJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
pj_list_insert_before(&ioqueue->active_list, key);
++ioqueue->count;
+ /* Rescan fdset to get max descriptor */
+ rescan_fdset(ioqueue);
+
on_return:
/* On error, socket may be left in non-blocking mode. */
*p_key = key;
@@ -368,6 +406,8 @@ static void decrement_counter(pj_ioqueue_key_t *key)
pj_lock_acquire(key->ioqueue->lock);
pj_list_erase(key);
pj_list_push_back(&key->ioqueue->closing_list, key);
+ /* Rescan fdset to get max descriptor */
+ rescan_fdset(key->ioqueue);
pj_lock_release(key->ioqueue->lock);
}
pj_mutex_unlock(key->ioqueue->ref_cnt_mutex);
@@ -611,6 +651,7 @@ PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)
scan_closing_keys(ioqueue);
#endif
pj_lock_release(ioqueue->lock);
+ TRACE__((THIS_FILE, " poll: no fd is set"));
if (timeout)
pj_thread_sleep(PJ_TIME_VAL_MSEC(*timeout));
return 0;
@@ -632,7 +673,8 @@ PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)
/* Unlock ioqueue before select(). */
pj_lock_release(ioqueue->lock);
- count = pj_sock_select(FD_SETSIZE, &rfdset, &wfdset, &xfdset, timeout);
+ count = pj_sock_select(ioqueue->nfds+1, &rfdset, &wfdset, &xfdset,
+ timeout);
if (count <= 0)
return -pj_get_netos_error();
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index ad9f6143..d37c142b 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -16,6 +16,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+/*
+ * Contributors:
+ * - Thanks for Zetron, Inc. (Phil Torre, ptorre@zetron.com) for donating
+ * the RTEMS port.
+ */
#define _GNU_SOURCE
#include <pj/os.h>
#include <pj/assert.h>
@@ -153,7 +158,7 @@ PJ_DEF(pj_status_t) pj_init(void)
}
#endif
- PJ_LOG(4,(THIS_FILE, "pjlib %s for Unix initialized",
+ PJ_LOG(4,(THIS_FILE, "pjlib %s for POSIX initialized",
PJ_VERSION));
return PJ_SUCCESS;
@@ -196,6 +201,8 @@ PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
// has been deleted by application.
//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);
//return PJ_SUCCESS;
+ PJ_LOG(4,(THIS_FILE, "Info: possibly re-registering existing "
+ "thread"));
}
/* Initialize and set the thread entry. */
@@ -281,6 +288,7 @@ static void *thread_main(void *param)
/* Done. */
PJ_LOG(6,(rec->obj_name, "Thread quitting"));
+
return result;
}
#endif
@@ -298,15 +306,18 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
{
#if PJ_HAS_THREADS
pj_thread_t *rec;
+ pthread_attr_t thread_attr;
+ void *stack_addr;
int rc;
+ PJ_UNUSED_ARG(stack_addr);
+
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);
/* Create thread record and assign name for the thread */
rec = (struct pj_thread_t*) pj_pool_zalloc(pool, sizeof(pj_thread_t));
- if (!rec)
- return PJ_ENOMEM;
+ PJ_ASSERT_RETURN(rec, PJ_ENOMEM);
/* Set name. */
if (!thread_name)
@@ -319,32 +330,61 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
rec->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
}
+ /* Set default stack size */
+ if (stack_size == 0)
+ stack_size = PJ_THREAD_DEFAULT_STACK_SIZE;
+
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
- rec->stk_size = stack_size ? stack_size : 0xFFFFFFFFUL;
+ rec->stk_size = stack_size;
rec->stk_max_usage = 0;
#endif
/* Emulate suspended thread with mutex. */
if (flags & PJ_THREAD_SUSPENDED) {
rc = pj_mutex_create_simple(pool, NULL, &rec->suspended_mutex);
- if (rc != PJ_SUCCESS)
+ if (rc != PJ_SUCCESS) {
return rc;
+ }
pj_mutex_lock(rec->suspended_mutex);
} else {
pj_assert(rec->suspended_mutex == NULL);
}
- PJ_LOG(6, (rec->obj_name, "Thread created"));
+
+ /* Init thread attributes */
+ pthread_attr_init(&thread_attr);
+
+#if defined(PJ_THREAD_SET_STACK_SIZE) && PJ_THREAD_SET_STACK_SIZE!=0
+ /* Set thread's stack size */
+ rc = pthread_attr_setstacksize(&thread_attr, stack_size);
+ if (rc != 0)
+ return PJ_RETURN_OS_ERROR(rc);
+#endif /* PJ_THREAD_SET_STACK_SIZE */
+
+
+#if defined(PJ_THREAD_ALLOCATE_STACK) && PJ_THREAD_ALLOCATE_STACK!=0
+ /* Allocate memory for the stack */
+ stack_addr = pj_pool_alloc(pool, stack_size);
+ PJ_ASSERT_RETURN(stack_addr, PJ_ENOMEM);
+
+ rc = pthread_attr_setstackaddr(&thread_attr, stack_addr);
+ if (rc != 0)
+ return PJ_RETURN_OS_ERROR(rc);
+#endif /* PJ_THREAD_ALLOCATE_STACK */
+
/* Create the thread. */
rec->proc = proc;
rec->arg = arg;
- rc = pthread_create( &rec->thread, NULL, thread_main, rec);
- if (rc != 0)
+ rc = pthread_create( &rec->thread, &thread_attr, &thread_main, rec);
+ if (rc != 0) {
return PJ_RETURN_OS_ERROR(rc);
+ }
*ptr_thread = rec;
+
+ PJ_LOG(6, (rec->obj_name, "Thread created"));
return PJ_SUCCESS;
#else
pj_assert(!"Threading is disabled!");
@@ -423,8 +463,13 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
if (result == 0)
return PJ_SUCCESS;
- else
- return PJ_RETURN_OS_ERROR(result);
+ else {
+ /* Calling pthread_join() on a thread that no longer exists and
+ * getting back ESRCH isn't an error (in this context).
+ * Thanks Phil Torre <ptorre@zetron.com>.
+ */
+ return result==ESRCH ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(result);
+ }
#else
PJ_CHECK_STACK();
pj_assert(!"No multithreading support!");
@@ -437,10 +482,14 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
*/
PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)
{
- /* This function is used to destroy thread handle in other platforms.
- * I suppose there's nothing to do here..
- */
PJ_CHECK_STACK();
+
+ /* Destroy mutex used to suspend thread */
+ if (p->suspended_mutex) {
+ pj_mutex_destroy(p->suspended_mutex);
+ p->suspended_mutex = NULL;
+ }
+
return PJ_SUCCESS;
}
@@ -449,8 +498,26 @@ PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)
*/
PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
{
+/* TODO: should change this to something like PJ_OS_HAS_NANOSLEEP */
+#if defined(PJ_RTEMS) && PJ_RTEMS!=0
+ enum { NANOSEC_PER_MSEC = 1000000 };
+ struct timespec req;
+
PJ_CHECK_STACK();
- return usleep(msec * 1000);
+ req.tv_sec = msec / 1000;
+ req.tv_nsec = (msec % 1000) * NANOSEC_PER_MSEC;
+
+ if (nanosleep(&req, NULL) == 0)
+ return PJ_SUCCESS;
+
+ return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#else
+ PJ_CHECK_STACK();
+ if (usleep(msec * 1000) == 0)
+ return PJ_SUCCESS;
+
+ return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#endif /* PJ_RTEMS */
}
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
@@ -513,8 +580,7 @@ PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,
{
pj_status_t rc;
pj_atomic_t *atomic_var = pj_pool_calloc(pool, 1, sizeof(pj_atomic_t));
- if (!atomic_var)
- return PJ_ENOMEM;
+ PJ_ASSERT_RETURN(atomic_var, PJ_ENOMEM);
#if PJ_HAS_THREADS
rc = pj_mutex_create(pool, "atm%p", PJ_MUTEX_SIMPLE, &atomic_var->mutex);
@@ -765,12 +831,16 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
PJ_CHECK_STACK();
- pthread_mutexattr_init(&attr);
+ rc = pthread_mutexattr_init(&attr);
+ if (rc != 0)
+ return PJ_RETURN_OS_ERROR(rc);
if (type == PJ_MUTEX_SIMPLE) {
#if defined(PJ_LINUX) && PJ_LINUX!=0
extern int pthread_mutexattr_settype(pthread_mutexattr_t*,int);
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_FAST_NP);
+#elif defined(PJ_RTEMS) && PJ_RTEMS!=0
+ /* Nothing to do, default is simple */
#else
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
#endif
@@ -778,6 +848,13 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
#if defined(PJ_LINUX) && PJ_LINUX!=0
extern int pthread_mutexattr_settype(pthread_mutexattr_t*,int);
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#elif defined(PJ_RTEMS) && PJ_RTEMS!=0
+ // Phil Torre <ptorre@zetron.com>:
+ // The RTEMS implementation of POSIX mutexes doesn't include
+ // pthread_mutexattr_settype(), so what follows is a hack
+ // until I get RTEMS patched to support the set/get functions.
+ PJ_TODO(FIX_RTEMS_RECURSIVE_MUTEX_TYPE)
+ attr.recursive = 1;
#else
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#endif
@@ -831,7 +908,7 @@ PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
PJ_ASSERT_RETURN(pool && ptr_mutex, PJ_EINVAL);
mutex = pj_pool_alloc(pool, sizeof(*mutex));
- if (!mutex) return PJ_ENOMEM;
+ PJ_ASSERT_RETURN(mutex, PJ_ENOMEM);
if ((rc=init_mutex(mutex, name, type)) != PJ_SUCCESS)
return rc;
@@ -1002,6 +1079,13 @@ PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
#endif
///////////////////////////////////////////////////////////////////////////////
+/*
+ * Include Read/Write mutex emulation for POSIX platforms that lack it (e.g.
+ * RTEMS). Otherwise use POSIX rwlock.
+ */
+#if defined(PJ_EMULATE_RWMUTEX) && PJ_EMULATE_RWMUTEX!=0
+# include "os_rwmutex.c"
+#else
struct pj_rwmutex_t
{
pthread_rwlock_t rwlock;
@@ -1095,6 +1179,9 @@ PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
return PJ_SUCCESS;
}
+#endif /* PJ_EMULATE_RWMUTEX */
+
+
///////////////////////////////////////////////////////////////////////////////
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
@@ -1113,8 +1200,8 @@ PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(pool != NULL && ptr_sem != NULL, PJ_EINVAL);
- sem = pj_pool_alloc(pool, sizeof(*sem));
- if (!sem) return PJ_ENOMEM;
+ sem = pj_pool_alloc(pool, sizeof(*sem));
+ PJ_ASSERT_RETURN(sem, PJ_ENOMEM);
if (sem_init( &sem->sem, 0, initial) != 0)
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
diff --git a/pjlib/src/pj/os_rwmutex.c b/pjlib/src/pj/os_rwmutex.c
new file mode 100644
index 00000000..2ec147f0
--- /dev/null
+++ b/pjlib/src/pj/os_rwmutex.c
@@ -0,0 +1,162 @@
+/* $Id$ */
+/*
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Note:
+ *
+ * DO NOT BUILD THIS FILE DIRECTLY. THIS FILE WILL BE INCLUDED BY os_core_*.c
+ * WHEN MACRO PJ_EMULATE_RWMUTEX IS SET.
+ */
+
+/*
+ * os_rwmutex.c:
+ *
+ * Implementation of Read-Write mutex for platforms that lack it (e.g.
+ * Win32, RTEMS).
+ */
+
+
+struct pj_rwmutex_t
+{
+ pj_mutex_t *read_lock;
+ /* write_lock must use semaphore, because write_lock may be released
+ * by thread other than the thread that acquire the write_lock in the
+ * first place.
+ */
+ pj_sem_t *write_lock;
+ pj_int32_t reader_count;
+};
+
+/*
+ * Create reader/writer mutex.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
+ pj_rwmutex_t **p_mutex)
+{
+ pj_status_t status;
+ pj_rwmutex_t *rwmutex;
+
+ PJ_ASSERT_RETURN(pool && p_mutex, PJ_EINVAL);
+
+ *p_mutex = NULL;
+ rwmutex = pj_pool_alloc(pool, sizeof(struct pj_rwmutex_t));
+
+ status = pj_mutex_create_simple(pool, name, &rwmutex ->read_lock);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pj_sem_create(pool, name, 1, 1, &rwmutex->write_lock);
+ if (status != PJ_SUCCESS) {
+ pj_mutex_destroy(rwmutex->read_lock);
+ return status;
+ }
+
+ rwmutex->reader_count = 0;
+ *p_mutex = rwmutex;
+ return PJ_SUCCESS;
+}
+
+/*
+ * Lock the mutex for reading.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)
+{
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+ status = pj_mutex_lock(mutex->read_lock);
+ if (status != PJ_SUCCESS) {
+ pj_assert(!"This pretty much is unexpected");
+ return status;
+ }
+
+ mutex->reader_count++;
+
+ pj_assert(mutex->reader_count < 0x7FFFFFF0L);
+
+ if (mutex->reader_count == 1)
+ pj_sem_wait(mutex->write_lock);
+
+ status = pj_mutex_unlock(mutex->read_lock);
+ return status;
+}
+
+/*
+ * Lock the mutex for writing.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)
+{
+ PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+ return pj_sem_wait(mutex->write_lock);
+}
+
+/*
+ * Release read lock.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)
+{
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+ status = pj_mutex_lock(mutex->read_lock);
+ if (status != PJ_SUCCESS) {
+ pj_assert(!"This pretty much is unexpected");
+ return status;
+ }
+
+ pj_assert(mutex->reader_count >= 1);
+
+ --mutex->reader_count;
+ if (mutex->reader_count == 0)
+ pj_sem_post(mutex->write_lock);
+
+ status = pj_mutex_unlock(mutex->read_lock);
+ return status;
+}
+
+/*
+ * Release write lock.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)
+{
+ PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+ pj_assert(mutex->reader_count <= 1);
+ return pj_sem_post(mutex->write_lock);
+}
+
+
+/*
+ * Destroy reader/writer mutex.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
+{
+ PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+ pj_mutex_destroy(mutex->read_lock);
+ pj_sem_destroy(mutex->write_lock);
+ return PJ_SUCCESS;
+}
+
diff --git a/pjlib/src/pj/os_time_unix.c b/pjlib/src/pj/os_time_unix.c
index b5733b64..081d97c8 100644
--- a/pjlib/src/pj/os_time_unix.c
+++ b/pjlib/src/pj/os_time_unix.c
@@ -17,23 +17,30 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pj/os.h>
+#include <pj/errno.h>
#include <pj/compat/time.h>
#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0
# include <unistd.h>
#endif
+#include <errno.h>
+
///////////////////////////////////////////////////////////////////////////////
PJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *p_tv)
{
- struct timeval tv;
+ struct timeval the_time;
+ int rc;
PJ_CHECK_STACK();
- gettimeofday(&tv, NULL);
- p_tv->sec = tv.tv_sec;
- p_tv->msec = tv.tv_usec / 1000;
+ rc = gettimeofday(&the_time, NULL);
+ if (rc != 0)
+ return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+
+ p_tv->sec = the_time.tv_sec;
+ p_tv->msec = the_time.tv_usec / 1000;
return PJ_SUCCESS;
}
diff --git a/pjlib/src/pj/os_timestamp_linux.c b/pjlib/src/pj/os_timestamp_posix.c
index 9d9ae8e5..9d9ae8e5 100644
--- a/pjlib/src/pj/os_timestamp_linux.c
+++ b/pjlib/src/pj/os_timestamp_posix.c
diff --git a/pjlib/src/pj/pool.c b/pjlib/src/pj/pool.c
index e5412d4b..a9f658c5 100644
--- a/pjlib/src/pj/pool.c
+++ b/pjlib/src/pj/pool.c
@@ -173,6 +173,11 @@ PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name,
PJ_CHECK_STACK();
+ /* If callback is NULL, set calback from the policy */
+ if (callback == NULL)
+ callback = f->policy.callback;
+
+ /* Allocate initial block */
buffer = (*f->policy.block_alloc)(f, initial_size);
if (!buffer)
return NULL;
diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c
index e207eeaa..37cb85e5 100644
--- a/pjlib/src/pj/sock_bsd.c
+++ b/pjlib/src/pj/sock_bsd.c
@@ -26,7 +26,7 @@
/*
* Address families conversion.
- * The values here are indexed based on pj_addr_family-0xFF00.
+ * The values here are indexed based on pj_addr_family.
*/
const pj_uint16_t PJ_AF_UNIX = AF_UNIX;
const pj_uint16_t PJ_AF_INET = AF_INET;
@@ -44,7 +44,7 @@ const pj_uint16_t PJ_AF_IRDA = 0xFFFF;
/*
* Socket types conversion.
- * The values here are indexed based on pj_sock_type-0xFF00
+ * The values here are indexed based on pj_sock_type
*/
const pj_uint16_t PJ_SOCK_STREAM = SOCK_STREAM;
const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
@@ -346,7 +346,7 @@ PJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sock,
{
PJ_CHECK_STACK();
- PJ_ASSERT_RETURN(addr && len > 0, PJ_EINVAL);
+ PJ_ASSERT_RETURN(addr && len >= sizeof(struct sockaddr_in), PJ_EINVAL);
if (bind(sock, (struct sockaddr*)addr, len) != 0)
return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());