1 /*
2 * $Id$
3 *
4 * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
5 * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
6 *
7 * The initial version of this code was written by Dragos Vingarzan
8 * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
9 * Fruanhofer Institute. It was and still is maintained in a separate
10 * branch of the original SER. We are therefore migrating it to
11 * Kamailio/SR and look forward to maintaining it from here on out.
12 * 2011/2012 Smile Communications, Pty. Ltd.
13 * ported/maintained/improved by
14 * Jason Penton (jason(dot)penton(at)smilecoms.com and
15 * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
16 * effort to add full IMS support to Kamailio/SR using a new and
17 * improved architecture
18 *
19 * NB: Alot of this code was originally part of OpenIMSCore,
20 * FhG Fokus.
21 * Copyright (C) 2004-2006 FhG Fokus
22 * Thanks for great work! This is an effort to
23 * break apart the various CSCF functions into logically separate
24 * components. We hope this will drive wider use. We also feel
25 * that in this way the architecture is more complete and thereby easier
26 * to manage in the Kamailio/SR environment
27 *
28 * This file is part of Kamailio, a free SIP server.
29 *
30 * Kamailio is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version
34 *
35 * Kamailio is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
43 *
44 */
45
46
47
48 #include "hslot.h"
49
50 /*! number of locks */
51 int ul_locks_no=4;
52 /*! global list of locks */
53 gen_lock_set_t* ul_locks=0;
54
55
56 /*!
57 * \brief Initialize locks for the hash table
58 * \return 0 on success, -1 on failure
59 */
ul_init_locks(void)60 int ul_init_locks(void)
61 {
62 int i;
63 i = ul_locks_no;
64 do {
65 if ((( ul_locks=lock_set_alloc(i))!=0)&&
66 (lock_set_init(ul_locks)!=0))
67 {
68 ul_locks_no = i;
69 LM_INFO("locks array size %d\n", ul_locks_no);
70 return 0;
71
72 }
73 if (ul_locks){
74 lock_set_dealloc(ul_locks);
75 ul_locks=0;
76 }
77 i--;
78 if(i==0)
79 {
80 LM_ERR("failed to allocate locks\n");
81 return -1;
82 }
83 } while (1);
84 }
85
86
87 /*!
88 * \brief Unlock all locks on the list
89 */
ul_unlock_locks(void)90 void ul_unlock_locks(void)
91 {
92 unsigned int i;
93
94 if (ul_locks==0)
95 return;
96
97 for (i=0;i<ul_locks_no;i++) {
98 #ifdef GEN_LOCK_T_PREFERED
99 lock_release(&ul_locks->locks[i]);
100 #else
101 ul_release_idx(i);
102 #endif
103 };
104 }
105
106
107 /*!
108 * \brief Destroy all locks on the list
109 */
ul_destroy_locks(void)110 void ul_destroy_locks(void)
111 {
112 if (ul_locks !=0){
113 lock_set_destroy(ul_locks);
114 lock_set_dealloc(ul_locks);
115 };
116 }
117
118 #ifndef GEN_LOCK_T_PREFERED
119 /*!
120 * \brief Lock a lock with a certain index
121 * \param idx lock index
122 */
ul_lock_idx(int idx)123 void ul_lock_idx(int idx)
124 {
125 lock_set_get(ul_locks, idx);
126 }
127
128
129 /*!
130 * \brief Release a lock with a certain index
131 * \param idx lock index
132 */
ul_release_idx(int idx)133 void ul_release_idx(int idx)
134 {
135 lock_set_release(ul_locks, idx);
136 }
137 #endif
138
139 /*!
140 * \brief Initialize cache slot structure
141 * \param _d domain for the hash slot
142 * \param _s hash slot
143 * \param n used to get the slot number (modulo number or locks)
144 */
init_slot(struct udomain * _d,hslot_t * _s,int n)145 void init_slot(struct udomain* _d, hslot_t* _s, int n)
146 {
147 _s->n = 0;
148 _s->first = 0;
149 _s->last = 0;
150 _s->d = _d;
151
152 #ifdef GEN_LOCK_T_PREFERED
153 _s->lock = &ul_locks->locks[n%ul_locks_no];
154 #else
155 _s->lockidx = n%ul_locks_no;
156 #endif
157 }
158
159
160 /*!
161 * \brief Deinitialize given slot structure
162 * \param _s hash slot
163 */
deinit_slot(hslot_t * _s)164 void deinit_slot(hslot_t* _s)
165 {
166 struct impurecord* ptr;
167
168 /* Remove all elements */
169 while(_s->first) {
170 ptr = _s->first;
171 _s->first = _s->first->next;
172 free_impurecord(ptr);
173 }
174
175 _s->n = 0;
176 _s->last = 0;
177 _s->d = 0;
178 }
179
180
181 /*!
182 * \brief Add an element to an slot's linked list
183 * \param _s hash slot
184 * \param _r added record
185 */
slot_add(hslot_t * _s,struct impurecord * _r)186 void slot_add(hslot_t* _s, struct impurecord* _r)
187 {
188 if (_s->n == 0) {
189 _s->first = _s->last = _r;
190 } else {
191 _r->prev = _s->last;
192 _s->last->next = _r;
193 _s->last = _r;
194 }
195 _s->n++;
196 _r->slot = _s;
197 }
198
199
200 /*!
201 * \brief Remove an element from slot linked list
202 * \param _s hash slot
203 * \param _r removed record
204 */
slot_rem(hslot_t * _s,struct impurecord * _r)205 void slot_rem(hslot_t* _s, struct impurecord* _r)
206 {
207 LM_DBG("Removing IMPU [%.*s] from hashtable\n", _r->public_identity.len, _r->public_identity.s);
208 if (_r->prev) {
209 _r->prev->next = _r->next;
210 } else {
211 _s->first = _r->next;
212 }
213
214 if (_r->next) {
215 _r->next->prev = _r->prev;
216 } else {
217 _s->last = _r->prev;
218 }
219
220 _r->prev = _r->next = 0;
221 _r->slot = 0;
222 _s->n--;
223 }
224