Asterisk - The Open Source Telephony Project  GIT-master-09303e8
Data Structures | Functions | Variables
func_lock.c File Reference

Dialplan mutexes. More...

#include "asterisk.h"
#include <signal.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Data Structures

struct  channel_lock_frame
 
struct  lock_frame
 
struct  locklist
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int get_lock (struct ast_channel *chan, char *lockname, int trylock)
 
static int load_module (void)
 
static void lock_fixup (void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
 
static void lock_free (void *data)
 
static int lock_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int trylock_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int unload_module (void)
 
static int unlock_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Dialplan mutexes" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function lock_function
 
static const struct ast_datastore_info lock_info
 
static struct locklist locklist = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static struct ast_custom_function trylock_function
 
static int unloading = 0
 
static struct ast_custom_function unlock_function
 

Detailed Description

Dialplan mutexes.

Author
Tilghman Lesher func_.nosp@m.lock.nosp@m._2007.nosp@m.@the.nosp@m.-tilg.nosp@m.hman.nosp@m..com

Definition in file func_lock.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 477 of file func_lock.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 477 of file func_lock.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 477 of file func_lock.c.

◆ get_lock()

static int get_lock ( struct ast_channel chan,
char *  lockname,
int  trylock 
)
static

Definition at line 183 of file func_lock.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_name(), ast_cond_init, ast_cond_signal, ast_cond_timedwait, ast_datastore_alloc, ast_datastore_free(), ast_debug, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), channel_lock_frame::channel, lock_frame::cond, lock_frame::count, ast_datastore::data, lock_frame::entries, channel_lock_frame::list, channel_lock_frame::lock_frame, LOG_ERROR, lock_frame::mutex, lock_frame::name, NULL, lock_frame::owner, lock_frame::requesters, and unloading.

Referenced by lock_read(), and trylock_read().

184 {
185  struct ast_datastore *lock_store = ast_channel_datastore_find(chan, &lock_info, NULL);
186  struct lock_frame *current;
187  struct channel_lock_frame *clframe = NULL;
189  int res = 0;
190  struct timespec timeout = { 0, };
191  struct timeval now;
192 
193  if (!lock_store) {
194  ast_debug(1, "Channel %s has no lock datastore, so we're allocating one.\n", ast_channel_name(chan));
195  lock_store = ast_datastore_alloc(&lock_info, NULL);
196  if (!lock_store) {
197  ast_log(LOG_ERROR, "Unable to allocate new datastore. No locks will be obtained.\n");
198  return -1;
199  }
200 
201  list = ast_calloc(1, sizeof(*list));
202  if (!list) {
204  "Unable to allocate datastore list head. %sLOCK will fail.\n",
205  trylock ? "TRY" : "");
206  ast_datastore_free(lock_store);
207  return -1;
208  }
209 
210  lock_store->data = list;
211  AST_LIST_HEAD_INIT(list);
212  ast_channel_datastore_add(chan, lock_store);
213  } else
214  list = lock_store->data;
215 
216  /* Lock already exists? */
218  AST_LIST_TRAVERSE(&locklist, current, entries) {
219  if (strcmp(current->name, lockname) == 0) {
220  break;
221  }
222  }
223 
224  if (!current) {
225  if (unloading) {
226  /* Don't bother */
228  return -1;
229  }
230 
231  /* Create new lock entry */
232  current = ast_calloc(1, sizeof(*current) + strlen(lockname) + 1);
233  if (!current) {
235  return -1;
236  }
237 
238  strcpy(current->name, lockname); /* SAFE */
239  if ((res = ast_mutex_init(&current->mutex))) {
240  ast_log(LOG_ERROR, "Unable to initialize mutex: %s\n", strerror(res));
241  ast_free(current);
243  return -1;
244  }
245  if ((res = ast_cond_init(&current->cond, NULL))) {
246  ast_log(LOG_ERROR, "Unable to initialize condition variable: %s\n", strerror(res));
247  ast_mutex_destroy(&current->mutex);
248  ast_free(current);
250  return -1;
251  }
252  current->requesters = 0;
253  AST_LIST_INSERT_TAIL(&locklist, current, entries);
254  }
255  /* Add to requester list */
256  ast_mutex_lock(&current->mutex);
257  current->requesters++;
258  ast_mutex_unlock(&current->mutex);
260 
261  /* Found lock or created one - now find or create the corresponding link in the channel */
262  AST_LIST_LOCK(list);
263  AST_LIST_TRAVERSE(list, clframe, list) {
264  if (clframe->lock_frame == current) {
265  break;
266  }
267  }
268 
269  if (!clframe) {
270  if (unloading) {
271  /* Don't bother */
272  AST_LIST_UNLOCK(list);
273  return -1;
274  }
275 
276  if (!(clframe = ast_calloc(1, sizeof(*clframe)))) {
278  "Unable to allocate channel lock frame. %sLOCK will fail.\n",
279  trylock ? "TRY" : "");
280  AST_LIST_UNLOCK(list);
281  return -1;
282  }
283 
284  clframe->lock_frame = current;
285  clframe->channel = chan;
286  AST_LIST_INSERT_TAIL(list, clframe, list);
287  }
288  AST_LIST_UNLOCK(list);
289 
290  /* If we already own the lock, then we're being called recursively.
291  * Keep track of how many times that is, because we need to unlock
292  * the same amount, before we'll release this one.
293  */
294  if (current->owner == chan) {
295  /* We're not a requester, we already have it */
296  ast_mutex_lock(&current->mutex);
297  current->requesters--;
298  ast_mutex_unlock(&current->mutex);
299  current->count++;
300  return 0;
301  }
302 
303  /* Wait up to three seconds from now for LOCK. */
304  now = ast_tvnow();
305  timeout.tv_sec = now.tv_sec + 3;
306  timeout.tv_nsec = now.tv_usec * 1000;
307 
308  ast_mutex_lock(&current->mutex);
309 
310  res = 0;
311  while (!trylock && !res && current->owner) {
312  res = ast_cond_timedwait(&current->cond, &current->mutex, &timeout);
313  }
314  if (current->owner) {
315  /* timeout;
316  * trylock; or
317  * cond_timedwait failed.
318  *
319  * either way, we fail to obtain the lock.
320  */
321  res = -1;
322  } else {
323  current->owner = chan;
324  current->count++;
325  res = 0;
326  }
327  /* Remove from requester list */
328  current->requesters--;
329  if (res && unloading)
330  ast_cond_signal(&current->cond);
331  ast_mutex_unlock(&current->mutex);
332 
333  return res;
334 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:172
static int unloading
Definition: func_lock.c:112
struct lock_frame * lock_frame
Definition: func_lock.c:138
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static int timeout
Definition: cdr_mysql.c:86
#define ast_cond_init(cond, attr)
Definition: lock.h:199
unsigned int requesters
Definition: func_lock.c:127
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
Structure for a data store object.
Definition: datastore.h:68
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2390
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static const struct ast_datastore_info lock_info
Definition: func_lock.c:114
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
ast_mutex_t mutex
Definition: func_lock.c:122
ast_cond_t cond
Definition: func_lock.c:123
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char name[0]
Definition: func_lock.c:131
struct channel_lock_frame::@206 list
void * data
Definition: datastore.h:70
struct ast_channel * owner
Definition: func_lock.c:129
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * channel
Definition: func_lock.c:137
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2376
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
unsigned int count
Definition: func_lock.c:125
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ load_module()

static int load_module ( void  )
static

Definition at line 468 of file func_lock.c.

References AST_CFE_READ, and ast_custom_function_register_escalating.

469 {
473 
474  return res;
475 }
static struct ast_custom_function trylock_function
Definition: func_lock.c:418
#define ast_custom_function_register_escalating(acf, escalation)
Register a custom function which requires escalated privileges.
Definition: pbx.h:1517
static struct ast_custom_function unlock_function
Definition: func_lock.c:424
static struct ast_custom_function lock_function
Definition: func_lock.c:412

◆ lock_fixup()

static void lock_fixup ( void *  data,
struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 162 of file func_lock.c.

References ast_channel_datastore_find(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, channel_lock_frame::channel, ast_datastore::data, channel_lock_frame::list, channel_lock_frame::lock_frame, NULL, and lock_frame::owner.

163 {
164  struct ast_datastore *lock_store = ast_channel_datastore_find(oldchan, &lock_info, NULL);
166  struct channel_lock_frame *clframe = NULL;
167 
168  if (!lock_store) {
169  return;
170  }
171  list = lock_store->data;
172 
174  AST_LIST_TRAVERSE(list, clframe, list) {
175  if (clframe->lock_frame->owner == oldchan) {
176  clframe->lock_frame->owner = newchan;
177  }
178  clframe->channel = newchan;
179  }
181 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:172
struct lock_frame * lock_frame
Definition: func_lock.c:138
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Structure for a data store object.
Definition: datastore.h:68
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2390
#define NULL
Definition: resample.c:96
static const struct ast_datastore_info lock_info
Definition: func_lock.c:114
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct channel_lock_frame::@206 list
void * data
Definition: datastore.h:70
struct ast_channel * owner
Definition: func_lock.c:129
struct ast_channel * channel
Definition: func_lock.c:137

◆ lock_free()

static void lock_free ( void *  data)
static

Definition at line 141 of file func_lock.c.

References ast_cond_signal, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, channel_lock_frame::channel, lock_frame::cond, lock_frame::count, channel_lock_frame::list, channel_lock_frame::lock_frame, lock_frame::mutex, NULL, and lock_frame::owner.

142 {
143  AST_LIST_HEAD(, channel_lock_frame) *oldlist = data;
144  struct channel_lock_frame *clframe;
145  AST_LIST_LOCK(oldlist);
146  while ((clframe = AST_LIST_REMOVE_HEAD(oldlist, list))) {
147  /* Only unlock if we own the lock */
148  if (clframe->channel == clframe->lock_frame->owner) {
149  ast_mutex_lock(&clframe->lock_frame->mutex);
150  clframe->lock_frame->count = 0;
151  clframe->lock_frame->owner = NULL;
152  ast_cond_signal(&clframe->lock_frame->cond);
153  ast_mutex_unlock(&clframe->lock_frame->mutex);
154  }
155  ast_free(clframe);
156  }
157  AST_LIST_UNLOCK(oldlist);
158  AST_LIST_HEAD_DESTROY(oldlist);
159  ast_free(oldlist);
160 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:172
struct lock_frame * lock_frame
Definition: func_lock.c:138
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
ast_mutex_t mutex
Definition: func_lock.c:122
ast_cond_t cond
Definition: func_lock.c:123
#define ast_free(a)
Definition: astmm.h:182
struct channel_lock_frame::@206 list
struct ast_channel * owner
Definition: func_lock.c:129
struct ast_channel * channel
Definition: func_lock.c:137
unsigned int count
Definition: func_lock.c:125
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ lock_read()

static int lock_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 388 of file func_lock.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), and get_lock().

389 {
390  if (!chan) {
391  return -1;
392  }
393  ast_autoservice_start(chan);
394  ast_copy_string(buf, get_lock(chan, data, 0) ? "0" : "1", len);
395  ast_autoservice_stop(chan);
396 
397  return 0;
398 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int get_lock(struct ast_channel *chan, char *lockname, int trylock)
Definition: func_lock.c:183
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ trylock_read()

static int trylock_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 400 of file func_lock.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), and get_lock().

401 {
402  if (!chan) {
403  return -1;
404  }
405  ast_autoservice_start(chan);
406  ast_copy_string(buf, get_lock(chan, data, 1) ? "0" : "1", len);
407  ast_autoservice_stop(chan);
408 
409  return 0;
410 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int get_lock(struct ast_channel *chan, char *lockname, int trylock)
Definition: func_lock.c:183
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 430 of file func_lock.c.

References ast_cond_destroy, ast_cond_wait, ast_custom_function_unregister(), ast_free, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, lock_frame::cond, lock_frame::entries, lock_frame::mutex, lock_frame::owner, lock_frame::requesters, and unloading.

431 {
432  struct lock_frame *current;
433 
434  /* Module flag */
435  unloading = 1;
436 
437  /* Make it impossible for new requesters to be added
438  * NOTE: channels could already be in get_lock() */
441 
443  AST_LIST_TRAVERSE(&locklist, current, entries) {
444  ast_mutex_lock(&current->mutex);
445  while (current->owner || current->requesters) {
446  /* either the mutex is locked, or other parties are currently in get_lock,
447  * we need to wait for all of those to clear first */
448  ast_cond_wait(&current->cond, &current->mutex);
449  }
450  ast_mutex_unlock(&current->mutex);
451  /* At this point we know:
452  * 1. the lock has been released,
453  * 2. there are no requesters (nor should any be able to sneak in).
454  */
455  ast_mutex_destroy(&current->mutex);
456  ast_cond_destroy(&current->cond);
457  ast_free(current);
458  }
461 
462  /* At this point we can safely stop access to UNLOCK */
464 
465  return 0;
466 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int unloading
Definition: func_lock.c:112
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct ast_custom_function trylock_function
Definition: func_lock.c:418
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
unsigned int requesters
Definition: func_lock.c:127
#define ast_mutex_lock(a)
Definition: lock.h:187
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
struct lock_frame::@205 entries
ast_mutex_t mutex
Definition: func_lock.c:122
#define ast_cond_destroy(cond)
Definition: lock.h:200
ast_cond_t cond
Definition: func_lock.c:123
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
static struct ast_custom_function unlock_function
Definition: func_lock.c:424
struct ast_channel * owner
Definition: func_lock.c:129
#define ast_mutex_destroy(a)
Definition: lock.h:186
static struct ast_custom_function lock_function
Definition: func_lock.c:412
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ unlock_read()

static int unlock_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 336 of file func_lock.c.

References ast_channel_datastore_find(), ast_cond_signal, ast_copy_string(), ast_debug, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, lock_frame::cond, lock_frame::count, ast_datastore::data, channel_lock_frame::list, channel_lock_frame::lock_frame, LOG_WARNING, lock_frame::mutex, lock_frame::name, NULL, and lock_frame::owner.

337 {
338  struct ast_datastore *lock_store;
339  struct channel_lock_frame *clframe;
341 
342  if (!chan) {
343  return -1;
344  }
345 
346  lock_store = ast_channel_datastore_find(chan, &lock_info, NULL);
347  if (!lock_store) {
348  ast_log(LOG_WARNING, "No datastore for dialplan locks. Nothing was ever locked!\n");
349  ast_copy_string(buf, "0", len);
350  return 0;
351  }
352 
353  if (!(list = lock_store->data)) {
354  ast_debug(1, "This should NEVER happen\n");
355  ast_copy_string(buf, "0", len);
356  return 0;
357  }
358 
359  /* Find item in the channel list */
361  AST_LIST_TRAVERSE(list, clframe, list) {
362  if (clframe->lock_frame && clframe->lock_frame->owner == chan && strcmp(clframe->lock_frame->name, data) == 0) {
363  break;
364  }
365  }
366  /* We never destroy anything until channel destruction, which will never
367  * happen while this routine is executing, so we don't need to hold the
368  * lock beyond this point. */
370 
371  if (!clframe) {
372  /* We didn't have this lock in the first place */
373  ast_copy_string(buf, "0", len);
374  return 0;
375  }
376 
377  if (--clframe->lock_frame->count == 0) {
378  ast_mutex_lock(&clframe->lock_frame->mutex);
379  clframe->lock_frame->owner = NULL;
380  ast_cond_signal(&clframe->lock_frame->cond);
381  ast_mutex_unlock(&clframe->lock_frame->mutex);
382  }
383 
384  ast_copy_string(buf, "1", len);
385  return 0;
386 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:172
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct lock_frame * lock_frame
Definition: func_lock.c:138
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_mutex_lock(a)
Definition: lock.h:187
Structure for a data store object.
Definition: datastore.h:68
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2390
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static const struct ast_datastore_info lock_info
Definition: func_lock.c:114
ast_mutex_t mutex
Definition: func_lock.c:122
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
ast_cond_t cond
Definition: func_lock.c:123
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char name[0]
Definition: func_lock.c:131
struct channel_lock_frame::@206 list
void * data
Definition: datastore.h:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_channel * owner
Definition: func_lock.c:129
unsigned int count
Definition: func_lock.c:125
#define ast_mutex_unlock(a)
Definition: lock.h:188

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Dialplan mutexes" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 477 of file func_lock.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 477 of file func_lock.c.

◆ lock_function

struct ast_custom_function lock_function
static
Initial value:
= {
.name = "LOCK",
.read = lock_read,
.read_max = 2,
}
static int lock_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_lock.c:388

Definition at line 412 of file func_lock.c.

◆ lock_info

const struct ast_datastore_info lock_info
static
Initial value:
= {
.type = "MUTEX",
.destroy = lock_free,
.chan_fixup = lock_fixup,
}
static void lock_free(void *data)
Definition: func_lock.c:141
static void lock_fixup(void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: func_lock.c:162

Definition at line 114 of file func_lock.c.

Referenced by dummy_start().

◆ locklist

struct locklist locklist = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ trylock_function

struct ast_custom_function trylock_function
static
Initial value:
= {
.name = "TRYLOCK",
.read = trylock_read,
.read_max = 2,
}
static int trylock_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_lock.c:400

Definition at line 418 of file func_lock.c.

◆ unloading

int unloading = 0
static

Definition at line 112 of file func_lock.c.

Referenced by get_lock(), and unload_module().

◆ unlock_function

struct ast_custom_function unlock_function
static
Initial value:
= {
.name = "UNLOCK",
.read = unlock_read,
.read_max = 2,
}
static int unlock_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_lock.c:336

Definition at line 424 of file func_lock.c.