/*! \brief returns number of active/allocated channels */
int ast_active_channels(void)
{
- return current_channel_storage_instance ? CHANNELSTORAGE_API(current_channel_storage_instance, active_channels) : 0;
+ return current_channel_storage_instance ? CHANNELSTORAGE_API(current_channel_storage_instance, active_channels, 1) : 0;
}
int ast_undestroyed_channels(void)
static void ast_channel_destructor(void *obj);
static void ast_dummy_channel_destructor(void *obj);
-static int do_ids_conflict(const struct ast_assigned_ids *assignedids)
+static int do_ids_conflict(const struct ast_assigned_ids *assignedids, int rdlock)
{
struct ast_channel *conflict;
if (!ast_strlen_zero(assignedids->uniqueid)) {
conflict = CHANNELSTORAGE_API(current_channel_storage_instance,
- get_by_uniqueid, assignedids->uniqueid);
+ get_by_uniqueid, assignedids->uniqueid, rdlock);
if (conflict) {
ast_log(LOG_ERROR, "Channel Unique ID '%s' already in use by channel %s(%p)\n",
assignedids->uniqueid, ast_channel_name(conflict), conflict);
if (!ast_strlen_zero(assignedids->uniqueid2)) {
conflict = CHANNELSTORAGE_API(current_channel_storage_instance,
- get_by_uniqueid, assignedids->uniqueid2);
+ get_by_uniqueid, assignedids->uniqueid2, rdlock);
if (conflict) {
ast_log(LOG_ERROR, "Channel Unique ID2 '%s' already in use by channel %s(%p)\n",
assignedids->uniqueid2, ast_channel_name(conflict), conflict);
CHANNELSTORAGE_API(current_channel_storage_instance, wrlock);
- if (do_ids_conflict(assignedids)) {
+ if (do_ids_conflict(assignedids, 0)) {
ast_channel_internal_errno_set(AST_CHANNEL_ERROR_ID_EXISTS);
ast_channel_unlock(tmp);
CHANNELSTORAGE_API(current_channel_storage_instance, unlock);
ast_log(LOG_ERROR, "callback function must be provided\n");
return NULL;
}
- return CHANNELSTORAGE_API(current_channel_storage_instance, callback, cb_fn, arg, data, ao2_flags);
+ return CHANNELSTORAGE_API(current_channel_storage_instance, callback, cb_fn, arg, data, ao2_flags, 1);
}
struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_iterator *i)
return NULL;
}
- return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_name_prefix_or_uniqueid, name, name_len);
+ return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_name_prefix_or_uniqueid, name, name_len, 1);
}
/*
return NULL;
}
- return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_name_prefix_or_uniqueid, name, 0);
+ return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_name_prefix_or_uniqueid, name, 0, 1);
}
struct ast_channel *ast_channel_get_by_exten(const char *exten, const char *context)
ast_log(LOG_ERROR, "exten and context must be provided\n");
return NULL;
}
- return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_exten, exten, context);
+ return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_exten, exten, context, 1);
}
struct ast_channel *ast_channel_get_by_uniqueid(const char *uniqueid)
ast_log(LOG_ERROR, "uniqueid must be provided\n");
return NULL;
}
- return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_uniqueid, uniqueid);
+ return CHANNELSTORAGE_API(current_channel_storage_instance, get_by_uniqueid, uniqueid, 1);
}
int ast_is_deferrable_frame(const struct ast_frame *frame)
}
struct ast_channel *channelstorage_by_exten(struct ast_channelstorage_instance *driver,
- const char *exten, const char *context)
+ const char *exten, const char *context, int rdlock)
{
char *l_exten = (char *) exten;
char *l_context = (char *) context;
- return CHANNELSTORAGE_API(driver, callback, channelstorage_exten_cb, l_context, l_exten, 0);
+ return CHANNELSTORAGE_API(driver, callback, channelstorage_exten_cb, l_context, l_exten, 0, rdlock);
}
int channelstorage_name_cb(void *obj, void *arg, void *data, int flags)
}
struct ast_channel *channelstorage_by_name_or_uniqueid(struct ast_channelstorage_instance *driver,
- const char *name)
+ const char *name, int rdlock)
{
- return CHANNELSTORAGE_API(driver, get_by_name_prefix_or_uniqueid, name, 0);
+ return CHANNELSTORAGE_API(driver, get_by_name_prefix_or_uniqueid, name, 0, rdlock);
}
struct ast_channel *channelstorage_by_name_prefix_or_uniqueid(struct ast_channelstorage_instance *driver,
- const char *name, size_t name_len)
+ const char *name, size_t name_len, int rdlock)
{
struct ast_channel *chan = NULL;
- chan = CHANNELSTORAGE_API(driver, get_by_name_prefix, name, name_len);
+ chan = CHANNELSTORAGE_API(driver, get_by_name_prefix, name, name_len, rdlock);
if (chan) {
return chan;
}
if (name_len == 0) {
- chan = CHANNELSTORAGE_API(driver, get_by_uniqueid, name);
+ chan = CHANNELSTORAGE_API(driver, get_by_uniqueid, name, rdlock);
}
return chan;
}
struct ast_channel *channelstorage_by_uniqueid(struct ast_channelstorage_instance *driver,
- const char *uniqueid)
+ const char *uniqueid, int rdlock)
{
- return CHANNELSTORAGE_API(driver, callback, channelstorage_uniqueid_cb, (char *)uniqueid, NULL, 0);
+ return CHANNELSTORAGE_API(driver, callback, channelstorage_uniqueid_cb, (char *)uniqueid, NULL, 0, rdlock);
}
#ifdef TEST_FRAMEWORK
}
end = ast_tvnow();
elapsed = ast_tvdiff_us(end, start);
- i = CHANNELSTORAGE_API(storage_instance, active_channels);
+ i = CHANNELSTORAGE_API(storage_instance, active_channels, 1);
ast_test_status_update(test, "%*s: %8ld\n", collen, "create channels", elapsed);
ast_test_validate_cleanup(test, i == CHANNEL_COUNT, res, done);
start = ast_tvnow();
for (i = 0; i < CHANNEL_COUNT; i++) {
sprintf(search1, "testchannel-%ld-%04d-something", rand, i);
- mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, 0);
+ mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, 0, 1);
ast_test_validate_cleanup(test, mock_channel, res, done);
ast_test_validate_cleanup(test, mock_channel == test_channels[i], res, done);
ast_test_validate_cleanup(test,
start = ast_tvnow();
for (i = 0; i < CHANNEL_COUNT; i++) {
sprintf(search1, "TestUniqueid-%ld-%04d-something", rand, i);
- mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_uniqueid, search1);
+ mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_uniqueid, search1, 1);
ast_test_validate_cleanup(test, mock_channel, res, done);
ast_channel_unref(mock_channel);
}
start = ast_tvnow();
for (i = 0; i < CHANNEL_COUNT; i++) {
sprintf(search1, "TestUniqueid-%ld-%04d-something", rand, i);
- mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, 0);
+ mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, 0, 1);
ast_test_validate_cleanup(test, mock_channel, res, done);
ast_channel_unref(mock_channel);
}
start = ast_tvnow();
for (i = 0; i < CHANNEL_COUNT; i++) {
sprintf(search1, "TestChannel-%ld-%04d", rand, i);
- mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, strlen(search1));
+ mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, strlen(search1), 1);
ast_test_validate_cleanup(test, mock_channel, res, done);
ast_channel_unref(mock_channel);
}
for (i = 0; i < CHANNEL_COUNT; i++) {
sprintf(search1, "TestContext-%ld-%04d", rand, i % 100);
sprintf(search2, "TestExten-%ld-%04d", rand, i % 10);
- mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_exten, search2, search1);
+ mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_exten, search2, search1, 1);
ast_test_validate_cleanup(test, mock_channel, res, done);
ast_channel_unref(mock_channel);
}
ast_test_status_update(test, "%*s: %8ld\n", collen, "iter all chan", elapsed);
ast_test_validate_cleanup_custom(test, i == CHANNEL_COUNT, res, done,
"Expected %d channels, got %d, in container: %d\n", CHANNEL_COUNT, i,
- CHANNELSTORAGE_API(storage_instance, active_channels));
+ CHANNELSTORAGE_API(storage_instance, active_channels, 1));
i = 0;
start = ast_tvnow();
ast_test_status_update(test, "%*s: %8ld\n", collen, "iter 10 partial name", elapsed);
ast_test_validate_cleanup_custom(test, i == 10, res, done,
"Expected %d channels, got %d, in container: %d\n", 10, i,
- CHANNELSTORAGE_API(storage_instance, active_channels));
+ CHANNELSTORAGE_API(storage_instance, active_channels, 1));
i = 0;
start = ast_tvnow();
elapsed = ast_tvdiff_us(end, start);
ast_test_status_update(test, "%*s: %8ld\n", collen, "del all channels", elapsed);
ast_test_validate_cleanup(test, i == CHANNEL_COUNT, res, done);
- rc = CHANNELSTORAGE_API(storage_instance, active_channels);
+ rc = CHANNELSTORAGE_API(storage_instance, active_channels, 1);
ast_test_validate_cleanup_custom(test, rc == 0, res, final,
"There are still %d channels in the container\n", rc);
void (*rdlock)(struct ast_channelstorage_instance *driver);
void (*wrlock)(struct ast_channelstorage_instance *driver);
void (*unlock)(struct ast_channelstorage_instance *driver);
- int (*active_channels)(struct ast_channelstorage_instance *driver);
+ int (*active_channels)(struct ast_channelstorage_instance *driver, int rdlock);
struct ast_channel *(*callback)(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn,
- void *arg, void *data, int ao2_flags);
- struct ast_channel *(*get_by_name_prefix)(struct ast_channelstorage_instance *driver, const char *name, size_t len);
- struct ast_channel *(*get_by_name_prefix_or_uniqueid)(struct ast_channelstorage_instance *driver, const char *name, size_t len);
- struct ast_channel *(*get_by_exten)(struct ast_channelstorage_instance *driver, const char *exten, const char *context);
- struct ast_channel *(*get_by_uniqueid)(struct ast_channelstorage_instance *driver, const char *uniqueid);
+ void *arg, void *data, int ao2_flags, int rdlock);
+ struct ast_channel *(*get_by_name_prefix)(struct ast_channelstorage_instance *driver, const char *name, size_t len, int rdlock);
+ struct ast_channel *(*get_by_name_prefix_or_uniqueid)(struct ast_channelstorage_instance *driver, const char *name, size_t len, int rdlock);
+ struct ast_channel *(*get_by_exten)(struct ast_channelstorage_instance *driver, const char *exten, const char *context, int rdlock);
+ struct ast_channel *(*get_by_uniqueid)(struct ast_channelstorage_instance *driver, const char *uniqueid, int rdlock);
struct ast_channel_iterator *(*iterator_all_new)(struct ast_channelstorage_instance *driver);
struct ast_channel_iterator *(*iterator_by_exten_new)
(struct ast_channelstorage_instance *driver, const char *exten, const char *context);
int channelstorage_exten_cb(void *obj, void *arg, void *data, int flags);
struct ast_channel *channelstorage_by_exten(struct ast_channelstorage_instance *driver,
- const char *exten, const char *context);
+ const char *exten, const char *context, int rdlock);
int channelstorage_name_cb(void *obj, void *arg, void *data, int flags);
struct ast_channel *channelstorage_by_name_or_uniqueid(struct ast_channelstorage_instance *driver,
- const char *name);
+ const char *name, int rdlock);
struct ast_channel *channelstorage_by_name_prefix_or_uniqueid(struct ast_channelstorage_instance *driver,
- const char *name, size_t name_len);
+ const char *name, size_t name_len, int rdlock);
int channelstorage_uniqueid_cb(void *obj, void *arg, void *data, int flags);
struct ast_channel *channelstorage_by_uniqueid(struct ast_channelstorage_instance *driver,
- const char *uniqueid);
+ const char *uniqueid, int rdlock);
#if defined(__cplusplus) || defined(c_plusplus)
}
}
/*! \brief returns number of active/allocated channels */
-static int active_channels(struct ast_channelstorage_instance *driver)
+static int active_channels(struct ast_channelstorage_instance *driver, int rdlock)
{
return getdb(driver) ? ao2_container_count(getdb(driver)) : 0;
}
static struct ast_channel *callback(struct ast_channelstorage_instance *driver,
- ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
+ ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
{
return ao2_callback_data(getdb(driver), ao2_flags, cb_fn, arg, data);
}
}
i->active_iterator = (void *) callback(driver, by_exten_cb,
- l_context, l_exten, OBJ_MULTIPLE);
+ l_context, l_exten, OBJ_MULTIPLE, 1);
if (!i->active_iterator) {
ast_free(i);
return NULL;
i->active_iterator = (void *) callback(driver, by_name_cb,
l_name, &name_len,
- OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0));
+ OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0), 1);
if (!i->active_iterator) {
ast_free(i);
return NULL;
}
static struct ast_channel *get_by_uniqueid(struct ast_channelstorage_instance *driver,
- const char *uniqueid)
+ const char *uniqueid, int lock)
{
char *l_name = (char *) uniqueid;
size_t name_len = strlen(uniqueid);
- struct ast_channel *chan = callback(driver, by_uniqueid_cb, l_name, &name_len, 0);
+ struct ast_channel *chan = callback(driver, by_uniqueid_cb, l_name, &name_len, 0, lock);
return chan;
}
static struct ast_channel *get_by_name_prefix(struct ast_channelstorage_instance *driver,
- const char *name, size_t name_len)
+ const char *name, size_t name_len, int lock)
{
struct ast_channel *chan;
char *l_name = (char *) name;
}
chan = callback(driver, by_name_cb, l_name, &name_len,
- (name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0);
+ (name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0, lock);
if (chan) {
return chan;
}
/* Now try a search for uniqueid. */
- chan = callback(driver, by_uniqueid_cb, l_name, &name_len, 0);
+ chan = callback(driver, by_uniqueid_cb, l_name, &name_len, 0, lock);
return chan;
}
static struct ast_channel *get_by_exten(struct ast_channelstorage_instance *driver,
- const char *exten, const char *context)
+ const char *exten, const char *context, int rdlock)
{
char *l_exten = (char *) exten;
char *l_context = (char *) context;
- return callback(driver, by_exten_cb, l_context, l_exten, 0);
+ return callback(driver, by_exten_cb, l_context, l_exten, 0, rdlock);
}
static int hash_cb(const void *obj, const int flags)
}
/*! \brief returns number of active/allocated channels */
-static int active_channels(struct ast_channelstorage_instance *driver)
+static int active_channels(struct ast_channelstorage_instance *driver, int lock)
{
int count = 0;
return 0;
}
- rdlock(driver);
+ if (lock) {
+ rdlock(driver);
+ }
count = getdb(driver).size();
- unlock(driver);
+ if (lock) {
+ unlock(driver);
+ }
return count;
}
static struct ast_channel *callback(struct ast_channelstorage_instance *driver,
- ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
+ ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int lock)
{
struct ast_channel *chan = NULL;
ChannelMap::const_iterator it;
return NULL;
}
- rdlock(driver);
+ if (lock) {
+ rdlock(driver);
+ }
for (it = getdb(driver).begin(); it != getdb(driver).end(); it++) {
chan = it->second;
if (cb_fn(chan, arg, data, ao2_flags) == (CMP_MATCH | CMP_STOP)) {
ao2_bump(chan);
- unlock(driver);
- return chan;
+ break;
}
}
- unlock(driver);
+ if (lock) {
+ unlock(driver);
+ }
- return NULL;
+ return chan;
}
enum cpp_map_iterator_type {
}
static struct ast_channel *get_by_uniqueid(struct ast_channelstorage_instance *driver,
- const char *uniqueid)
+ const char *uniqueid, int lock)
{
struct ast_channel *chan = NULL;
char *search = uniqueid ? ast_str_to_lower(ast_strdupa(uniqueid)) : NULL;
return NULL;
}
- rdlock(driver);
+ if (lock) {
+ rdlock(driver);
+ }
auto rtn = map_by_id(driver).find(search);
if (rtn != map_by_id(driver).end()) {
chan = ao2_bump((struct ast_channel *)rtn->second);
}
- unlock(driver);
+ if (lock) {
+ unlock(driver);
+ }
return chan;
}
static struct ast_channel *get_by_name_exact(struct ast_channelstorage_instance *driver,
- const char *name)
+ const char *name, int lock)
{
struct ast_channel *chan = NULL;
char *search = name ? ast_str_to_lower(ast_strdupa(name)) : NULL;
return NULL;
}
- rdlock(driver);
+ if (lock) {
+ rdlock(driver);
+ }
auto rtn = getdb(driver).find(search);
if (rtn != getdb(driver).end()) {
chan = ao2_bump((struct ast_channel *)rtn->second);
}
- unlock(driver);
+ if (lock) {
+ unlock(driver);
+ }
return chan;
}
static struct ast_channel *get_by_name_prefix(struct ast_channelstorage_instance *driver,
- const char *name, size_t name_len)
+ const char *name, size_t name_len, int lock)
{
struct ast_channel *chan = NULL;
char *l_name = NULL;
if (name_len == 0) {
- chan = get_by_name_exact(driver, name);
+ chan = get_by_name_exact(driver, name, lock);
return chan;
}
l_name = ast_str_to_lower(ast_strdupa(name));
- rdlock(driver);
+ if (lock) {
+ rdlock(driver);
+ }
auto rtn = getdb(driver).lower_bound(l_name);
if (rtn != getdb(driver).end()) {
chan = ao2_bump((struct ast_channel *)rtn->second);
}
- unlock(driver);
+ if (lock) {
+ unlock(driver);
+ }
return chan;
}