Asterisk - The Open Source Telephony Project  18.5.0
named_locks.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2016, Fairview 5 Engineering, LLC
5  *
6  * George Joseph <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Named Locks
22  *
23  * \author George Joseph <[email protected]>
24  */
25 
26 #include "asterisk.h"
27 
28 #include "asterisk/_private.h"
29 #include "asterisk/astobj2.h"
30 #include "asterisk/named_locks.h"
31 #include "asterisk/utils.h"
32 
34 #define NAMED_LOCKS_BUCKETS 101
35 
37  AO2_WEAKPROXY();
38  char key[0];
39 };
40 
42 };
43 
46 
47 static void named_locks_shutdown(void)
48 {
49  ao2_cleanup(named_locks);
50 }
51 
53 {
55  NAMED_LOCKS_BUCKETS, named_lock_proxy_hash_fn, NULL, named_lock_proxy_cmp_fn);
56  if (!named_locks) {
57  return -1;
58  }
59 
61 
62  return 0;
63 }
64 
65 static void named_lock_proxy_cb(void *weakproxy, void *data)
66 {
67  ao2_unlink(named_locks, weakproxy);
68 }
69 
70 struct ast_named_lock *__ast_named_lock_get(const char *filename, int lineno, const char *func,
71  enum ast_named_lock_type lock_type, const char *keyspace, const char *key)
72 {
73  struct named_lock_proxy *proxy;
74  struct ast_named_lock *lock;
75  int keylen = strlen(keyspace) + strlen(key) + 2;
76  char *concat_key = ast_alloca(keylen);
77 
78  sprintf(concat_key, "%s-%s", keyspace, key); /* Safe */
79 
80  ao2_lock(named_locks);
81  lock = __ao2_weakproxy_find(named_locks, concat_key, OBJ_SEARCH_KEY | OBJ_NOLOCK,
82  __PRETTY_FUNCTION__, filename, lineno, func);
83  if (lock) {
84  ast_assert((ao2_options_get(lock) & AO2_ALLOC_OPT_LOCK_MASK) == lock_type);
85  ao2_unlock(named_locks);
86 
87  return lock;
88  }
89 
90  proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + keylen, NULL, concat_key);
91  if (!proxy) {
92  goto failure_cleanup;
93  }
94 
95  lock = __ao2_alloc(sizeof(*lock) + keylen, NULL, lock_type, concat_key, filename, lineno, func);
96  if (!lock) {
97  goto failure_cleanup;
98  }
99 
100  /* We have exclusive access to proxy and lock, no need for locking here. */
101  if (ao2_weakproxy_set_object(proxy, lock, OBJ_NOLOCK)) {
102  goto failure_cleanup;
103  }
104 
106  goto failure_cleanup;
107  }
108 
109  strcpy(proxy->key, concat_key); /* Safe */
110  ao2_link_flags(named_locks, proxy, OBJ_NOLOCK);
111  ao2_unlock(named_locks);
112  ao2_t_ref(proxy, -1, "Release allocation reference");
113 
114  return lock;
115 
116 failure_cleanup:
117  ao2_unlock(named_locks);
118 
119  ao2_cleanup(proxy);
120  ao2_cleanup(lock);
121 
122  return NULL;
123 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static void named_lock_proxy_cb(void *weakproxy, void *data)
Definition: named_locks.c:65
#define ao2_weakproxy_set_object(weakproxy, obj, flags)
Definition: astobj2.h:583
Asterisk main include file. File version handling, generic pbx functions.
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
Definition: astobj2.h:2055
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition: astobj2.c:765
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ast_assert(a)
Definition: utils.h:695
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
Definition: astobj2.c:931
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct ao2_container * named_locks
Definition: named_locks.c:33
Utility functions.
static void named_locks_shutdown(void)
Definition: named_locks.c:47
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_lock(a)
Definition: astobj2.h:718
ast_named_lock_type
Which type of lock to request.
Definition: named_locks.h:57
void * __ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
Named Locks.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
struct ast_named_lock * __ast_named_lock_get(const char *filename, int lineno, const char *func, enum ast_named_lock_type lock_type, const char *keyspace, const char *key)
Definition: named_locks.c:70
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
Prototypes for public functions only of internal interest,.
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
Definition: astobj2.h:2071
int ast_named_locks_init(void)
Definition: named_locks.c:52
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int ao2_options_get(void *obj)
Retrieve the ao2 options used to create the object.
Definition: astobj2.c:778
#define ao2_t_weakproxy_alloc(data_size, destructor_fn, tag)
Definition: astobj2.h:557
Generic container type.
#define NAMED_LOCKS_BUCKETS
Definition: named_locks.c:34