[svn-commits] russell: branch 1.4 r63445 -
/branches/1.4/res/res_features.c
svn-commits at lists.digium.com
svn-commits at lists.digium.com
Tue May 8 09:30:44 MST 2007
Author: russell
Date: Tue May 8 11:30:43 2007
New Revision: 63445
URL: http://svn.digium.com/view/asterisk?view=rev&rev=63445
Log:
Use a read/write lock when accessing the built-in features.
Modified:
branches/1.4/res/res_features.c
Modified: branches/1.4/res/res_features.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_features.c?view=diff&rev=63445&r1=63444&r2=63445
==============================================================================
--- branches/1.4/res/res_features.c (original)
+++ branches/1.4/res/res_features.c Tue May 8 11:30:43 2007
@@ -878,7 +878,9 @@
/* add atxfer and automon as undefined so you can only use em if you configure them */
#define FEATURES_COUNT (sizeof(builtin_features) / sizeof(builtin_features[0]))
-struct ast_call_feature builtin_features[] =
+AST_RWLOCK_DEFINE_STATIC(features_lock);
+
+static struct ast_call_feature builtin_features[] =
{
{ AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
{ AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
@@ -930,16 +932,14 @@
}
/*! \brief find a feature by name */
-static struct ast_call_feature *find_feature(char *name)
+static struct ast_call_feature *find_feature(const char *name)
{
struct ast_call_feature *tmp;
- AST_LIST_LOCK(&feature_list);
AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
if (!strcasecmp(tmp->sname, name))
break;
}
- AST_LIST_UNLOCK(&feature_list);
return tmp;
}
@@ -1016,23 +1016,25 @@
static void unmap_features(void)
{
int x;
+
+ ast_rwlock_wrlock(&features_lock);
for (x = 0; x < FEATURES_COUNT; x++)
strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
+ ast_rwlock_unlock(&features_lock);
}
static int remap_feature(const char *name, const char *value)
{
- int x;
int res = -1;
- for (x = 0; x < FEATURES_COUNT; x++) {
- if (!strcasecmp(name, builtin_features[x].sname)) {
- ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Remapping feature %s (%s) to sequence '%s'\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
- res = 0;
- } else if (!strcmp(value, builtin_features[x].exten))
- ast_log(LOG_WARNING, "Sequence '%s' already mapped to function %s (%s) while assigning to %s\n", value, builtin_features[x].fname, builtin_features[x].sname, name);
- }
+ struct ast_call_feature *feature;
+
+ ast_rwlock_wrlock(&features_lock);
+ if ((feature = find_feature(name))) {
+ ast_copy_string(feature->exten, value, sizeof(feature->exten));
+ res = 0;
+ }
+ ast_rwlock_unlock(&features_lock);
+
return res;
}
@@ -1043,6 +1045,7 @@
int res = FEATURE_RETURN_PASSDIGITS;
struct ast_call_feature *feature;
const char *dynamic_features=pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES");
+ char *tmp, *tok;
if (sense == FEATURE_SENSE_CHAN)
ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
@@ -1051,7 +1054,8 @@
if (option_debug > 2)
ast_log(LOG_DEBUG, "Feature interpret: chan=%s, peer=%s, sense=%d, features=%d\n", chan->name, peer->name, sense, features.flags);
- for (x=0; x < FEATURES_COUNT; x++) {
+ ast_rwlock_rdlock(&features_lock);
+ for (x = 0; x < FEATURES_COUNT; x++) {
if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
!ast_strlen_zero(builtin_features[x].exten)) {
/* Feature is up for consideration */
@@ -1064,27 +1068,31 @@
}
}
}
-
-
- if (!ast_strlen_zero(dynamic_features)) {
- char *tmp = ast_strdupa(dynamic_features);
- char *tok;
-
- while ((tok = strsep(&tmp, "#")) != NULL) {
- feature = find_feature(tok);
+ ast_rwlock_unlock(&features_lock);
+
+ if (ast_strlen_zero(dynamic_features))
+ return res;
+
+ tmp = ast_strdupa(dynamic_features);
+
+ while ((tok = strsep(&tmp, "#"))) {
+ ast_rwlock_rdlock(&features_lock);
+ if (!(feature = find_feature(tok))) {
+ ast_rwlock_unlock(&features_lock);
+ continue;
+ }
- if (feature) {
- /* Feature is up for consideration */
- if (!strcmp(feature->exten, code)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
- res = feature->operation(chan, peer, config, code, sense);
- break;
- } else if (!strncmp(feature->exten, code, strlen(code))) {
- res = FEATURE_RETURN_STOREDIGITS;
- }
- }
- }
+ /* Feature is up for consideration */
+ if (!strcmp(feature->exten, code)) {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
+ res = feature->operation(chan, peer, config, code, sense);
+ ast_rwlock_unlock(&features_lock);
+ break;
+ } else if (!strncmp(feature->exten, code, strlen(code)))
+ res = FEATURE_RETURN_STOREDIGITS;
+
+ ast_rwlock_unlock(&features_lock);
}
return res;
@@ -1094,16 +1102,20 @@
{
int x;
- ast_clear_flag(config, AST_FLAGS_ALL);
+ ast_clear_flag(config, AST_FLAGS_ALL);
+
+ ast_rwlock_rdlock(&features_lock);
for (x = 0; x < FEATURES_COUNT; x++) {
- if (ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF)) {
- if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
-
- if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
- }
- }
+ if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
+ continue;
+
+ if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
+ ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
+
+ if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
+ ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
+ }
+ ast_rwlock_unlock(&features_lock);
if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
@@ -1115,12 +1127,14 @@
/* while we have a feature */
while ((tok = strsep(&tmp, "#"))) {
+ ast_rwlock_rdlock(&features_lock);
if ((feature = find_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
}
+ ast_rwlock_unlock(&features_lock);
}
}
}
@@ -1156,7 +1170,8 @@
ast_indicate(caller, AST_CONTROL_RINGING);
/* support dialing of the featuremap disconnect code while performing an attended tranfer */
- for (x=0; x < FEATURES_COUNT; x++) {
+ ast_rwlock_rdlock(&features_lock);
+ for (x = 0; x < FEATURES_COUNT; x++) {
if (strcasecmp(builtin_features[x].sname, "disconnect"))
continue;
@@ -1166,6 +1181,7 @@
memset(dialed_code, 0, len);
break;
}
+ ast_rwlock_unlock(&features_lock);
x = 0;
started = ast_tvnow();
to = timeout;
@@ -1917,7 +1933,6 @@
static int handle_showfeatures(int fd, int argc, char *argv[])
{
int i;
- int fcount;
struct ast_call_feature *feature;
char format[] = "%-25s %-7s %-7s\n";
@@ -1926,23 +1941,20 @@
ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext()); /* default hardcoded above, so we'll hardcode it here */
- fcount = sizeof(builtin_features) / sizeof(builtin_features[0]);
-
- for (i = 0; i < fcount; i++)
- {
+ ast_rwlock_rdlock(&features_lock);
+ for (i = 0; i < FEATURES_COUNT; i++)
ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
- }
+ ast_rwlock_unlock(&features_lock);
+
ast_cli(fd, "\n");
ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
ast_cli(fd, format, "---------------", "-------", "-------");
- if (AST_LIST_EMPTY(&feature_list)) {
+ if (AST_LIST_EMPTY(&feature_list))
ast_cli(fd, "(none)\n");
- }
else {
AST_LIST_LOCK(&feature_list);
- AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
+ AST_LIST_TRAVERSE(&feature_list, feature, feature_entry)
ast_cli(fd, format, feature->sname, "no def", feature->exten);
- }
AST_LIST_UNLOCK(&feature_list);
}
ast_cli(fd, "\nCall parking\n");
More information about the svn-commits
mailing list