Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Typedefs | Functions
lock.h File Reference

Asterisk locking-related definitions: More...

#include <pthread.h>
#include <time.h>
#include <sys/param.h>
#include <execinfo.h>
#include "asterisk/backtrace.h"
#include "asterisk/logger.h"
#include "asterisk/compiler.h"
#include "asterisk/inline_api.h"

Go to the source code of this file.

Data Structures

struct  ast_lock_track
 Lock tracking information. More...
 
struct  ast_lock_track_flags
 
struct  ast_mutex_info
 Structure for mutex and tracking information. More...
 
struct  ast_rwlock_info
 Structure for rwlock and tracking information. More...
 

Macros

#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track)   scope ast_mutex_t mutex = init_val
 
#define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track)   scope ast_rwlock_t rwlock = init_val
 
#define __AST_RWLOCK_INIT_VALUE   PTHREAD_RWLOCK_INITIALIZER
 
#define AO2_DEADLOCK_AVOIDANCE(obj)
 
#define ast_cond_broadcast(cond)    __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
 
#define ast_cond_destroy(cond)    __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
 
#define ast_cond_init(cond, attr)    __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
 
#define ast_cond_signal(cond)    __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
 
#define ast_cond_timedwait(cond, mutex, time)   __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
 
#define ast_cond_wait(cond, mutex)    __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
 
#define AST_LOCK_TRACK_INIT_VALUE   { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_MUTEX_INIT_VALUE }
 
#define AST_MAX_REENTRANCY   10
 
#define AST_MUTEX_DEFINE_STATIC(mutex)   __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE, 1)
 
#define AST_MUTEX_DEFINE_STATIC_NOTRACKING(mutex)   __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE_NOTRACKING, 0)
 
#define ast_mutex_destroy(a)    __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
 
#define ast_mutex_init(pmutex)    __ast_pthread_mutex_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
 
#define ast_mutex_init_notracking(pmutex)   __ast_pthread_mutex_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
 
#define AST_MUTEX_INIT_VALUE   { PTHREAD_MUTEX_INIT_VALUE, NULL, {1, 0} }
 
#define AST_MUTEX_INIT_VALUE_NOTRACKING   { PTHREAD_MUTEX_INIT_VALUE, NULL, {0, 0} }
 
#define AST_MUTEX_INITIALIZER   __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
 
#define AST_MUTEX_KIND   PTHREAD_MUTEX_RECURSIVE_NP
 
#define ast_mutex_lock(a)    __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
 
#define ast_mutex_trylock(a)    __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
 
#define ast_mutex_unlock(a)    __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
 
#define AST_PTHREADT_NULL   (pthread_t) -1
 
#define AST_PTHREADT_STOP   (pthread_t) -2
 
#define AST_RWLOCK_DEFINE_STATIC(rwlock)   __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE, 1)
 
#define AST_RWLOCK_DEFINE_STATIC_NOTRACKING(rwlock)   __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE_NOTRACKING, 0)
 
#define ast_rwlock_destroy(rwlock)    __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
 
#define ast_rwlock_init(rwlock)    __ast_rwlock_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
 wrapper for rwlock with tracking enabled More...
 
#define ast_rwlock_init_notracking(rwlock)   __ast_rwlock_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
 wrapper for ast_rwlock_init with tracking disabled More...
 
#define AST_RWLOCK_INIT_VALUE   { __AST_RWLOCK_INIT_VALUE, NULL, {1, 0} }
 
#define AST_RWLOCK_INIT_VALUE_NOTRACKING   { __AST_RWLOCK_INIT_VALUE, NULL, {0, 0} }
 
#define ast_rwlock_rdlock(a)    __ast_rwlock_rdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
 
#define ast_rwlock_timedrdlock(a, b)    __ast_rwlock_timedrdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a, b)
 
#define ast_rwlock_timedwrlock(a, b)    __ast_rwlock_timedwrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a, b)
 
#define ast_rwlock_tryrdlock(a)    __ast_rwlock_tryrdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
 
#define ast_rwlock_trywrlock(a)    __ast_rwlock_trywrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
 
#define ast_rwlock_unlock(a)    __ast_rwlock_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
 
#define ast_rwlock_wrlock(a)    __ast_rwlock_wrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
 
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
 
#define DEADLOCK_AVOIDANCE(lock)
 
#define DLA_LOCK(lock)   ast_mutex_lock(lock)
 
#define DLA_UNLOCK(lock)   ast_mutex_unlock(lock)
 
#define gethostbyname   __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
 
#define pthread_cond_broadcast   use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
 
#define pthread_cond_destroy   use_ast_cond_destroy_instead_of_pthread_cond_destroy
 
#define pthread_cond_init   use_ast_cond_init_instead_of_pthread_cond_init
 
#define pthread_cond_signal   use_ast_cond_signal_instead_of_pthread_cond_signal
 
#define pthread_cond_t   use_ast_cond_t_instead_of_pthread_cond_t
 
#define pthread_cond_timedwait   use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
 
#define pthread_cond_wait   use_ast_cond_wait_instead_of_pthread_cond_wait
 
#define pthread_create   __use_ast_pthread_create_instead__
 
#define pthread_mutex_destroy   use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
 
#define pthread_mutex_init   use_ast_mutex_init_instead_of_pthread_mutex_init
 
#define PTHREAD_MUTEX_INIT_VALUE   PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
#define pthread_mutex_lock   use_ast_mutex_lock_instead_of_pthread_mutex_lock
 
#define pthread_mutex_t   use_ast_mutex_t_instead_of_pthread_mutex_t
 
#define pthread_mutex_trylock   use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
 
#define pthread_mutex_unlock   use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
 
#define ROFFSET   ((lt->reentrancy > 0) ? (lt->reentrancy-1) : 0)
 
#define SCOPED_AO2LOCK(varname, obj)   SCOPED_LOCK(varname, (obj), ao2_lock, ao2_unlock)
 scoped lock specialization for ao2 mutexes.
 
#define SCOPED_AO2RDLOCK(varname, obj)   SCOPED_LOCK(varname, (obj), ao2_rdlock, ao2_unlock)
 scoped lock specialization for ao2 read locks.
 
#define SCOPED_AO2WRLOCK(varname, obj)   SCOPED_LOCK(varname, (obj), ao2_wrlock, ao2_unlock)
 scoped lock specialization for ao2 write locks.
 
#define SCOPED_CHANNELLOCK(varname, chan)   SCOPED_LOCK(varname, (chan), ast_channel_lock, ast_channel_unlock)
 scoped lock specialization for channels.
 
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)   RAII_VAR(typeof((lock)), varname, ({lockfunc((lock)); (lock); }), unlockfunc)
 Scoped Locks. More...
 
#define SCOPED_MUTEX(varname, lock)   SCOPED_LOCK(varname, (lock), ast_mutex_lock, ast_mutex_unlock)
 scoped lock specialization for mutexes
 
#define SCOPED_RDLOCK(varname, lock)   SCOPED_LOCK(varname, (lock), ast_rwlock_rdlock, ast_rwlock_unlock)
 scoped lock specialization for read locks
 
#define SCOPED_WRLOCK(varname, lock)   SCOPED_LOCK(varname, (lock), ast_rwlock_wrlock, ast_rwlock_unlock)
 scoped lock specialization for write locks
 

Typedefs

typedef pthread_cond_t ast_cond_t
 
typedef struct ast_mutex_info ast_mutex_t
 
typedef struct ast_rwlock_info ast_rwlock_t
 

Functions

int __ast_cond_broadcast (const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond)
 
int __ast_cond_destroy (const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond)
 
int __ast_cond_init (const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
 
int __ast_cond_signal (const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond)
 
int __ast_cond_timedwait (const char *filename, int lineno, const char *func, const char *cond_name, const char *mutex_name, ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
 
int __ast_cond_wait (const char *filename, int lineno, const char *func, const char *cond_name, const char *mutex_name, ast_cond_t *cond, ast_mutex_t *t)
 
int __ast_pthread_mutex_destroy (const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
 
int __ast_pthread_mutex_init (int tracking, const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
 
int __ast_pthread_mutex_lock (const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
 
int __ast_pthread_mutex_trylock (const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
 
int __ast_pthread_mutex_unlock (const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
 
int __ast_rwlock_destroy (const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t)
 
int __ast_rwlock_init (int tracking, const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t)
 
int __ast_rwlock_rdlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
 
int __ast_rwlock_timedrdlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout)
 
int __ast_rwlock_timedwrlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout)
 
int __ast_rwlock_tryrdlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
 
int __ast_rwlock_trywrlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
 
int __ast_rwlock_unlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
 
int __ast_rwlock_wrlock (const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
 
#define ast_atomic_fetch_add(ptr, val, memorder)   __atomic_fetch_add((ptr), (val), (memorder))
 Support for atomic instructions. More...
 
#define ast_atomic_add_fetch(ptr, val, memorder)   __atomic_add_fetch((ptr), (val), (memorder))
 
#define ast_atomic_fetch_sub(ptr, val, memorder)   __atomic_fetch_sub((ptr), (val), (memorder))
 
#define ast_atomic_sub_fetch(ptr, val, memorder)   __atomic_sub_fetch((ptr), (val), (memorder))
 
#define ast_atomic_fetch_and(ptr, val, memorder)   __atomic_fetch_and((ptr), (val), (memorder))
 
#define ast_atomic_and_fetch(ptr, val, memorder)   __atomic_and_fetch((ptr), (val), (memorder))
 
#define ast_atomic_fetch_or(ptr, val, memorder)    __atomic_fetch_or((ptr), (val), (memorder))
 
#define ast_atomic_or_fetch(ptr, val, memorder)    __atomic_or_fetch((ptr), (val), (memorder))
 
#define ast_atomic_fetch_xor(ptr, val, memorder)   __atomic_fetch_xor((ptr), (val), (memorder))
 
#define ast_atomic_xor_fetch(ptr, val, memorder)   __atomic_xor_fetch((ptr), (val), (memorder))
 
#define ast_atomic_flag_set(ptr, val, memorder)    ast_atomic_fetch_or((ptr), (val), (memorder))
 
#define ast_atomic_flag_clear(ptr, val, memorder)   ast_atomic_fetch_and((ptr), ~(val), (memorder))
 
int ast_atomic_fetchadd_int (volatile int *p, int v)
 Atomically add v to *p and return the previous value of *p. More...
 
int ast_atomic_dec_and_test (volatile int *p)
 decrement *p by 1 and return true if the variable has reached 0. More...
 

Detailed Description

Asterisk locking-related definitions:

Magic number.

This is used to verify that a pointer is a valid astobj2 or ao2_weak reference.

Note
This field is constant after object creation. It shares a uint32_t with options and lockused.
Warning
Stealing bits for any additional writable fields would cause reentrancy issues if using bitfields. If any additional writable bits are required in the future we will need to put all bitfields into a single 'uint32_t flags' field and use atomic operations from to perform writes.

Definition in file lock.h.

Macro Definition Documentation

#define AO2_DEADLOCK_AVOIDANCE (   obj)
Value:
ao2_unlock(obj); \
usleep(1); \
ao2_lock(obj);

Definition at line 469 of file lock.h.

#define ast_atomic_fetch_add (   ptr,
  val,
  memorder 
)    __atomic_fetch_add((ptr), (val), (memorder))

Support for atomic instructions.

These macros implement a uniform interface to use built-in atomic functionality. If available __atomic built-ins are prefered. Legacy __sync built-ins are used as a fallback for older compilers.

Detailed documentation can be found in the GCC manual, all API's are modeled after the __atomic interfaces but using the namespace ast_atomic.

The memorder argument is always ignored by legacy __sync functions. Invalid memorder arguments do not produce errors unless __atomic functions are supported as the argument is erased by the preprocessor.

Note
ast_atomic_fetch_nand and ast_atomic_nand_fetch purposely do not exist. It's implementation was broken prior to gcc-4.4.

Atomic +=

Definition at line 669 of file lock.h.

#define ast_atomic_fetch_and (   ptr,
  val,
  memorder 
)    __atomic_fetch_and((ptr), (val), (memorder))

Atomic &=

Definition at line 677 of file lock.h.

#define ast_atomic_fetch_or (   ptr,
  val,
  memorder 
)    __atomic_fetch_or((ptr), (val), (memorder))

Atomic |=

Definition at line 681 of file lock.h.

#define ast_atomic_fetch_sub (   ptr,
  val,
  memorder 
)    __atomic_fetch_sub((ptr), (val), (memorder))

Atomic -=

Definition at line 673 of file lock.h.

#define ast_atomic_fetch_xor (   ptr,
  val,
  memorder 
)    __atomic_fetch_xor((ptr), (val), (memorder))

Atomic xor =

Definition at line 685 of file lock.h.

#define ast_atomic_flag_clear (   ptr,
  val,
  memorder 
)    ast_atomic_fetch_and((ptr), ~(val), (memorder))

Atomic flag clear

Definition at line 746 of file lock.h.

#define ast_atomic_flag_set (   ptr,
  val,
  memorder 
)    ast_atomic_fetch_or((ptr), (val), (memorder))

Atomic flag set

Definition at line 743 of file lock.h.

#define ast_rwlock_init (   rwlock)    __ast_rwlock_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)

wrapper for rwlock with tracking enabled

Returns
0 on success, non zero for error
Since
1.6.1

Definition at line 224 of file lock.h.

Referenced by _ast_hashtab_dup(), ast_context_find_or_create(), ast_hashtab_initlock(), ast_msg_init(), ast_refer_init(), ast_rtp_codecs_payloads_initialize(), ast_rtp_engine_init(), ast_translate_init(), and messaging_init().

#define ast_rwlock_init_notracking (   rwlock)    __ast_rwlock_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)

wrapper for ast_rwlock_init with tracking disabled

Returns
0 on success, non zero for error
Since
1.6.1

Definition at line 231 of file lock.h.

#define CHANNEL_DEADLOCK_AVOIDANCE (   chan)
Value:
ast_channel_unlock(chan); \
usleep(1); \
ast_channel_lock(chan);

Definition at line 474 of file lock.h.

#define SCOPED_LOCK (   varname,
  lock,
  lockfunc,
  unlockfunc 
)    RAII_VAR(typeof((lock)), varname, ({lockfunc((lock)); (lock); }), unlockfunc)

Scoped Locks.

Scoped locks provide a way to use RAII locks. In other words, declaration of a scoped lock will automatically define and lock the lock. When the lock goes out of scope, it will automatically be unlocked.

1 int some_function(struct ast_channel *chan)
2 {
3  SCOPED_LOCK(lock, chan, ast_channel_lock, ast_channel_unlock);
4 
5  if (!strcmp(ast_channel_name(chan, "foo")) {
6  return 0;
7  }
8 
9  return -1;
10 }

In the above example, neither return path requires explicit unlocking of the channel.

Note
Care should be taken when using SCOPED_LOCKS in conjunction with ao2 objects. ao2 objects should be unlocked before they are unreffed. Since SCOPED_LOCK runs once the variable goes out of scope, this can easily lead to situations where the variable gets unlocked after it is unreffed.
Parameters
varnameThe unique name to give to the scoped lock. You are not likely to reference this outside of the SCOPED_LOCK invocation.
lockThe variable to lock. This can be anything that can be passed to a locking or unlocking function.
lockfuncThe function to call to lock the lock
unlockfuncThe function to call to unlock the lock

Definition at line 583 of file lock.h.

Referenced by ast_bridge_basic_set_flags(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), bridge_basic_change_personality(), and remove_hooks_on_personality_change().

Function Documentation

int ast_atomic_dec_and_test ( volatile int *  p)
inline

decrement *p by 1 and return true if the variable has reached 0.

Useful e.g. to check if a refcount has reached 0.

Definition at line 767 of file lock.h.

Referenced by dispose_conf().

int ast_atomic_fetchadd_int ( volatile int *  p,
int  v 
)
inline