Changeset 5707
Use a rwlock to protect the dialplan data structures rather than a simple mutex
Comitted by:
mjagdis
Date:
Jun 04 2010 * 23:10 (about 1 year ago)
Affected files:
callweaver/trunk/corelib/callweaver.c (unified diff)
| r5697 | r5707 | |
|---|---|---|
| 152 | 152 | #include "console.h" |
| 153 | 153 | |
| 154 | 154 | |
| 155 | /* From corelib/pbx.c */ | |
| 156 | extern pthread_rwlock_t conlock; | |
| 157 | ||
| 158 | ||
| 155 | 159 | #if defined(_POSIX_TIMERS) |
| 156 | 160 | # if defined(_POSIX_MONOTONIC_CLOCK) && defined(__USE_XOPEN2K) |
| 157 | 161 | clockid_t global_clock_monotonic = CLOCK_MONOTONIC; |
| --- | --- | |
| 1751 | 1755 | if ((option_console || option_nofork) && !option_verbose) |
| 1752 | 1756 | cw_verbose("[ Initializing Custom Configuration Options ]"); |
| 1753 | 1757 | |
| 1758 | pthread_rwlock_init(&conlock, NULL); | |
| 1759 | ||
| 1754 | 1760 | cw_registry_init(&atexit_registry, 1); |
| 1755 | 1761 | cw_registry_init(&channel_registry, 1024); |
| 1756 | 1762 | cw_registry_init(&device_registry, 1024); |
callweaver/trunk/corelib/pbx.c (unified diff)
| r5700 | r5707 | |
|---|---|---|
| 166 | 166 | CW_MUTEX_DEFINE_STATIC(maxcalllock); |
| 167 | 167 | static int countcalls = 0; |
| 168 | 168 | |
| 169 | pthread_rwlock_t conlock; | |
| 169 | 170 | static struct cw_context *contexts = NULL; |
| 170 | CW_MUTEX_DEFINE_STATIC(conlock); /* Lock for the cw_context list */ | |
| 171 | 171 | |
| 172 | 172 | CW_MUTEX_DEFINE_STATIC(hintlock); /* Lock for extension state notifys */ |
| 173 | 173 | static int stateid = 1; |
| --- | --- | |
| 466 | 466 | |
| 467 | 467 | struct cw_context *cw_context_find(const char *name) |
| 468 | 468 | { |
| 469 | struct cw_context *tmp; | |
| 470 | unsigned int hash; | |
| 469 | struct cw_context *tmp; | |
| 470 | unsigned int hash; | |
| 471 | 471 | |
| 472 | cw_mutex_lock(&conlock); | |
| 473 | if (name) | |
| 474 | { | |
| 475 | hash = cw_hash_string(name); | |
| 476 | for (tmp = contexts; tmp; tmp = tmp->next) | |
| 477 | if (hash == tmp->hash && !strcmp(name, tmp->name)) | |
| 478 | break; | |
| 479 | } | |
| 480 | else | |
| 481 | { | |
| 482 | tmp = contexts; | |
| 483 | } | |
| 484 | cw_mutex_unlock(&conlock); | |
| 485 | return tmp; | |
| 472 | if (name) { | |
| 473 | pthread_rwlock_rdlock(&conlock); | |
| 474 | ||
| 475 | hash = cw_hash_string(name); | |
| 476 | for (tmp = contexts; tmp; tmp = tmp->next) | |
| 477 | if (hash == tmp->hash && !strcmp(name, tmp->name)) | |
| 478 | break; | |
| 479 | ||
| 480 | pthread_rwlock_unlock(&conlock); | |
| 481 | } else | |
| 482 | tmp = contexts; | |
| 483 | ||
| 484 | return tmp; | |
| 486 | 485 | } |
| 487 | 486 | |
| 488 | 487 | #define STATUS_NO_CONTEXT 1 |
| --- | --- | |
| 756 | 755 | |
| 757 | 756 | int pbx_retrieve_substr(struct cw_channel *chan, struct cw_registry *vars, char *src, size_t srclen, struct cw_dynstr *result) |
| 758 | 757 | { |
| 759 | struct cw_dynargs av = CW_DYNARRAY_INIT; | |
| 758 | struct cw_dynargs av; | |
| 760 | 759 | char *args; |
| 761 | 760 | size_t i; |
| 762 | 761 | int offset, length; |
| --- | --- | |
| 790 | 789 | |
| 791 | 790 | while (i && isspace(src[i])) i--; |
| 792 | 791 | |
| 792 | cw_dynargs_init(&av, 1, 1); | |
| 793 | 793 | args = NULL; |
| 794 | 794 | if (!cw_split_args(&av, src, "\0", '(', &args)) { |
| 795 | 795 | if (args) { |
| --- | --- | |
| 857 | 857 | } else |
| 858 | 858 | result->error = 1; |
| 859 | 859 | |
| 860 | cw_dynargs_free(&av); | |
| 860 | 861 | return res; |
| 861 | 862 | } |
| 862 | 863 | |
| --- | --- | |
| 1111 | 1112 | int stacklen = 0; |
| 1112 | 1113 | int res = -1; |
| 1113 | 1114 | |
| 1114 | cw_mutex_lock(&conlock); | |
| 1115 | pthread_rwlock_rdlock(&conlock); | |
| 1115 | 1116 | |
| 1116 | 1117 | e = pbx_find_extension(c, con, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data, &foundcontext); |
| 1117 | 1118 | |
| --- | --- | |
| 1125 | 1126 | case HELPER_CANMATCH: |
| 1126 | 1127 | case HELPER_EXISTS: |
| 1127 | 1128 | case HELPER_MATCHMORE: |
| 1128 | cw_mutex_unlock(&conlock); | |
| 1129 | pthread_rwlock_unlock(&conlock); | |
| 1129 | 1130 | break; |
| 1130 | 1131 | case HELPER_EXEC: |
| 1131 | cw_mutex_unlock(&conlock); | |
| 1132 | pthread_rwlock_unlock(&conlock); | |
| 1132 | 1133 | if (c->context != context) |
| 1133 | 1134 | cw_copy_string(c->context, context, sizeof(c->context)); |
| 1134 | 1135 | if (c->exten != exten) |
| --- | --- | |
| 1165 | 1166 | case HELPER_EXISTS: |
| 1166 | 1167 | case HELPER_MATCHMORE: |
| 1167 | 1168 | case HELPER_FINDLABEL: |
| 1168 | cw_mutex_unlock(&conlock); | |
| 1169 | pthread_rwlock_unlock(&conlock); | |
| 1169 | 1170 | break; |
| 1170 | 1171 | case HELPER_EXEC: |
| 1171 | cw_mutex_unlock(&conlock); | |
| 1172 | pthread_rwlock_unlock(&conlock); | |
| 1172 | 1173 | if (sw->exec) |
| 1173 | 1174 | res = sw->exec(c, (foundcontext ? foundcontext : context), exten, priority, callerid, data.data); |
| 1174 | 1175 | else |
| --- | --- | |
| 1181 | 1182 | } |
| 1182 | 1183 | else |
| 1183 | 1184 | { |
| 1184 | cw_mutex_unlock(&conlock); | |
| 1185 | pthread_rwlock_unlock(&conlock); | |
| 1185 | 1186 | switch (status) |
| 1186 | 1187 | { |
| 1187 | 1188 | case STATUS_NO_CONTEXT: |
| --- | --- | |
| 1226 | 1227 | char *incstack[CW_PBX_MAX_STACK]; |
| 1227 | 1228 | int stacklen = 0; |
| 1228 | 1229 | |
| 1229 | cw_mutex_lock(&conlock); | |
| 1230 | pthread_rwlock_rdlock(&conlock); | |
| 1230 | 1231 | |
| 1231 | 1232 | e = pbx_find_extension(c, NULL, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data, &foundcontext); |
| 1232 | 1233 | |
| 1233 | cw_mutex_unlock(&conlock); | |
| 1234 | pthread_rwlock_rdlock(&conlock); | |
| 1234 | 1235 | |
| 1235 | 1236 | cw_dynstr_free(&data); |
| 1236 | 1237 | |
| --- | --- | |
| 2875 | 2876 | |
| 2876 | 2877 | length = sizeof(struct cw_context); |
| 2877 | 2878 | length += strlen(name) + 1; |
| 2879 | ||
| 2878 | 2880 | if (!extcontexts) |
| 2879 | 2881 | { |
| 2880 | 2882 | local_contexts = &contexts; |
| 2881 | cw_mutex_lock(&conlock); | |
| 2883 | pthread_rwlock_wrlock(&conlock); | |
| 2882 | 2884 | } |
| 2883 | 2885 | else |
| 2884 | 2886 | { |
| --- | --- | |
| 2890 | 2892 | if (hash == tmp->hash && !strcmp(name, tmp->name)) |
| 2891 | 2893 | { |
| 2892 | 2894 | if (!extcontexts) |
| 2893 | cw_mutex_unlock(&conlock); | |
| 2895 | pthread_rwlock_unlock(&conlock); | |
| 2894 | 2896 | cw_log(CW_LOG_WARNING, "Failed to register context '%s' because it is already in use\n", name); |
| 2895 | 2897 | return NULL; |
| 2896 | 2898 | } |
| --- | --- | |
| 2919 | 2921 | } |
| 2920 | 2922 | |
| 2921 | 2923 | if (!extcontexts) |
| 2922 | cw_mutex_unlock(&conlock); | |
| 2924 | pthread_rwlock_unlock(&conlock); | |
| 2923 | 2925 | return tmp; |
| 2924 | 2926 | } |
| 2925 | 2927 | |
| --- | --- | |
| 4619 | 4621 | struct cw_exten *e, *el, *en; |
| 4620 | 4622 | struct cw_ignorepat *ipi, *ipl = NULL; |
| 4621 | 4623 | |
| 4622 | cw_mutex_lock(&conlock); | |
| 4624 | pthread_rwlock_wrlock(&conlock); | |
| 4623 | 4625 | tmp = contexts; |
| 4624 | 4626 | while (tmp) |
| 4625 | 4627 | { |
| --- | --- | |
| 4685 | 4687 | tmpil = NULL; |
| 4686 | 4688 | continue; |
| 4687 | 4689 | } |
| 4688 | cw_mutex_unlock(&conlock); | |
| 4690 | pthread_rwlock_unlock(&conlock); | |
| 4689 | 4691 | return; |
| 4690 | 4692 | } |
| 4691 | 4693 | tmpl = tmp; |
| 4692 | 4694 | tmp = tmp->next; |
| 4693 | 4695 | } |
| 4694 | cw_mutex_unlock(&conlock); | |
| 4696 | pthread_rwlock_unlock(&conlock); | |
| 4695 | 4697 | } |
| 4696 | 4698 | |
| 4697 | 4699 | |
| --- | --- | |
| 4731 | 4733 | cw_mutex_unlock(&hintlock); |
| 4732 | 4734 | |
| 4733 | 4735 | tmp = *extcontexts; |
| 4734 | cw_mutex_lock(&conlock); | |
| 4735 | 4736 | if (registrar) |
| 4736 | 4737 | { |
| 4737 | 4738 | cw_context_destroy(NULL,registrar); |
| --- | --- | |
| 4752 | 4753 | } |
| 4753 | 4754 | if (lasttmp) |
| 4754 | 4755 | { |
| 4756 | pthread_rwlock_wrlock(&conlock); | |
| 4755 | 4757 | lasttmp->next = contexts; |
| 4756 | 4758 | contexts = *extcontexts; |
| 4759 | pthread_rwlock_unlock(&conlock); | |
| 4757 | 4760 | *extcontexts = NULL; |
| 4758 | 4761 | } |
| 4759 | 4762 | else |
| 4760 | 4763 | { |
| 4761 | 4764 | cw_log(CW_LOG_WARNING, "Requested contexts could not be merged\n"); |
| 4762 | 4765 | } |
| 4763 | cw_mutex_unlock(&conlock); | |
| 4764 | 4766 | |
| 4765 | 4767 | /* restore the watchers for hints that can be found; notify those that |
| 4766 | 4768 | cannot be restored |
| --- | --- | |
| 4921 | 4923 | */ |
| 4922 | 4924 | int cw_lock_contexts() |
| 4923 | 4925 | { |
| 4924 | return cw_mutex_lock(&conlock); | |
| 4926 | return pthread_rwlock_rdlock(&conlock); | |
| 4925 | 4927 | } |
| 4926 | 4928 | |
| 4927 | 4929 | int cw_unlock_contexts() |
| 4928 | 4930 | { |
| 4929 | return cw_mutex_unlock(&conlock); | |
| 4931 | return pthread_rwlock_unlock(&conlock); | |
| 4930 | 4932 | } |
| 4931 | 4933 | |
| 4932 | 4934 | /* |
![Home changeset 5707 [home]](/images/logo.png?1180520111)

RSS Feeds