diff options
author | Benny Prijono <bennylp@teluu.com> | 2005-12-30 23:50:15 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2005-12-30 23:50:15 +0000 |
commit | 944562492d0c16b9e44ec4e1cc97657846d82cd0 (patch) | |
tree | 6e6c2e65e95e479384faeeaab4f525fa91cc7f27 /pjlib | |
parent | 9b86a2145e18cb843e69167b10f3c7414c11c634 (diff) |
Basic module, transport, and sending messages
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@106 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r-- | pjlib/include/pj/assert.h | 20 | ||||
-rw-r--r-- | pjlib/include/pj/os.h | 69 | ||||
-rw-r--r-- | pjlib/include/pj/sock.h | 4 | ||||
-rw-r--r-- | pjlib/include/pj/types.h | 3 | ||||
-rw-r--r-- | pjlib/src/pj/os_core_win32.c | 117 | ||||
-rw-r--r-- | pjlib/src/pj/sock_bsd.c | 5 |
6 files changed, 213 insertions, 5 deletions
diff --git a/pjlib/include/pj/assert.h b/pjlib/include/pj/assert.h index 5a842477..6814e4cd 100644 --- a/pjlib/include/pj/assert.h +++ b/pjlib/include/pj/assert.h @@ -67,6 +67,26 @@ # define PJ_ASSERT_RETURN(expr,retval) pj_assert(expr) #endif +/** + * @hideinitializer + * If #PJ_ENABLE_EXTRA_CHECK is declared and non-zero, then + * #PJ_ASSERT_ON_FAIL macro will evaluate the expression in @a expr during + * run-time. If the expression yields false, assertion will be triggered + * and @a exec_on_fail will be executed. + * + * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time + * checking will be performed. The macro simply evaluates to pj_assert(expr). + */ +#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0 +# define PJ_ASSERT_ON_FAIL(expr,exec_on_fail) \ + do { \ + pj_assert(expr); \ + if (!(expr)) exec_on_fail; \ + } while (0) +#else +# define PJ_ASSERT_ON_FAIL(expr,exec_on_fail) pj_assert(expr) +#endif + /** @} */ #endif /* __PJ_ASSERT_H__ */ diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h index 2917a2ab..8c04364d 100644 --- a/pjlib/include/pj/os.h +++ b/pjlib/include/pj/os.h @@ -507,6 +507,75 @@ PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex); /////////////////////////////////////////////////////////////////////////////// /** + * @defgroup PJ_RW_MUTEX Reader/Writer Mutex + * @ingroup PJ_OS + * @{ + * Reader/writer mutex is a classic synchronization object where multiple + * readers can acquire the mutex, but only a single writer can acquire the + * mutex. + */ +typedef struct pj_rwmutex_t pj_rwmutex_t; + +/** + * Create reader/writer mutex. + * + * @param pool Pool to allocate memory for the mutex. + * @param name Name to be assigned to the mutex. + * @param mutex Pointer to receive the newly created mutex. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name, + pj_rwmutex_t **mutex); + +/** + * Lock the mutex for reading. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex); + +/** + * Lock the mutex for writing. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex); + +/** + * Release read lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex); + +/** + * Release write lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex); + +/** + * Destroy reader/writer mutex. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex); + + +/** + * @} + */ + + +/////////////////////////////////////////////////////////////////////////////// +/** * @defgroup PJ_CRIT_SEC Critical sections. * @ingroup PJ_OS * @{ diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h index 02d88c1e..89883495 100644 --- a/pjlib/include/pj/sock.h +++ b/pjlib/include/pj/sock.h @@ -176,13 +176,13 @@ typedef struct pj_in_addr /** * This structure describes Internet socket address. */ -typedef struct pj_sockaddr_in +struct pj_sockaddr_in { pj_uint16_t sin_family; /**< Address family. */ pj_uint16_t sin_port; /**< Transport layer port number. */ pj_in_addr sin_addr; /**< IP address. */ char sin_zero[8]; /**< Padding. */ -} pj_sockaddr_in; +}; /** diff --git a/pjlib/include/pj/types.h b/pjlib/include/pj/types.h index 62e2c0f4..0099255f 100644 --- a/pjlib/include/pj/types.h +++ b/pjlib/include/pj/types.h @@ -218,6 +218,9 @@ typedef long pj_sock_t; /** Generic socket address. */ typedef void pj_sockaddr_t; +/** Forward declaration. */ +typedef struct pj_sockaddr_in pj_sockaddr_in; + /** Color type. */ typedef unsigned int pj_color_t; diff --git a/pjlib/src/pj/os_core_win32.c b/pjlib/src/pj/os_core_win32.c index 756b88a8..eac778f6 100644 --- a/pjlib/src/pj/os_core_win32.c +++ b/pjlib/src/pj/os_core_win32.c @@ -859,6 +859,123 @@ PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex) #endif /////////////////////////////////////////////////////////////////////////////// + +struct pj_rwmutex_t +{ + pj_mutex_t *read_lock, *write_lock; + int 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_mutex_create_recursive(pool, name, &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) + return status; + + mutex->reader_count++; + if (mutex->reader_count == 1) + pj_mutex_lock(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_mutex_lock(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) + return status; + + pj_assert(mutex->reader_count >= 1); + + --mutex->reader_count; + if (mutex->reader_count == 0) + pj_mutex_unlock(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); + return pj_mutex_unlock(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_mutex_destroy(mutex->write_lock); + return PJ_SUCCESS; +} + +/////////////////////////////////////////////////////////////////////////////// /* * pj_enter_critical_section() */ diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c index 5a096936..3ded3a54 100644 --- a/pjlib/src/pj/sock_bsd.c +++ b/pjlib/src/pj/sock_bsd.c @@ -187,7 +187,7 @@ PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr, { PJ_CHECK_STACK(); - PJ_ASSERT_RETURN(str_addr && str_addr->slen < PJ_MAX_HOSTNAME, + PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); addr->sin_family = AF_INET; @@ -224,8 +224,7 @@ PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, const pj_str_t *str_addr, pj_uint16_t port) { - PJ_ASSERT_RETURN(addr && str_addr, - (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); + PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); addr->sin_family = PJ_AF_INET; pj_sockaddr_in_set_port(addr, port); |