Asterisk - The Open Source Telephony Project GIT-master-a358458
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 554 of file func_lock.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 554 of file func_lock.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 554 of file func_lock.c.

◆ get_lock()

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

Definition at line 198 of file func_lock.c.

199{
200 struct ast_datastore *lock_store = ast_channel_datastore_find(chan, &lock_info, NULL);
201 struct lock_frame *current;
202 struct channel_lock_frame *clframe = NULL;
204 int res = 0;
205 struct timespec timeout = { 0, };
206 struct timeval now;
207
208 if (!lock_store) {
209 if (unloading) {
210 ast_log(LOG_ERROR, "%sLOCK has no datastore and func_lock is unloading, failing.\n",
211 trylock ? "TRY" : "");
212 return -1;
213 }
214
215 lock_store = ast_datastore_alloc(&lock_info, NULL);
216 if (!lock_store) {
217 ast_log(LOG_ERROR, "Unable to allocate new datastore. No locks will be obtained.\n");
218 return -1;
219 }
220
221 list = ast_calloc(1, sizeof(*list));
222 if (!list) {
224 "Unable to allocate datastore list head. %sLOCK will fail.\n",
225 trylock ? "TRY" : "");
226 ast_datastore_free(lock_store);
227 return -1;
228 }
229
230 lock_store->data = list;
231 AST_LIST_HEAD_INIT(list);
232 ast_channel_datastore_add(chan, lock_store);
233
234 /* We cannot unload until this channel has released the lock_store */
236 } else
237 list = lock_store->data;
238
239 /* Lock already exists? */
242 if (strcmp(current->name, lockname) == 0) {
243 break;
244 }
245 }
246
247 if (!current) {
248 if (unloading) {
250 "Lock doesn't exist whilst unloading. %sLOCK will fail.\n",
251 trylock ? "TRY" : "");
252 /* Don't bother */
254 return -1;
255 }
256
257 /* Create new lock entry */
258 current = ast_calloc(1, sizeof(*current) + strlen(lockname) + 1);
259 if (!current) {
261 return -1;
262 }
263
264 strcpy(current->name, lockname); /* SAFE */
265 if ((res = ast_mutex_init(&current->mutex))) {
266 ast_log(LOG_ERROR, "Unable to initialize mutex: %s\n", strerror(res));
269 return -1;
270 }
271 if ((res = ast_cond_init(&current->cond, NULL))) {
272 ast_log(LOG_ERROR, "Unable to initialize condition variable: %s\n", strerror(res));
273 ast_mutex_destroy(&current->mutex);
276 return -1;
277 }
279 }
280 /* Add to requester list */
281 ast_mutex_lock(&current->mutex);
282 current->requesters++;
283 ast_mutex_unlock(&current->mutex);
285
286 /* Found lock or created one - now find or create the corresponding link in the channel */
287 AST_LIST_LOCK(list);
288 AST_LIST_TRAVERSE(list, clframe, list) {
289 if (clframe->lock_frame == current) {
290 break;
291 }
292 }
293
294 if (!clframe) {
295 if (unloading) {
297 "Busy unloading. %sLOCK will fail.\n",
298 trylock ? "TRY" : "");
299 /* Don't bother */
300 ast_mutex_lock(&current->mutex);
301 current->requesters--;
302 ast_mutex_unlock(&current->mutex);
303 AST_LIST_UNLOCK(list);
304 return -1;
305 }
306
307 if (!(clframe = ast_calloc(1, sizeof(*clframe)))) {
309 "Unable to allocate channel lock frame. %sLOCK will fail.\n",
310 trylock ? "TRY" : "");
311 ast_mutex_lock(&current->mutex);
312 current->requesters--;
313 ast_mutex_unlock(&current->mutex);
314 AST_LIST_UNLOCK(list);
315 return -1;
316 }
317
318 clframe->lock_frame = current;
319 clframe->channel = chan;
320 AST_LIST_INSERT_TAIL(list, clframe, list);
321 }
322 AST_LIST_UNLOCK(list);
323
324 /* If we already own the lock, then we're being called recursively.
325 * Keep track of how many times that is, because we need to unlock
326 * the same amount, before we'll release this one.
327 */
328 if (current->owner == chan) {
329 /* We're not a requester, we already have it */
330 ast_mutex_lock(&current->mutex);
331 current->requesters--;
332 ast_mutex_unlock(&current->mutex);
333 current->count++;
334 return 0;
335 }
336
337 /* Wait up to three seconds from now for LOCK. */
338 now = ast_tvnow();
339 timeout.tv_sec = now.tv_sec + 3;
340 timeout.tv_nsec = now.tv_usec * 1000;
341
342 ast_mutex_lock(&current->mutex);
343
344 res = 0;
345 while (!trylock && !res && current->owner) {
346 res = ast_cond_timedwait(&current->cond, &current->mutex, &timeout);
347 }
348 if (current->owner) {
349 /* timeout;
350 * trylock; or
351 * cond_timedwait failed.
352 *
353 * either way, we fail to obtain the lock.
354 */
355 res = -1;
356 } else {
357 current->owner = chan;
358 current->count++;
359 res = 0;
360 }
361 /* Remove from requester list */
362 current->requesters--;
363 if (res && unloading)
364 ast_cond_signal(&current->cond);
365 ast_mutex_unlock(&current->mutex);
366
367 return res;
368}
#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:2385
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:2399
#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:127
static int unloading
Definition: func_lock.c:125
#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:201
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ast_cond_signal(cond)
Definition: lock.h:203
size_t current
Definition: main/cli.c:113
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443
#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:342
struct channel_lock_frame::@174 list
struct ast_channel * channel
Definition: func_lock.c:150
struct lock_frame * lock_frame
Definition: func_lock.c:151
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 446 of file func_lock.c.

447{
448 int c = 0;
449 struct lock_frame* current;
450 switch (cmd) {
451 case CLI_INIT:
452 e->command = "dialplan locks show";
453 e->usage =
454 "Usage: dialplan locks show\n"
455 " List all locks known to func_lock, along with their current status.\n";
456 return NULL;
457 case CLI_GENERATE:
458 return NULL;
459 }
460
461 ast_cli(a->fd, "func_lock locks:\n");
462 ast_cli(a->fd, "%-40s Requesters Owner\n", "Name");
465 ast_mutex_lock(&current->mutex);
466 ast_cli(a->fd, "%-40s %-10d %s\n", current->name, current->requesters,
467 current->owner ? ast_channel_name(current->owner) : "(unlocked)");
468 ast_mutex_unlock(&current->mutex);
469 c++;
470 }
472 ast_cli(a->fd, "%d total locks listed.\n", c);
473
474 return 0;
475}
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 544 of file func_lock.c.

545{
550
551 return res;
552}
#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:483
static struct ast_custom_function lock_function
Definition: func_lock.c:477
static struct ast_cli_entry cli_locks_show
Definition: func_lock.c:495
static struct ast_custom_function unlock_function
Definition: func_lock.c:489
#define ast_custom_function_register_escalating(acf, escalation)
Register a custom function which requires escalated privileges.
Definition: pbx.h:1567
@ AST_CFE_READ
Definition: pbx.h:1550

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

178{
179 struct ast_datastore *lock_store = ast_channel_datastore_find(oldchan, &lock_info, NULL);
181 struct channel_lock_frame *clframe = NULL;
182
183 if (!lock_store) {
184 return;
185 }
186 list = lock_store->data;
187
189 AST_LIST_TRAVERSE(list, clframe, list) {
190 if (clframe->lock_frame->owner == oldchan) {
191 clframe->lock_frame->owner = newchan;
192 }
193 clframe->channel = newchan;
194 }
196}
struct ast_channel * owner
Definition: func_lock.c:142

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

155{
156 AST_LIST_HEAD(, channel_lock_frame) *oldlist = data;
157 struct channel_lock_frame *clframe;
158 AST_LIST_LOCK(oldlist);
159 while ((clframe = AST_LIST_REMOVE_HEAD(oldlist, list))) {
160 /* Only unlock if we own the lock */
161 if (clframe->channel == clframe->lock_frame->owner) {
162 ast_mutex_lock(&clframe->lock_frame->mutex);
163 clframe->lock_frame->count = 0;
164 clframe->lock_frame->owner = NULL;
165 ast_cond_signal(&clframe->lock_frame->cond);
167 }
168 ast_free(clframe);
169 }
170 AST_LIST_UNLOCK(oldlist);
171 AST_LIST_HEAD_DESTROY(oldlist);
172 ast_free(oldlist);
173
175}
#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:469
unsigned int count
Definition: func_lock.c:138
ast_cond_t cond
Definition: func_lock.c:136
ast_mutex_t mutex
Definition: func_lock.c:135

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

423{
424 if (!chan) {
425 return -1;
426 }
428 ast_copy_string(buf, get_lock(chan, data, 0) ? "0" : "1", len);
430
431 return 0;
432}
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:198
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 434 of file func_lock.c.

435{
436 if (!chan) {
437 return -1;
438 }
440 ast_copy_string(buf, get_lock(chan, data, 1) ? "0" : "1", len);
442
443 return 0;
444}

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

498{
499 struct lock_frame *current;
500
501 /* Module flag */
502 unloading = 1;
503
504 /* Make it impossible for new requesters to be added
505 * NOTE: channels could already be in get_lock() */
508
510
513 int warned = 0;
514 ast_mutex_lock(&current->mutex);
515 while (current->owner || current->requesters) {
516 if (!warned) {
517 ast_log(LOG_WARNING, "Waiting for %d requesters for %s lock %s.\n",
518 current->requesters, current->owner ? "locked" : "unlocked",
519 current->name);
520 warned = 1;
521 }
522 /* either the mutex is locked, or other parties are currently in get_lock,
523 * we need to wait for all of those to clear first */
524 ast_cond_wait(&current->cond, &current->mutex);
525 }
526 ast_mutex_unlock(&current->mutex);
527 /* At this point we know:
528 * 1. the lock has been released,
529 * 2. there are no requesters (nor should any be able to sneak in).
530 */
531 ast_mutex_destroy(&current->mutex);
534 }
537
538 /* At this point we can safely stop access to UNLOCK */
540
541 return 0;
542}
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2427
#define LOG_WARNING
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
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 370 of file func_lock.c.

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

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

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 554 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 495 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:422

Definition at line 477 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:154
static void lock_fixup(void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: func_lock.c:177

Definition at line 127 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:434

Definition at line 483 of file func_lock.c.

Referenced by load_module(), and unload_module().

◆ unloading

int unloading = 0
static

Definition at line 125 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:370

Definition at line 489 of file func_lock.c.

Referenced by load_module(), and unload_module().