1 /*
2 * Copyright (C) 2005 iptelorg GmbH
3 *
4 * This file is part of ser, a free SIP server.
5 *
6 * ser is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
10 *
11 * For a license to use the ser software under conditions
12 * other than those described here, or to purchase support for this
13 * software, please contact iptel.org by e-mail at the following addresses:
14 * info@iptel.org
15 *
16 * ser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #include <presence/domain_maintainer.h>
27 #include <cds/ptr_vector.h>
28 #include <cds/memory.h>
29 #include <cds/logger.h>
30
create_domain_maintainer()31 domain_maintainer_t *create_domain_maintainer()
32 {
33 domain_maintainer_t *dm;
34
35 dm = (domain_maintainer_t*)cds_malloc(sizeof(domain_maintainer_t));
36 if (dm) {
37 ptr_vector_init(&dm->registered_domains, 8);
38 cds_mutex_init(&dm->mutex);
39 dm->rc_grp = create_reference_counter_group(16);
40 }
41 return dm;
42 }
43
destroy_domain_maintainer(domain_maintainer_t * dm)44 void destroy_domain_maintainer(domain_maintainer_t *dm)
45 {
46 int i, cnt;
47 notifier_domain_t *d;
48
49 if (!dm) return;
50
51 DEBUG_LOG("destroying domain maintainer\n");
52
53 cnt = ptr_vector_size(&dm->registered_domains);
54 for (i = 0; i < cnt; i++) {
55 d = ptr_vector_get(&dm->registered_domains, i);
56 if (!d) continue;
57 if (remove_reference(&d->ref)) {
58 DEBUG_LOG("freeing domain: \'%.*s\'\n", FMT_STR(d->name));
59 destroy_notifier_domain(d);
60 }
61 }
62 ptr_vector_destroy(&dm->registered_domains);
63 cds_mutex_destroy(&dm->mutex);
64 cds_free(dm);
65 }
66
find_domain_nolock(domain_maintainer_t * dm,const str_t * name)67 static notifier_domain_t *find_domain_nolock(domain_maintainer_t *dm, const str_t *name)
68 {
69 notifier_domain_t *d = NULL;
70 int i, cnt;
71
72 cnt = ptr_vector_size(&dm->registered_domains);
73 for (i = 0; i < cnt; i++) {
74 d = ptr_vector_get(&dm->registered_domains, i);
75 if (!d) continue;
76 if (str_case_equals(&d->name, name) == 0) return d;
77 }
78 return NULL;
79 }
80
add_domain_nolock(domain_maintainer_t * dm,const str_t * name)81 static notifier_domain_t *add_domain_nolock(domain_maintainer_t *dm, const str_t *name)
82 {
83 notifier_domain_t *d = create_notifier_domain(dm->rc_grp, name);
84
85 if (d) {
86 DEBUG_LOG("created domain: \'%.*s\'\n", FMT_STR(d->name));
87 ptr_vector_add(&dm->registered_domains, d);
88 return d;
89 }
90 else return NULL;
91 }
92
93 /* notifier_domain_t *find_notifier_domain(domain_maintainer_t *dm, const str_t *name)
94 {
95 notifier_domain_t *d = NULL;
96
97 if (!dm) return NULL;
98 cds_mutex_lock(&dm->mutex);
99 d = find_domain_nolock(dm, name);
100 cds_mutex_unlock(&dm->mutex);
101 return d;
102 } */
103
register_notifier_domain(domain_maintainer_t * dm,const str_t * name)104 notifier_domain_t *register_notifier_domain(domain_maintainer_t *dm, const str_t *name)
105 {
106 notifier_domain_t *d = NULL;
107
108 if (!dm) return NULL;
109
110 cds_mutex_lock(&dm->mutex);
111 d = find_domain_nolock(dm, name);
112 if (!d) d = add_domain_nolock(dm, name);
113 if (d) {
114 add_reference(&d->ref); /* add reference for client */
115 }
116 cds_mutex_unlock(&dm->mutex);
117 return d;
118 }
119
remove_notifier_domain(domain_maintainer_t * dm,notifier_domain_t * domain)120 static void remove_notifier_domain(domain_maintainer_t *dm, notifier_domain_t *domain)
121 {
122 notifier_domain_t *d = NULL;
123 int i, cnt;
124
125 cnt = ptr_vector_size(&dm->registered_domains);
126 for (i = 0; i < cnt; i++) {
127 d = ptr_vector_get(&dm->registered_domains, i);
128 if (d == domain) {
129 ptr_vector_remove(&dm->registered_domains, i);
130 break;
131 }
132 }
133 }
134
release_notifier_domain(domain_maintainer_t * dm,notifier_domain_t * domain)135 void release_notifier_domain(domain_maintainer_t *dm, notifier_domain_t *domain)
136 {
137 if ((!dm) || (!domain)) return;
138
139 cds_mutex_lock(&dm->mutex);
140 if (remove_reference(&domain->ref)) {
141 /* last reference */
142 DEBUG_LOG("freeing domain: \'%.*s\'\n", FMT_STR(domain->name));
143 remove_notifier_domain(dm, domain);
144 destroy_notifier_domain(domain);
145 }
146 cds_mutex_unlock(&dm->mutex);
147 }
148
149