mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
channelstorage_cpp_map_name_id.cc: Refactor iterators for thread-safety.
The fact that deleting an object from a map invalidates any iterator that happens to currently point to that object was overlooked in the initial implementation. Unfortunately, there's no way to detect that an iterator has been invalidated so the result was an occasional SEGV triggered by modules like app_chanspy that opens an iterator and can keep it open for a long period of time. The new implementation doesn't keep the underlying C++ iterator open across calls to ast_channel_iterator_next() and uses a read lock on the map to ensure that, even for the few microseconds we use the iterator, another thread can't delete a channel from under it. Even with this change, the iterators are still WAY faster than the ao2_legacy storage driver. Full details about the new implementation are located in the comments for iterator_next() in channelstorage_cpp_map_name_id.cc. Resolves: #1309
This commit is contained in:
committed by
github-actions[bot]
parent
22d405e900
commit
baa73b6b12
@@ -277,76 +277,6 @@ static void *test_storage_thread(void *data)
|
||||
elapsed = ast_tvdiff_us(end, start);
|
||||
ast_test_status_update(test, "%*s: %8ld\n", collen, "by context/exten", elapsed);
|
||||
|
||||
#if 0
|
||||
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_or_uniqueid, search1);
|
||||
ast_test_validate_cleanup(test, mock_channel, res, done);
|
||||
|
||||
CHANNELSTORAGE_API(storage_instance, wrlock);
|
||||
|
||||
sprintf(mock_channel->context, "TestXXContext-%ld-%04d", rand, i);
|
||||
sprintf(search1, "TestContext-%ld-%04d", rand, i);
|
||||
|
||||
rc = CHANNELSTORAGE_API(storage_instance, update, mock_channel,
|
||||
AST_CHANNELSTORAGE_UPDATE_CONTEXT, search1, mock_channel->context, 0);
|
||||
ast_test_validate_cleanup(test, rc == 0, res, done);
|
||||
|
||||
sprintf(mock_channel->exten, "TestXXExten-%ld-%04d", rand, i);
|
||||
sprintf(search2, "TestExten-%ld-%04d", rand, i);
|
||||
|
||||
rc = CHANNELSTORAGE_API(storage_instance, update, mock_channel,
|
||||
AST_CHANNELSTORAGE_UPDATE_EXTEN, search2, mock_channel->exten, 0);
|
||||
CHANNELSTORAGE_API(storage_instance, unlock);
|
||||
|
||||
ast_test_validate_cleanup(test, rc == 0, res, done);
|
||||
|
||||
ast_channel_unref(mock_channel);
|
||||
}
|
||||
end = ast_tvnow();
|
||||
elapsed = ast_tvdiff_us(end, start);
|
||||
ast_test_status_update(test, "%*s: %8ld\n", collen, "update", elapsed);
|
||||
|
||||
start = ast_tvnow();
|
||||
for (i = 0; i < CHANNEL_COUNT; i++) {
|
||||
sprintf(search1, "TestXXContext-%ld-%04d", rand, i);
|
||||
sprintf(search2, "TestXXExten-%ld-%04d", rand, i);
|
||||
mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_exten, search2, search1);
|
||||
ast_test_validate_cleanup(test, mock_channel, res, done);
|
||||
ast_channel_unref(mock_channel);
|
||||
}
|
||||
end = ast_tvnow();
|
||||
elapsed = ast_tvdiff_us(end, start);
|
||||
ast_test_status_update(test, "%*s: %8ld\n", collen, "by context/exten2", elapsed);
|
||||
|
||||
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_or_uniqueid, search1);
|
||||
ast_test_validate_cleanup(test, mock_channel, res, done);
|
||||
sprintf(search2, "TestXXChannel-%ld-%04d", rand, i);
|
||||
rc = CHANNELSTORAGE_API(storage_instance, update, mock_channel,
|
||||
AST_CHANNELSTORAGE_UPDATE_NAME, search1, search2, 1);
|
||||
ast_channel_unref(mock_channel);
|
||||
ast_test_validate_cleanup(test, rc == 0, res, done);
|
||||
}
|
||||
end = ast_tvnow();
|
||||
elapsed = ast_tvdiff_us(end, start);
|
||||
ast_test_status_update(test, "%*s: %8ld\n", collen, "change name", elapsed);
|
||||
|
||||
start = ast_tvnow();
|
||||
for (i = 0; i < CHANNEL_COUNT; i++) {
|
||||
sprintf(search1, "TestXXChannel-%ld-%04d", rand, i);
|
||||
mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_or_uniqueid, search1);
|
||||
ast_test_validate_cleanup_custom(test, mock_channel, res, done,"Channel %s not found\n", search1);
|
||||
ast_channel_unref(mock_channel);
|
||||
}
|
||||
end = ast_tvnow();
|
||||
elapsed = ast_tvdiff_us(end, start);
|
||||
ast_test_status_update(test, "%*s: %8ld\n", collen, "by name exact2", elapsed);
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
start = ast_tvnow();
|
||||
iter = CHANNELSTORAGE_API(storage_instance, iterator_all_new);
|
||||
|
Reference in New Issue
Block a user