Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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"
#include "asterisk/cli.h"
Include dependency graph for func_lock.c:

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 char * handle_cli_locks_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
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_cli_entry cli_locks_show = { .handler = handle_cli_locks_show , .summary = "List func_lock locks." ,}
 
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 563 of file func_lock.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 563 of file func_lock.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 563 of file func_lock.c.

◆ get_lock()

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

Definition at line 207 of file func_lock.c.

208{
209 struct ast_datastore *lock_store = ast_channel_datastore_find(chan, &lock_info, NULL);
210 struct lock_frame *current;
211 struct channel_lock_frame *clframe = NULL;
213 int res = 0;
214 struct timespec timeout = { 0, };
215 struct timeval now;
216
217 if (!lock_store) {
218 if (unloading) {
219 ast_log(LOG_ERROR, "%sLOCK has no datastore and func_lock is unloading, failing.\n",
220 trylock ? "TRY" : "");
221 return -1;
222 }
223
224 lock_store = ast_datastore_alloc(&lock_info, NULL);
225 if (!lock_store) {
226 ast_log(LOG_ERROR, "Unable to allocate new datastore. No locks will be obtained.\n");
227 return -1;
228 }
229
230 list = ast_calloc(1, sizeof(*list));
231 if (!list) {
233 "Unable to allocate datastore list head. %sLOCK will fail.\n",
234 trylock ? "TRY" : "");
235 ast_datastore_free(lock_store);
236 return -1;
237 }
238
239 lock_store->data = list;
240 AST_LIST_HEAD_INIT(list);
241 ast_channel_datastore_add(chan, lock_store);
242
243 /* We cannot unload until this channel has released the lock_store */
245 } else
246 list = lock_store->data;
247
248 /* Lock already exists? */
251 if (strcmp(current->name, lockname) == 0) {
252 break;
253 }
254 }
255
256 if (!current) {
257 if (unloading) {
259 "Lock doesn't exist whilst unloading. %sLOCK will fail.\n",
260 trylock ? "TRY" : "");
261 /* Don't bother */
263 return -1;
264 }
265
266 /* Create new lock entry */
267 current = ast_calloc(1, sizeof(*current) + strlen(lockname) + 1);
268 if (!current) {
270 return -1;
271 }
272
273 strcpy(current->name, lockname); /* SAFE */
274 if ((res = ast_mutex_init(&current->mutex))) {
275 ast_log(LOG_ERROR, "Unable to initialize mutex: %s\n", strerror(res));
278 return -1;
279 }
280 if ((res = ast_cond_init(&current->cond, NULL))) {
281 ast_log(LOG_ERROR, "Unable to initialize condition variable: %s\n", strerror(res));
282 ast_mutex_destroy(&current->mutex);
285 return -1;
286 }
288 }
289 /* Add to requester list */
290 ast_mutex_lock(&current->mutex);
291 current->requesters++;
292 ast_mutex_unlock(&current->mutex);
294
295 /* Found lock or created one - now find or create the corresponding link in the channel */
296 AST_LIST_LOCK(list);
297 AST_LIST_TRAVERSE(list, clframe, list) {
298 if (clframe->lock_frame == current) {
299 break;
300 }
301 }
302
303 if (!clframe) {
304 if (unloading) {
306 "Busy unloading. %sLOCK will fail.\n",
307 trylock ? "TRY" : "");
308 /* Don't bother */
309 ast_mutex_lock(&current->mutex);
310 current->requesters--;
311 ast_mutex_unlock(&current->mutex);
312 AST_LIST_UNLOCK(list);
313 return -1;
314 }
315
316 if (!(clframe = ast_calloc(1, sizeof(*clframe)))) {
318 "Unable to allocate channel lock frame. %sLOCK will fail.\n",
319 trylock ? "TRY" : "");
320 ast_mutex_lock(&current->mutex);
321 current->requesters--;
322 ast_mutex_unlock(&current->mutex);
323 AST_LIST_UNLOCK(list);
324 return -1;
325 }
326
327 clframe->lock_frame = current;
328 clframe->channel = chan;
329 AST_LIST_INSERT_TAIL(list, clframe, list);
330 }
331 AST_LIST_UNLOCK(list);
332
333 /* If we already own the lock, then we're being called recursively.
334 * Keep track of how many times that is, because we need to unlock
335 * the same amount, before we'll release this one.
336 */
337 if (current->owner == chan) {
338 /* We're not a requester, we already have it */
339 ast_mutex_lock(&current->mutex);
340 current->requesters--;
341 ast_mutex_unlock(&current->mutex);
342 current->count++;
343 return 0;
344 }
345
346 /* Wait up to three seconds from now for LOCK. */
347 now = ast_tvnow();
348 timeout.tv_sec = now.tv_sec + 3;
349 timeout.tv_nsec = now.tv_usec * 1000;
350
351 ast_mutex_lock(&current->mutex);
352
353 res = 0;
354 while (!trylock && !res && current->owner) {
355 res = ast_cond_timedwait(&current->cond, &current->mutex, &timeout);
356 }
357 if (current->owner) {
358 /* timeout;
359 * trylock; or
360 * cond_timedwait failed.
361 *
362 * either way, we fail to obtain the lock.
363 */
364 res = -1;
365 } else {
366 current->owner = chan;
367 current->count++;
368 res = 0;
369 }
370 /* Remove from requester list */
371 current->requesters--;
372 if (res && unloading)
373 ast_cond_signal(&current->cond);
374 ast_mutex_unlock(&current->mutex);
375
376 return res;
377}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2414
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:2428
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static const struct ast_datastore_info lock_info
Definition: func_lock.c:136
static int unloading
Definition: func_lock.c:134
#define LOG_ERROR
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:173
#define ast_cond_init(cond, attr)
Definition: lock.h:205
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:210
#define ast_mutex_init(pmutex)
Definition: lock.h:190
#define ast_mutex_unlock(a)
Definition: lock.h:194
#define ast_mutex_destroy(a)
Definition: lock.h:192
#define ast_mutex_lock(a)
Definition: lock.h:193
#define ast_cond_signal(cond)
Definition: lock.h:207
size_t current
Definition: main/cli.c:113
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:457
#define NULL
Definition: resample.c:96
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
struct ast_module * self
Definition: module.h:356
struct channel_lock_frame::@174 list
struct ast_channel * channel
Definition: func_lock.c:159
struct lock_frame * lock_frame
Definition: func_lock.c:160
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_cond_init, ast_cond_signal, ast_cond_timedwait, ast_datastore_alloc, ast_datastore_free(), 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_module_ref, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), channel_lock_frame::channel, current, ast_datastore::data, channel_lock_frame::list, channel_lock_frame::lock_frame, lock_info, LOG_ERROR, NULL, ast_module_info::self, and unloading.

Referenced by lock_read(), and trylock_read().

◆ handle_cli_locks_show()

static char * handle_cli_locks_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 455 of file func_lock.c.

456{
457 int c = 0;
458 struct lock_frame* current;
459 switch (cmd) {
460 case CLI_INIT:
461 e->command = "dialplan locks show";
462 e->usage =
463 "Usage: dialplan locks show\n"
464 " List all locks known to func_lock, along with their current status.\n";
465 return NULL;
466 case CLI_GENERATE:
467 return NULL;
468 }
469
470 ast_cli(a->fd, "func_lock locks:\n");
471 ast_cli(a->fd, "%-40s Requesters Owner\n", "Name");
474 ast_mutex_lock(&current->mutex);
475 ast_cli(a->fd, "%-40s %-10d %s\n", current->name, current->requesters,
476 current->owner ? ast_channel_name(current->owner) : "(unlocked)");
477 ast_mutex_unlock(&current->mutex);
478 c++;
479 }
481 ast_cli(a->fd, "%d total locks listed.\n", c);
482
483 return 0;
484}
const char * ast_channel_name(const struct ast_channel *chan)
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
struct lock_frame::@173 entries
static struct test_val a
static struct test_val c

References a, ast_channel_name(), ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, c, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, current, lock_frame::entries, NULL, and ast_cli_entry::usage.

◆ load_module()

static int load_module ( void  )
static

Definition at line 553 of file func_lock.c.

554{
559
560 return res;
561}
#define ast_cli_register(e)
Registers a command or an array of commands.
Definition: cli.h:256
static struct ast_custom_function trylock_function
Definition: func_lock.c:492
static struct ast_custom_function lock_function
Definition: func_lock.c:486
static struct ast_cli_entry cli_locks_show
Definition: func_lock.c:504
static struct ast_custom_function unlock_function
Definition: func_lock.c:498
#define ast_custom_function_register_escalating(acf, escalation)
Register a custom function which requires escalated privileges.
Definition: pbx.h:1568
@ AST_CFE_READ
Definition: pbx.h:1551

References AST_CFE_READ, ast_cli_register, ast_custom_function_register_escalating, cli_locks_show, lock_function, trylock_function, and unlock_function.

◆ lock_fixup()

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

Definition at line 186 of file func_lock.c.

187{
188 struct ast_datastore *lock_store = ast_channel_datastore_find(oldchan, &lock_info, NULL);
190 struct channel_lock_frame *clframe = NULL;
191
192 if (!lock_store) {
193 return;
194 }
195 list = lock_store->data;
196
198 AST_LIST_TRAVERSE(list, clframe, list) {
199 if (clframe->lock_frame->owner == oldchan) {
200 clframe->lock_frame->owner = newchan;
201 }
202 clframe->channel = newchan;
203 }
205}
struct ast_channel * owner
Definition: func_lock.c:151

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, lock_info, NULL, and lock_frame::owner.

◆ lock_free()

static void lock_free ( void *  data)
static

Definition at line 163 of file func_lock.c.

164{
165 AST_LIST_HEAD(, channel_lock_frame) *oldlist = data;
166 struct channel_lock_frame *clframe;
167 AST_LIST_LOCK(oldlist);
168 while ((clframe = AST_LIST_REMOVE_HEAD(oldlist, list))) {
169 /* Only unlock if we own the lock */
170 if (clframe->channel == clframe->lock_frame->owner) {
171 ast_mutex_lock(&clframe->lock_frame->mutex);
172 clframe->lock_frame->count = 0;
173 clframe->lock_frame->owner = NULL;
174 ast_cond_signal(&clframe->lock_frame->cond);
176 }
177 ast_free(clframe);
178 }
179 AST_LIST_UNLOCK(oldlist);
180 AST_LIST_HEAD_DESTROY(oldlist);
181 ast_free(oldlist);
182
184}
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:653
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
unsigned int count
Definition: func_lock.c:147
ast_cond_t cond
Definition: func_lock.c:145
ast_mutex_t mutex
Definition: func_lock.c:144

References ast_cond_signal, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_module_unref, 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, lock_frame::owner, and ast_module_info::self.

◆ lock_read()

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

Definition at line 431 of file func_lock.c.

432{
433 if (!chan) {
434 return -1;
435 }
437 ast_copy_string(buf, get_lock(chan, data, 0) ? "0" : "1", len);
439
440 return 0;
441}
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
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
static int get_lock(struct ast_channel *chan, char *lockname, int trylock)
Definition: func_lock.c:207
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

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

◆ trylock_read()

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

Definition at line 443 of file func_lock.c.

444{
445 if (!chan) {
446 return -1;
447 }
449 ast_copy_string(buf, get_lock(chan, data, 1) ? "0" : "1", len);
451
452 return 0;
453}

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

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 506 of file func_lock.c.

507{
508 struct lock_frame *current;
509
510 /* Module flag */
511 unloading = 1;
512
513 /* Make it impossible for new requesters to be added
514 * NOTE: channels could already be in get_lock() */
517
519
522 int warned = 0;
523 ast_mutex_lock(&current->mutex);
524 while (current->owner || current->requesters) {
525 if (!warned) {
526 ast_log(LOG_WARNING, "Waiting for %d requesters for %s lock %s.\n",
527 current->requesters, current->owner ? "locked" : "unlocked",
528 current->name);
529 warned = 1;
530 }
531 /* either the mutex is locked, or other parties are currently in get_lock,
532 * we need to wait for all of those to clear first */
533 ast_cond_wait(&current->cond, &current->mutex);
534 }
535 ast_mutex_unlock(&current->mutex);
536 /* At this point we know:
537 * 1. the lock has been released,
538 * 2. there are no requesters (nor should any be able to sneak in).
539 */
540 ast_mutex_destroy(&current->mutex);
543 }
546
547 /* At this point we can safely stop access to UNLOCK */
549
550 return 0;
551}
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2439
#define LOG_WARNING
#define ast_cond_destroy(cond)
Definition: lock.h:206
#define ast_cond_wait(cond, mutex)
Definition: lock.h:209
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

References ast_cli_unregister(), ast_cond_destroy, ast_cond_wait, ast_custom_function_unregister(), ast_free, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, cli_locks_show, current, lock_frame::entries, lock_function, LOG_WARNING, trylock_function, unloading, and unlock_function.

◆ unlock_read()

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

Definition at line 379 of file func_lock.c.

380{
381 struct ast_datastore *lock_store;
382 struct channel_lock_frame *clframe;
384
385 if (!chan) {
386 return -1;
387 }
388
389 lock_store = ast_channel_datastore_find(chan, &lock_info, NULL);
390 if (!lock_store) {
391 ast_log(LOG_WARNING, "No datastore for dialplan locks. Nothing was ever locked!\n");
392 ast_copy_string(buf, "0", len);
393 return 0;
394 }
395
396 if (!(list = lock_store->data)) {
397 ast_debug(1, "This should NEVER happen\n");
398 ast_copy_string(buf, "0", len);
399 return 0;
400 }
401
402 /* Find item in the channel list */
404 AST_LIST_TRAVERSE(list, clframe, list) {
405 if (clframe->lock_frame && clframe->lock_frame->owner == chan && strcmp(clframe->lock_frame->name, data) == 0) {
406 break;
407 }
408 }
409 /* We never destroy anything until channel destruction, which will never
410 * happen while this routine is executing, so we don't need to hold the
411 * lock beyond this point. */
413
414 if (!clframe) {
415 /* We didn't have this lock in the first place */
416 ast_copy_string(buf, "0", len);
417 return 0;
418 }
419
420 if (--clframe->lock_frame->count == 0) {
421 ast_mutex_lock(&clframe->lock_frame->mutex);
422 clframe->lock_frame->owner = NULL;
423 ast_cond_signal(&clframe->lock_frame->cond);
425 }
426
427 ast_copy_string(buf, "1", len);
428 return 0;
429}
#define ast_debug(level,...)
Log a DEBUG message.
char name[0]
Definition: func_lock.c:153

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, buf, lock_frame::cond, lock_frame::count, ast_datastore::data, len(), channel_lock_frame::list, channel_lock_frame::lock_frame, lock_info, LOG_WARNING, lock_frame::mutex, lock_frame::name, NULL, and lock_frame::owner.

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 563 of file func_lock.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 563 of file func_lock.c.

◆ cli_locks_show

struct ast_cli_entry cli_locks_show = { .handler = handle_cli_locks_show , .summary = "List func_lock locks." ,}
static

Definition at line 504 of file func_lock.c.

Referenced by load_module(), and unload_module().

◆ 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:431

Definition at line 486 of file func_lock.c.

Referenced by load_module(), and unload_module().

◆ 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:163
static void lock_fixup(void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: func_lock.c:186

Definition at line 136 of file func_lock.c.

Referenced by dummy_start(), get_lock(), lock_fixup(), and unlock_read().

◆ 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:443

Definition at line 492 of file func_lock.c.

Referenced by load_module(), and unload_module().

◆ unloading

int unloading = 0
static

Definition at line 134 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:379

Definition at line 498 of file func_lock.c.

Referenced by load_module(), and unload_module().