Browse Source

SERVER-84229 Move LockManager::getLockerToClientMap out of the LockManager

GitOrigin-RevId: 1ee5e8a02a
pull/1587/head
Kaloian Manassiev 3 years ago
committed by MongoDB Bot
parent
commit
32784fb36f
  1. 4
      src/mongo/client/SConscript
  2. 4
      src/mongo/crypto/SConscript
  3. 85
      src/mongo/db/SConscript
  4. 31
      src/mongo/db/auth/SConscript
  5. 5
      src/mongo/db/catalog/SConscript
  6. 2
      src/mongo/db/commands/SConscript
  7. 27
      src/mongo/db/commands/lock_info.cpp
  8. 2
      src/mongo/db/concurrency/d_concurrency.cpp
  9. 3
      src/mongo/db/concurrency/d_concurrency.h
  10. 32
      src/mongo/db/concurrency/lock_manager.cpp
  11. 26
      src/mongo/db/concurrency/lock_manager.h
  12. 2
      src/mongo/db/concurrency/locker.cpp
  13. 6
      src/mongo/db/concurrency/locker.h
  14. 24
      src/mongo/db/concurrency/locker_impl.cpp
  15. 129
      src/mongo/db/concurrency/locker_impl.h
  16. 35
      src/mongo/db/dump_lock_manager_impl.cpp
  17. 46
      src/mongo/db/dump_lock_manager_impl.h
  18. 5
      src/mongo/db/ftdc/SConscript
  19. 1
      src/mongo/db/index/SConscript
  20. 1
      src/mongo/db/op_observer/SConscript
  21. 5
      src/mongo/db/pipeline/SConscript
  22. 3
      src/mongo/db/process_health/SConscript
  23. 1
      src/mongo/db/query/SConscript
  24. 19
      src/mongo/db/repl/SConscript
  25. 2
      src/mongo/db/s/SConscript
  26. 2
      src/mongo/db/session/SConscript
  27. 8
      src/mongo/db/storage/SConscript
  28. 1
      src/mongo/db/storage/wiredtiger/SConscript
  29. 3
      src/mongo/db/transaction_resources_init_mongod.cpp
  30. 3
      src/mongo/db/transaction_resources_init_non_mongod.cpp
  31. 8
      src/mongo/rpc/SConscript
  32. 5
      src/mongo/s/SConscript
  33. 3
      src/mongo/s/query/SConscript
  34. 2
      src/mongo/s/sharding_state.cpp
  35. 9
      src/mongo/scripting/SConscript
  36. 2
      src/mongo/transport/SConscript
  37. 82
      src/mongo/util/SConscript
  38. 14
      src/mongo/util/cryptd/SConscript
  39. 16
      src/mongo/util/net/SConscript
  40. 5
      src/mongo/watchdog/SConscript

4
src/mongo/client/SConscript

@ -308,7 +308,7 @@ env.Library(
'remote_command_targeter_mock.cpp', 'remote_command_targeter_mock.cpp',
'remote_command_targeter_factory_mock.cpp', 'remote_command_targeter_factory_mock.cpp',
], ],
LIBDEPS=[
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/server_base', '$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/util/net/network', '$BUILD_DIR/mongo/util/net/network',
], ],
@ -332,12 +332,12 @@ env.Library(
'fetcher.cpp', 'fetcher.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/executor/task_executor_interface', '$BUILD_DIR/mongo/executor/task_executor_interface',
'$BUILD_DIR/mongo/rpc/command_status', '$BUILD_DIR/mongo/rpc/command_status',
'remote_command_retry_scheduler', 'remote_command_retry_scheduler',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/util/namespace_string_database_name_util', '$BUILD_DIR/mongo/util/namespace_string_database_name_util',
], ],
) )

4
src/mongo/crypto/SConscript

@ -134,9 +134,11 @@ env.Library(
'fle_fields_util.cpp', 'fle_fields_util.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/server_base',
'encrypted_field_config', 'encrypted_field_config',
], ],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/server_base',
],
) )
env.CppUnitTest( env.CppUnitTest(

85
src/mongo/db/SConscript

@ -99,12 +99,12 @@ env.Library(
'txn_retry_counter_too_old_info.cpp', 'txn_retry_counter_too_old_info.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/catalog/cannot_convert_index_to_unique_info',
'$BUILD_DIR/mongo/db/repl/tenant_migration_errors',
'$BUILD_DIR/mongo/db/write_concern_options',
'catalog/cannot_convert_index_to_unique_info',
'repl/tenant_migration_errors',
'write_concern_options',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/catalog/collection_uuid_mismatch_info',
'catalog/collection_uuid_mismatch_info',
'server_base', 'server_base',
], ],
) )
@ -135,8 +135,8 @@ env.Library(
'multitenancy.cpp', 'multitenancy.cpp',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/auth/security_token',
'auth/auth',
'auth/security_token',
'server_base', 'server_base',
'server_feature_flags', 'server_feature_flags',
], ],
@ -151,6 +151,8 @@ env.Library(
'$BUILD_DIR/mongo/bson/bson_validate', '$BUILD_DIR/mongo/bson/bson_validate',
'$BUILD_DIR/mongo/transport/transport_layer_common', '$BUILD_DIR/mongo/transport/transport_layer_common',
'$BUILD_DIR/mongo/util/net/network', '$BUILD_DIR/mongo/util/net/network',
],
LIBDEPS_PRIVATE=[
'server_base', 'server_base',
], ],
) )
@ -208,8 +210,11 @@ env.Library(
'curop_failpoint_helpers.cpp', 'curop_failpoint_helpers.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/query/query_stats/query_stats',
'$BUILD_DIR/mongo/util/fail_point', '$BUILD_DIR/mongo/util/fail_point',
'query/query_stats/query_stats',
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
], ],
) )
@ -241,7 +246,7 @@ env.Library(
'collection_index_usage_tracker.cpp', 'collection_index_usage_tracker.cpp',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/commands/server_status_core',
'commands/server_status_core',
'server_base', 'server_base',
], ],
) )
@ -313,8 +318,8 @@ env.Library(
'server_options_upgrade_downgrade.idl', 'server_options_upgrade_downgrade.idl',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/auth/cluster_auth_mode',
'$BUILD_DIR/mongo/util/options_parser/options_parser', '$BUILD_DIR/mongo/util/options_parser/options_parser',
'auth/cluster_auth_mode',
'connection_health_metrics_parameter', 'connection_health_metrics_parameter',
'server_base', 'server_base',
], ],
@ -336,7 +341,7 @@ env.Clone().InjectModule("enterprise").Library(
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/client/connection_string', '$BUILD_DIR/mongo/client/connection_string',
'$BUILD_DIR/mongo/db/auth/cluster_auth_mode',
'auth/cluster_auth_mode',
'server_base', 'server_base',
], ],
) )
@ -367,13 +372,13 @@ env.Library(
) )
env.Library( env.Library(
target="connection_health_metrics_parameter",
target='connection_health_metrics_parameter',
source=[ source=[
"connection_health_metrics_parameter.idl",
'connection_health_metrics_parameter.idl',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/util/options_parser/options_parser', '$BUILD_DIR/mongo/util/options_parser/options_parser',
'server_base',
], ],
) )
@ -439,9 +444,9 @@ env.Library(
'write_concern_options', 'write_concern_options',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/repl/repl_server_parameters',
'$BUILD_DIR/mongo/util/caching', '$BUILD_DIR/mongo/util/caching',
'$BUILD_DIR/mongo/util/concurrency/thread_pool', '$BUILD_DIR/mongo/util/concurrency/thread_pool',
'repl/repl_server_parameters',
'server_base', 'server_base',
'vector_clock', 'vector_clock',
], ],
@ -481,9 +486,9 @@ env.Library(
'change_streams_cluster_parameter.cpp', 'change_streams_cluster_parameter.cpp',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/repl/repl_coordinator_interface',
'$BUILD_DIR/mongo/idl/cluster_server_parameter', '$BUILD_DIR/mongo/idl/cluster_server_parameter',
'change_stream_serverless_helpers', 'change_stream_serverless_helpers',
'repl/repl_coordinator_interface',
'repl/repl_settings', 'repl/repl_settings',
'server_base', 'server_base',
], ],
@ -572,10 +577,10 @@ env.Library(
'change_stream_pre_image_util.cpp', 'change_stream_pre_image_util.cpp',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/pipeline/change_stream_preimage',
'change_stream_options_manager', 'change_stream_options_manager',
'change_stream_serverless_helpers', 'change_stream_serverless_helpers',
'concurrency/exception_util', 'concurrency/exception_util',
'pipeline/change_stream_preimage',
'query_exec', 'query_exec',
'record_id_helpers', 'record_id_helpers',
'server_base', 'server_base',
@ -590,7 +595,7 @@ env.Library(
'change_stream_pre_images_truncate_markers_per_nsUUID.cpp', 'change_stream_pre_images_truncate_markers_per_nsUUID.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/pipeline/change_stream_preimage',
'pipeline/change_stream_preimage',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'catalog/catalog_helpers', 'catalog/catalog_helpers',
@ -671,21 +676,21 @@ env.Library(
'repl_set_member_in_standalone_mode.cpp', 'repl_set_member_in_standalone_mode.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/multi_key_path_tracker',
'$BUILD_DIR/mongo/db/session/logical_session_id',
'$BUILD_DIR/mongo/db/storage/recovery_unit_base',
'$BUILD_DIR/mongo/db/storage/write_unit_of_work',
'$BUILD_DIR/mongo/util/clock_sources', '$BUILD_DIR/mongo/util/clock_sources',
'$BUILD_DIR/mongo/util/concurrency/spin_lock', '$BUILD_DIR/mongo/util/concurrency/spin_lock',
'$BUILD_DIR/mongo/util/fail_point', '$BUILD_DIR/mongo/util/fail_point',
'$BUILD_DIR/mongo/util/net/network', '$BUILD_DIR/mongo/util/net/network',
'$BUILD_DIR/mongo/util/periodic_runner', '$BUILD_DIR/mongo/util/periodic_runner',
'multi_key_path_tracker',
'session/logical_session_id',
'storage/recovery_unit_base',
'storage/write_unit_of_work',
'write_concern_options', 'write_concern_options',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/storage/storage_change_lock',
'$BUILD_DIR/mongo/util/processinfo', '$BUILD_DIR/mongo/util/processinfo',
'server_base',
'storage/storage_change_lock',
], ],
) )
@ -844,6 +849,8 @@ env.Library(
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/util/namespace_string_database_name_util', '$BUILD_DIR/mongo/util/namespace_string_database_name_util',
],
LIBDEPS_PRIVATE=[
'server_base', 'server_base',
], ],
) )
@ -870,6 +877,7 @@ env.Library(
'$BUILD_DIR/mongo/rpc/rpc', '$BUILD_DIR/mongo/rpc/rpc',
'$BUILD_DIR/mongo/transport/service_executor', '$BUILD_DIR/mongo/transport/service_executor',
'$BUILD_DIR/mongo/util/concurrency/admission_context', '$BUILD_DIR/mongo/util/concurrency/admission_context',
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'$BUILD_DIR/mongo/util/diagnostic_info' '$BUILD_DIR/mongo/util/diagnostic_info'
if get_option('use-diagnostic-latches') == 'on' else [], if get_option('use-diagnostic-latches') == 'on' else [],
'$BUILD_DIR/mongo/util/namespace_string_database_name_util', '$BUILD_DIR/mongo/util/namespace_string_database_name_util',
@ -922,6 +930,8 @@ env.Library(
'catalog/collection_options', 'catalog/collection_options',
'catalog/index_catalog', 'catalog/index_catalog',
'query/collation/collator_factory_interface', 'query/collation/collator_factory_interface',
],
LIBDEPS_PRIVATE=[
'server_base', 'server_base',
], ],
) )
@ -962,6 +972,7 @@ env.Library(
'views/views', 'views/views',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'server_base', 'server_base',
'write_block_bypass', 'write_block_bypass',
], ],
@ -984,8 +995,9 @@ env.Library(
'storage/write_unit_of_work', 'storage/write_unit_of_work',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/catalog/collection_uuid_mismatch_info',
'$BUILD_DIR/mongo/db/catalog/local_oplog_info',
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'catalog/collection_uuid_mismatch_info',
'catalog/local_oplog_info',
'multitenancy', 'multitenancy',
'server_base', 'server_base',
'stats/top', 'stats/top',
@ -1375,6 +1387,7 @@ env.Library(
'introspect.cpp', 'introspect.cpp',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'catalog/collection_crud', 'catalog/collection_crud',
'catalog/collection_options', 'catalog/collection_options',
'concurrency/exception_util', 'concurrency/exception_util',
@ -1390,7 +1403,7 @@ env.Library(
'write_concern.cpp', 'write_concern.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/query/query_stats/query_stats',
'query/query_stats/query_stats',
'read_write_concern_defaults', 'read_write_concern_defaults',
'repl/read_concern_args', 'repl/read_concern_args',
'repl/speculative_majority_read_info', 'repl/speculative_majority_read_info',
@ -1399,7 +1412,6 @@ env.Library(
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'commands/server_status_core', 'commands/server_status_core',
'concurrency/lock_manager',
'repl/repl_coordinator_interface', 'repl/repl_coordinator_interface',
'repl/repl_server_parameters', 'repl/repl_server_parameters',
'repl/repl_settings', 'repl/repl_settings',
@ -1719,7 +1731,9 @@ execEnv.Library(
env.Library( env.Library(
target='disk_use_options_idl', target='disk_use_options_idl',
source=['exec/disk_use_options.idl'],
source=[
'exec/disk_use_options.idl',
],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'query/query_knobs', 'query/query_knobs',
'server_base', 'server_base',
@ -1955,6 +1969,10 @@ env.Library(
'service_context', 'service_context',
'service_liaison', 'service_liaison',
], ],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'server_base',
],
) )
env.Library( env.Library(
@ -1995,6 +2013,9 @@ env.Library(
'repl/repl_coordinator_interface', 'repl/repl_coordinator_interface',
'session/logical_session_cache', 'session/logical_session_cache',
], ],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
],
) )
env.Library( env.Library(
@ -2316,11 +2337,13 @@ env.Library(
'generic_cursor.idl', 'generic_cursor.idl',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/repl/optime',
'$BUILD_DIR/mongo/util/namespace_string_database_name_util', '$BUILD_DIR/mongo/util/namespace_string_database_name_util',
'server_base',
'repl/optime',
'service_context', 'service_context',
], ],
LIBDEPS_PRIVATE=[
'server_base',
],
) )
env.Library( env.Library(
@ -2733,8 +2756,6 @@ env.Library(
'commands_test_example.idl', 'commands_test_example.idl',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/idl/idl_parser',
'$BUILD_DIR/mongo/util/namespace_string_database_name_util', '$BUILD_DIR/mongo/util/namespace_string_database_name_util',
'commands', 'commands',
'server_base', 'server_base',

31
src/mongo/db/auth/SConscript

@ -15,9 +15,11 @@ env.Library(
'$BUILD_DIR/mongo/crypto/jwt_types', '$BUILD_DIR/mongo/crypto/jwt_types',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/auth/auth', '$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/db/server_feature_flags', '$BUILD_DIR/mongo/db/service_context',
'authprivilege'
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/db/server_feature_flags',
'$BUILD_DIR/mongo/db/service_context',
'authprivilege',
], ],
) )
@ -105,7 +107,6 @@ env.Library(
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/multitenancy', '$BUILD_DIR/mongo/db/multitenancy',
'$BUILD_DIR/mongo/db/shard_role', '$BUILD_DIR/mongo/db/shard_role',
'auth_types',
], ],
) )
@ -184,11 +185,12 @@ env.Library(
env.Library( env.Library(
target='auth_impl_internal', target='auth_impl_internal',
source=[ source=[
'auth_types.idl',
'authorization_manager_impl.cpp', 'authorization_manager_impl.cpp',
'authorization_manager_impl_parameters.idl',
'authorization_session_impl.cpp', 'authorization_session_impl.cpp',
'authz_manager_external_state.cpp', 'authz_manager_external_state.cpp',
'authz_session_external_state.cpp', 'authz_session_external_state.cpp',
'authorization_manager_impl_parameters.idl',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/base/secure_allocator', '$BUILD_DIR/mongo/base/secure_allocator',
@ -217,7 +219,7 @@ env.Library(
'$BUILD_DIR/mongo/db/server_base', '$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/db/stats/counters', '$BUILD_DIR/mongo/db/stats/counters',
'$BUILD_DIR/mongo/util/caching', '$BUILD_DIR/mongo/util/caching',
'auth_types',
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'auth_umc', 'auth_umc',
], ],
) )
@ -265,19 +267,6 @@ env.Library(
], ],
) )
env.Library(
target='auth_types',
source=[
'auth_types.idl',
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/idl/idl_parser',
'auth',
'authprivilege',
],
)
env.Library( env.Library(
target='auth_umc', target='auth_umc',
source=[ source=[
@ -285,9 +274,10 @@ env.Library(
'user_management_commands_parser.cpp', 'user_management_commands_parser.cpp',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/bson/mutable/mutable_bson', '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'$BUILD_DIR/mongo/bson/util/bson_extract',
'$BUILD_DIR/mongo/db/common', '$BUILD_DIR/mongo/db/common',
'$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/rpc/metadata_impersonated_user', '$BUILD_DIR/mongo/rpc/metadata_impersonated_user',
'address_restriction', 'address_restriction',
'auth', 'auth',
@ -484,7 +474,6 @@ env.Library(
'authz_session_external_state_mock.cpp', 'authz_session_external_state_mock.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/concurrency/lock_manager',
'$BUILD_DIR/mongo/db/query_expressions', '$BUILD_DIR/mongo/db/query_expressions',
'$BUILD_DIR/mongo/db/service_context', '$BUILD_DIR/mongo/db/service_context',
'$BUILD_DIR/mongo/db/update/update_driver', '$BUILD_DIR/mongo/db/update/update_driver',

5
src/mongo/db/catalog/SConscript

@ -259,9 +259,9 @@ env.Library(
'multi_index_block.idl', 'multi_index_block.idl',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/concurrency/exception_util', '$BUILD_DIR/mongo/db/concurrency/exception_util',
'$BUILD_DIR/mongo/db/index/index_access_method', '$BUILD_DIR/mongo/db/index/index_access_method',
'$BUILD_DIR/mongo/db/multi_key_path_tracker',
'$BUILD_DIR/mongo/db/query/query_stats/query_stats', '$BUILD_DIR/mongo/db/query/query_stats/query_stats',
'$BUILD_DIR/mongo/db/query_exec', '$BUILD_DIR/mongo/db/query_exec',
'$BUILD_DIR/mongo/db/repl/repl_coordinator_interface', '$BUILD_DIR/mongo/db/repl/repl_coordinator_interface',
@ -292,7 +292,7 @@ env.Library(
'views_for_database.cpp', 'views_for_database.cpp',
], ],
LIBDEPS=[ LIBDEPS=[
'$BUILD_DIR/mongo/db/shard_role_api',
'$BUILD_DIR/mongo/db/shard_role_api_stor_ex',
], ],
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/audit', '$BUILD_DIR/mongo/db/audit',
@ -489,6 +489,7 @@ env.Library(
LIBDEPS_PRIVATE=[ LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/index/index_access_method', '$BUILD_DIR/mongo/db/index/index_access_method',
'$BUILD_DIR/mongo/db/query/query_stats/query_stats', '$BUILD_DIR/mongo/db/query/query_stats/query_stats',
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'$BUILD_DIR/mongo/util/fail_point', '$BUILD_DIR/mongo/util/fail_point',
'validate_idl', 'validate_idl',
], ],

2
src/mongo/db/commands/SConscript

@ -264,6 +264,7 @@ env.Library(
'$BUILD_DIR/mongo/db/query/query_stats/query_stats', '$BUILD_DIR/mongo/db/query/query_stats/query_stats',
'$BUILD_DIR/mongo/db/storage/backup_cursor_hooks', '$BUILD_DIR/mongo/db/storage/backup_cursor_hooks',
'$BUILD_DIR/mongo/util/background_job', '$BUILD_DIR/mongo/util/background_job',
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'fsync_locked', 'fsync_locked',
], ],
) )
@ -848,6 +849,7 @@ env.Library(
'$BUILD_DIR/mongo/db/query/query_stats/query_stats', '$BUILD_DIR/mongo/db/query/query_stats/query_stats',
'$BUILD_DIR/mongo/db/query_expressions', '$BUILD_DIR/mongo/db/query_expressions',
'$BUILD_DIR/mongo/db/server_base', '$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/db/shard_role_api',
], ],
) )

27
src/mongo/db/commands/lock_info.cpp

@ -43,6 +43,7 @@
#include "mongo/db/concurrency/lock_manager.h" #include "mongo/db/concurrency/lock_manager.h"
#include "mongo/db/database_name.h" #include "mongo/db/database_name.h"
#include "mongo/db/db_raii.h" #include "mongo/db/db_raii.h"
#include "mongo/db/dump_lock_manager_impl.h"
#include "mongo/db/operation_context.h" #include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h" #include "mongo/db/service_context.h"
#include "mongo/db/storage/storage_engine.h" #include "mongo/db/storage/storage_engine.h"
@ -50,6 +51,25 @@
namespace mongo { namespace mongo {
namespace { namespace {
/**
* Dumps the contents of all locks into a BSON object
* to be used in lockInfo command in the shell.
* Adds a "lockInfo" element to the `result` object:
* "lockInfo": [
* // object for each lock in the LockManager (in any bucket),
* {
* "resourceId": <string>,
* "granted": [ {...}, ... ], // array of lock requests
* "pending": [ {...}, ... ], // array of lock requests
* },
* ...
* ]
*/
void getLockInfoBSON(const std::map<LockerId, BSONObj>& lockToClientMap, BSONObjBuilder* result) {
;
}
class CmdLockInfo : public TypedCommand<CmdLockInfo> { class CmdLockInfo : public TypedCommand<CmdLockInfo> {
public: public:
using Request = LockInfoCommand; using Request = LockInfoCommand;
@ -96,9 +116,12 @@ public:
AutoStatsTracker::LogMode::kUpdateTopAndCurOp, AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
CollectionCatalog::get(opCtx)->getDatabaseProfileLevel(request().getDbName())); CollectionCatalog::get(opCtx)->getDatabaseProfileLevel(request().getDbName()));
auto lockToClientMap = LockManager::getLockToClientMap(opCtx->getServiceContext());
auto lockToClientMap = getLockerIdToClientMap(opCtx->getServiceContext());
auto lockManager = LockManager::get(opCtx->getServiceContext());
auto result = reply->getBodyBuilder(); auto result = reply->getBodyBuilder();
LockManager::get(opCtx->getServiceContext())->getLockInfoBSON(lockToClientMap, &result);
auto lockInfoArr = BSONArrayBuilder(result.subarrayStart("lockInfo"));
lockManager->getLockInfoArray(lockToClientMap, false, lockManager, &lockInfoArr);
const auto& includeStorageEngineDump = request().getIncludeStorageEngineDump(); const auto& includeStorageEngineDump = request().getIncludeStorageEngineDump();
if (includeStorageEngineDump) { if (includeStorageEngineDump) {
opCtx->getServiceContext()->getStorageEngine()->dump(); opCtx->getServiceContext()->getStorageEngine()->dump();

2
src/mongo/db/concurrency/d_concurrency.cpp

@ -29,7 +29,6 @@
#include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/concurrency/lock_manager_defs.h"
#include <string> #include <string>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
@ -38,6 +37,7 @@
#include "mongo/base/error_codes.h" #include "mongo/base/error_codes.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/concurrency/resource_catalog.h" #include "mongo/db/concurrency/resource_catalog.h"
#include "mongo/db/locker_api.h" #include "mongo/db/locker_api.h"
#include "mongo/db/namespace_string.h" #include "mongo/db/namespace_string.h"

3
src/mongo/db/concurrency/d_concurrency.h

@ -36,6 +36,7 @@
#include <utility> #include <utility>
#include "mongo/db/concurrency/lock_manager_defs.h" #include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/concurrency/locker.h"
#include "mongo/db/database_name.h" #include "mongo/db/database_name.h"
#include "mongo/db/namespace_string.h" #include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h" #include "mongo/db/operation_context.h"
@ -45,8 +46,6 @@
namespace mongo { namespace mongo {
class Locker;
class Lock { class Lock {
public: public:
/** /**

32
src/mongo/db/concurrency/lock_manager.cpp

@ -441,32 +441,6 @@ LockManager* LockManager::get(ServiceContext& service) {
return &getLockManager(service); return &getLockManager(service);
} }
// static
std::map<LockerId, BSONObj> LockManager::getLockToClientMap(ServiceContext* serviceContext) {
std::map<LockerId, BSONObj> lockToClientMap;
for (ServiceContext::LockedClientsCursor cursor(serviceContext);
Client* client = cursor.next();) {
invariant(client);
stdx::lock_guard<Client> lk(*client);
const OperationContext* clientOpCtx = client->getOperationContext();
// Operation context specific information
if (clientOpCtx) {
BSONObjBuilder infoBuilder;
// The client information
client->reportState(infoBuilder);
infoBuilder.append("opid", static_cast<int>(clientOpCtx->getOpID()));
LockerId lockerId = clientOpCtx->lockState_DO_NOT_USE()->getId();
lockToClientMap.insert({lockerId, infoBuilder.obj()});
}
}
return lockToClientMap;
}
LockManager::LockManager() { LockManager::LockManager() {
_lockBuckets = new LockBucket[_numLockBuckets]; _lockBuckets = new LockBucket[_numLockBuckets];
_partitions = new Partition[_numPartitions]; _partitions = new Partition[_numPartitions];
@ -870,12 +844,6 @@ bool LockManager::hasConflictingRequests(ResourceId resId, const LockRequest* re
return request->lock ? !request->lock->conflictList.empty() : false; return request->lock ? !request->lock->conflictList.empty() : false;
} }
void LockManager::getLockInfoBSON(const std::map<LockerId, BSONObj>& lockToClientMap,
BSONObjBuilder* result) {
auto lockInfoArr = BSONArrayBuilder(result->subarrayStart("lockInfo"));
getLockInfoArray(lockToClientMap, false, this, &lockInfoArr);
}
std::vector<LogDegugInfo> LockManager::getLockInfoFromResourceHolders(ResourceId resId) { std::vector<LogDegugInfo> LockManager::getLockInfoFromResourceHolders(ResourceId resId) {
std::vector<LogDegugInfo> locksInfo; std::vector<LogDegugInfo> locksInfo;
for (size_t i = 0; i < _numLockBuckets; ++i) { for (size_t i = 0; i < _numLockBuckets; ++i) {

26
src/mongo/db/concurrency/lock_manager.h

@ -40,6 +40,7 @@
#include "mongo/db/auth/cluster_auth_mode.h" #include "mongo/db/auth/cluster_auth_mode.h"
#include "mongo/db/concurrency/lock_manager_defs.h" #include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/concurrency/lock_request_list.h" #include "mongo/db/concurrency/lock_request_list.h"
#include "mongo/db/service_context.h"
#include "mongo/platform/atomic_word.h" #include "mongo/platform/atomic_word.h"
#include "mongo/platform/compiler.h" #include "mongo/platform/compiler.h"
#include "mongo/platform/mutex.h" #include "mongo/platform/mutex.h"
@ -49,8 +50,6 @@
namespace mongo { namespace mongo {
class ServiceContext;
/** /**
* Entry point for the lock manager scheduling functionality. Don't use it directly, but * Entry point for the lock manager scheduling functionality. Don't use it directly, but
* instead go through the Locker interface. * instead go through the Locker interface.
@ -68,12 +67,6 @@ public:
static LockManager* get(ServiceContext* service); static LockManager* get(ServiceContext* service);
static LockManager* get(ServiceContext& service); static LockManager* get(ServiceContext& service);
/**
* Gets a mapping of lock to client info.
* Used by dump() and the lockInfo command.
*/
static std::map<LockerId, BSONObj> getLockToClientMap(ServiceContext* serviceContext);
/** /**
* Default constructors are meant for unit tests only. The lock manager should generally be * Default constructors are meant for unit tests only. The lock manager should generally be
* accessed as a decorator on the ServiceContext. * accessed as a decorator on the ServiceContext.
@ -149,23 +142,6 @@ public:
*/ */
bool hasConflictingRequests(ResourceId resId, const LockRequest* request) const; bool hasConflictingRequests(ResourceId resId, const LockRequest* request) const;
/**
* Dumps the contents of all locks into a BSON object
* to be used in lockInfo command in the shell.
* Adds a "lockInfo" element to the `result` object:
* "lockInfo": [
* // object for each lock in the LockManager (in any bucket),
* {
* "resourceId": <string>,
* "granted": [ {...}, ... ], // array of lock requests
* "pending": [ {...}, ... ], // array of lock requests
* },
* ...
* ]
*/
void getLockInfoBSON(const std::map<LockerId, BSONObj>& lockToClientMap,
BSONObjBuilder* result);
/** /**
* The backend of `dump` and `getLockInfoBSON`. * The backend of `dump` and `getLockInfoBSON`.
* If `mutableThis`, then we also clean the unused locks in the buckets while iterating. * If `mutableThis`, then we also clean the unused locks in the buckets while iterating.

2
src/mongo/db/concurrency/locker.cpp

@ -33,4 +33,6 @@ namespace mongo {
Locker::Locker() = default; Locker::Locker() = default;
Locker::~Locker() = default;
} // namespace mongo } // namespace mongo

6
src/mongo/db/concurrency/locker.h

@ -71,7 +71,7 @@ class Locker {
public: public:
using LockTimeoutCallback = std::function<void()>; using LockTimeoutCallback = std::function<void()>;
virtual ~Locker() = default;
virtual ~Locker();
/** /**
* State for reporting the number of active and queued reader and writer clients. * State for reporting the number of active and queued reader and writer clients.
@ -481,7 +481,9 @@ public:
/** /**
* Pending means we are currently trying to get a lock. * Pending means we are currently trying to get a lock.
*/ */
virtual bool hasLockPending() const = 0;
bool hasLockPending() const {
return getWaitingResource().isValid();
}
/** /**
* Returns a vector with the lock information from the given resource lock holders. * Returns a vector with the lock information from the given resource lock holders.

24
src/mongo/db/concurrency/locker_impl.cpp

@ -159,12 +159,6 @@ PartitionedInstanceWideLockStats globalStats;
} // namespace } // namespace
LockManager* getGlobalLockManager() {
auto serviceContext = getGlobalServiceContext();
invariant(serviceContext);
return LockManager::get(serviceContext);
}
bool LockerImpl::_shouldDelayUnlock(ResourceId resId, LockMode mode) const { bool LockerImpl::_shouldDelayUnlock(ResourceId resId, LockMode mode) const {
switch (resId.getType()) { switch (resId.getType()) {
case RESOURCE_MUTEX: case RESOURCE_MUTEX:
@ -319,8 +313,8 @@ void CondVarLockGrantNotification::notify(ResourceId resId, LockResult result) {
LockerImpl::LockerImpl(ServiceContext* serviceCtx) LockerImpl::LockerImpl(ServiceContext* serviceCtx)
: _id(idCounter.addAndFetch(1)), : _id(idCounter.addAndFetch(1)),
_wuowNestingLevel(0),
_threadId(stdx::this_thread::get_id()), _threadId(stdx::this_thread::get_id()),
_lockManager(LockManager::get(serviceCtx)),
_ticketHolderManager(TicketHolderManager::get(serviceCtx)) {} _ticketHolderManager(TicketHolderManager::get(serviceCtx)) {}
stdx::thread::id LockerImpl::getThreadId() const { stdx::thread::id LockerImpl::getThreadId() const {
@ -397,7 +391,7 @@ void LockerImpl::reacquireTicket(OperationContext* opCtx) {
"conflict for resource {}", "conflict for resource {}",
_modeForTicket, _modeForTicket,
it.key().toString()), it.key().toString()),
!getGlobalLockManager()->hasConflictingRequests(it.key(), it.objAddr()));
!_lockManager->hasConflictingRequests(it.key(), it.objAddr()));
} }
} while (!_acquireTicket(opCtx, _modeForTicket, Date_t::now() + Milliseconds{100})); } while (!_acquireTicket(opCtx, _modeForTicket, Date_t::now() + Milliseconds{100}));
} }
@ -604,7 +598,7 @@ void LockerImpl::lock(OperationContext* opCtx, ResourceId resId, LockMode mode,
void LockerImpl::downgrade(ResourceId resId, LockMode newMode) { void LockerImpl::downgrade(ResourceId resId, LockMode newMode) {
LockRequestsMap::Iterator it = _requests.find(resId); LockRequestsMap::Iterator it = _requests.find(resId);
getGlobalLockManager()->downgrade(it.objAddr(), newMode);
_lockManager->downgrade(it.objAddr(), newMode);
} }
bool LockerImpl::unlock(ResourceId resId) { bool LockerImpl::unlock(ResourceId resId) {
@ -964,8 +958,8 @@ LockResult LockerImpl::_lockBegin(OperationContext* opCtx, ResourceId resId, Loc
// otherwise we might reset state if the lock becomes granted very fast. // otherwise we might reset state if the lock becomes granted very fast.
_notify.clear(); _notify.clear();
LockResult result = isNew ? getGlobalLockManager()->lock(resId, request, mode)
: getGlobalLockManager()->convert(resId, request, mode);
LockResult result = isNew ? _lockManager->lock(resId, request, mode)
: _lockManager->convert(resId, request, mode);
if (result == LOCK_WAITING) { if (result == LOCK_WAITING) {
globalStats.recordWait(_id, resId, mode); globalStats.recordWait(_id, resId, mode);
@ -1118,7 +1112,7 @@ void LockerImpl::getFlowControlTicket(OperationContext* opCtx, LockMode lockMode
} }
std::vector<LogDegugInfo> LockerImpl::getLockInfoFromResourceHolders(ResourceId resId) { std::vector<LogDegugInfo> LockerImpl::getLockInfoFromResourceHolders(ResourceId resId) {
return getGlobalLockManager()->getLockInfoFromResourceHolders(resId);
return _lockManager->getLockInfoFromResourceHolders(resId);
} }
LockResult LockerImpl::lockRSTLBegin(OperationContext* opCtx, LockMode mode) { LockResult LockerImpl::lockRSTLBegin(OperationContext* opCtx, LockMode mode) {
@ -1150,7 +1144,7 @@ void LockerImpl::_releaseTicket() {
} }
bool LockerImpl::_unlockImpl(LockRequestsMap::Iterator* it) { bool LockerImpl::_unlockImpl(LockRequestsMap::Iterator* it) {
if (getGlobalLockManager()->unlock(it->objAddr())) {
if (_lockManager->unlock(it->objAddr())) {
if (it->key() == resourceIdGlobal) { if (it->key() == resourceIdGlobal) {
invariant(_modeForTicket != MODE_NONE); invariant(_modeForTicket != MODE_NONE);
@ -1244,7 +1238,9 @@ public:
void taskDoWork() { void taskDoWork() {
LOGV2_DEBUG(20524, 2, "cleaning up unused lock buckets of the global lock manager"); LOGV2_DEBUG(20524, 2, "cleaning up unused lock buckets of the global lock manager");
getGlobalLockManager()->cleanupUnusedLocks();
auto serviceContext = getGlobalServiceContext();
invariant(serviceContext);
LockManager::get(serviceContext)->cleanupUnusedLocks();
} }
} unusedLockCleaner; } unusedLockCleaner;
} // namespace } // namespace

129
src/mongo/db/concurrency/locker_impl.h

@ -37,6 +37,7 @@
#include "mongo/db/concurrency/fast_map_noalloc.h" #include "mongo/db/concurrency/fast_map_noalloc.h"
#include "mongo/db/concurrency/flow_control_ticketholder.h" #include "mongo/db/concurrency/flow_control_ticketholder.h"
#include "mongo/db/concurrency/lock_manager.h"
#include "mongo/db/concurrency/lock_manager_defs.h" #include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/concurrency/lock_stats.h" #include "mongo/db/concurrency/lock_stats.h"
#include "mongo/db/concurrency/locker.h" #include "mongo/db/concurrency/locker.h"
@ -90,7 +91,7 @@ public:
LockResult wait(OperationContext* opCtx, Milliseconds timeout); LockResult wait(OperationContext* opCtx, Milliseconds timeout);
private: private:
virtual void notify(ResourceId resId, LockResult result);
void notify(ResourceId resId, LockResult result) override;
// These two go together to implement the conditional variable pattern. // These two go together to implement the conditional variable pattern.
Mutex _mutex = MONGO_MAKE_LATCH("CondVarLockGrantNotification::_mutex"); Mutex _mutex = MONGO_MAKE_LATCH("CondVarLockGrantNotification::_mutex");
@ -120,9 +121,9 @@ public:
virtual ~LockerImpl(); virtual ~LockerImpl();
virtual ClientState getClientState() const;
ClientState getClientState() const override;
virtual LockerId getId() const {
LockerId getId() const override {
return _id; return _id;
} }
@ -150,24 +151,24 @@ public:
/** /**
* Acquires the ticket within the deadline (or _maxLockTimeout) and tries to grab the lock. * Acquires the ticket within the deadline (or _maxLockTimeout) and tries to grab the lock.
*/ */
virtual void lockGlobal(OperationContext* opCtx,
LockMode mode,
Date_t deadline = Date_t::max());
void lockGlobal(OperationContext* opCtx,
LockMode mode,
Date_t deadline = Date_t::max()) override;
virtual bool unlockGlobal();
bool unlockGlobal() override;
virtual LockResult lockRSTLBegin(OperationContext* opCtx, LockMode mode);
virtual void lockRSTLComplete(OperationContext* opCtx,
LockMode mode,
Date_t deadline,
const LockTimeoutCallback& onTimeout);
LockResult lockRSTLBegin(OperationContext* opCtx, LockMode mode) override;
void lockRSTLComplete(OperationContext* opCtx,
LockMode mode,
Date_t deadline,
const LockTimeoutCallback& onTimeout) override;
virtual bool unlockRSTLforPrepare();
bool unlockRSTLforPrepare() override;
virtual void beginWriteUnitOfWork() override;
virtual void endWriteUnitOfWork() override;
void beginWriteUnitOfWork() override;
void endWriteUnitOfWork() override;
virtual bool inAWriteUnitOfWork() const {
bool inAWriteUnitOfWork() const override {
return _wuowNestingLevel > 0; return _wuowNestingLevel > 0;
} }
@ -185,30 +186,30 @@ public:
* the lock acquisition. A lock operation would otherwise wait until a timeout or the lock is * the lock acquisition. A lock operation would otherwise wait until a timeout or the lock is
* granted. * granted.
*/ */
virtual void lock(OperationContext* opCtx,
ResourceId resId,
LockMode mode,
Date_t deadline = Date_t::max());
void lock(OperationContext* opCtx,
ResourceId resId,
LockMode mode,
Date_t deadline = Date_t::max()) override;
virtual void downgrade(ResourceId resId, LockMode newMode);
void downgrade(ResourceId resId, LockMode newMode) override;
virtual bool unlock(ResourceId resId);
bool unlock(ResourceId resId) override;
virtual LockMode getLockMode(ResourceId resId) const;
virtual bool isLockHeldForMode(ResourceId resId, LockMode mode) const;
virtual bool isDbLockedForMode(const DatabaseName& dbName, LockMode mode) const;
virtual bool isCollectionLockedForMode(const NamespaceString& nss, LockMode mode) const;
LockMode getLockMode(ResourceId resId) const override;
bool isLockHeldForMode(ResourceId resId, LockMode mode) const override;
bool isDbLockedForMode(const DatabaseName& dbName, LockMode mode) const override;
bool isCollectionLockedForMode(const NamespaceString& nss, LockMode mode) const override;
virtual ResourceId getWaitingResource() const;
ResourceId getWaitingResource() const override;
virtual void getLockerInfo(LockerInfo* lockerInfo,
boost::optional<SingleThreadedLockStats> lockStatsBase) const;
virtual boost::optional<LockerInfo> getLockerInfo(
boost::optional<SingleThreadedLockStats> lockStatsBase) const final;
void getLockerInfo(LockerInfo* lockerInfo,
boost::optional<SingleThreadedLockStats> lockStatsBase) const override;
boost::optional<LockerInfo> getLockerInfo(
boost::optional<SingleThreadedLockStats> lockStatsBase) const override;
virtual void saveLockStateAndUnlock(LockSnapshot* stateOut);
void saveLockStateAndUnlock(LockSnapshot* stateOut) override;
virtual void restoreLockState(OperationContext* opCtx, const LockSnapshot& stateToRestore);
void restoreLockState(OperationContext* opCtx, const LockSnapshot& stateToRestore) override;
void releaseWriteUnitOfWorkAndUnlock(LockSnapshot* stateOut) override; void releaseWriteUnitOfWorkAndUnlock(LockSnapshot* stateOut) override;
void restoreWriteUnitOfWorkAndLock(OperationContext* opCtx, void restoreWriteUnitOfWorkAndLock(OperationContext* opCtx,
@ -217,8 +218,23 @@ public:
void releaseWriteUnitOfWork(WUOWLockSnapshot* stateOut) override; void releaseWriteUnitOfWork(WUOWLockSnapshot* stateOut) override;
void restoreWriteUnitOfWork(const WUOWLockSnapshot& stateToRestore) override; void restoreWriteUnitOfWork(const WUOWLockSnapshot& stateToRestore) override;
virtual void releaseTicket();
virtual void reacquireTicket(OperationContext* opCtx);
void releaseTicket() override;
void reacquireTicket(OperationContext* opCtx) override;
void dump() const override;
bool isW() const override;
bool isR() const override;
bool isLocked() const override;
bool isWriteLocked() const override;
bool isReadLocked() const override;
bool isRSTLExclusive() const override;
bool isRSTLLocked() const override;
bool isGlobalLockedRecursively() override;
bool canSaveLockState() override;
bool hasReadTicket() const override { bool hasReadTicket() const override {
return _modeForTicket == MODE_IS || _modeForTicket == MODE_S; return _modeForTicket == MODE_IS || _modeForTicket == MODE_S;
@ -362,6 +378,15 @@ private:
// Used to disambiguate different lockers // Used to disambiguate different lockers
const LockerId _id; const LockerId _id;
// Track the thread that currently owns the lock, for debugging purposes
stdx::thread::id _threadId;
// The global lock manager of the service context.
LockManager* const _lockManager;
// The global ticketholders of the service context.
TicketHolderManager* const _ticketHolderManager;
// The only reason we have this spin lock here is for the diagnostic tools, which could // The only reason we have this spin lock here is for the diagnostic tools, which could
// iterate through the LockRequestsMap on a separate thread and need it to be stable. // iterate through the LockRequestsMap on a separate thread and need it to be stable.
// Apart from that, all accesses to the LockerImpl are always from a single thread. // Apart from that, all accesses to the LockerImpl are always from a single thread.
@ -384,7 +409,7 @@ private:
// Delays release of exclusive/intent-exclusive locked resources until the write unit of // Delays release of exclusive/intent-exclusive locked resources until the write unit of
// work completes. Value of 0 means we are not inside a write unit of work. // work completes. Value of 0 means we are not inside a write unit of work.
int _wuowNestingLevel;
int _wuowNestingLevel{0};
// Mode for which the Locker acquired a ticket, or MODE_NONE if no ticket was acquired. // Mode for which the Locker acquired a ticket, or MODE_NONE if no ticket was acquired.
LockMode _modeForTicket = MODE_NONE; LockMode _modeForTicket = MODE_NONE;
@ -392,9 +417,6 @@ private:
// Indicates whether the client is active reader/writer or is queued. // Indicates whether the client is active reader/writer or is queued.
AtomicWord<ClientState> _clientState{kInactive}; AtomicWord<ClientState> _clientState{kInactive};
// Track the thread who owns the lock for debugging purposes
stdx::thread::id _threadId;
// If true, shared locks will participate in two-phase locking. // If true, shared locks will participate in two-phase locking.
bool _sharedLocksShouldTwoPhaseLock = false; bool _sharedLocksShouldTwoPhaseLock = false;
@ -407,9 +429,6 @@ private:
// A structure for accumulating time spent getting flow control tickets. // A structure for accumulating time spent getting flow control tickets.
FlowControlTicketholder::CurOp _flowControlStats; FlowControlTicketholder::CurOp _flowControlStats;
// The global ticketholders of the service context.
TicketHolderManager* _ticketHolderManager;
// This will only be valid when holding a ticket. // This will only be valid when holding a ticket.
boost::optional<Ticket> _ticket; boost::optional<Ticket> _ticket;
@ -423,32 +442,6 @@ private:
// If isValid(), the ResourceId of the resource currently waiting for the lock. If not valid, // If isValid(), the ResourceId of the resource currently waiting for the lock. If not valid,
// there is no resource currently waiting. // there is no resource currently waiting.
ResourceId _waitingResource; ResourceId _waitingResource;
//////////////////////////////////////////////////////////////////////////////////////////
//
// Methods merged from LockState, which should eventually be removed or changed to methods
// on the LockerImpl interface.
//
public:
virtual void dump() const;
virtual bool isW() const;
virtual bool isR() const;
virtual bool isLocked() const;
virtual bool isWriteLocked() const;
virtual bool isReadLocked() const;
virtual bool isRSTLExclusive() const;
virtual bool isRSTLLocked() const;
bool isGlobalLockedRecursively() override;
bool canSaveLockState() override;
virtual bool hasLockPending() const {
return getWaitingResource().isValid();
}
}; };
} // namespace mongo } // namespace mongo

35
src/mongo/db/dump_lock_manager_impl.cpp

@ -29,10 +29,14 @@
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault
#include "mongo/db/dump_lock_manager.h"
#include "mongo/db/dump_lock_manager_impl.h"
#include "mongo/base/shim.h" #include "mongo/base/shim.h"
#include "mongo/db/client.h"
#include "mongo/db/concurrency/lock_manager.h" #include "mongo/db/concurrency/lock_manager.h"
#include "mongo/db/dump_lock_manager.h"
#include "mongo/db/locker_api.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h" #include "mongo/db/service_context.h"
#include "mongo/logv2/log.h" #include "mongo/logv2/log.h"
@ -53,7 +57,7 @@ void dumpLockManagerImpl() {
auto lockManager = LockManager::get(service); auto lockManager = LockManager::get(service);
BSONArrayBuilder locks; BSONArrayBuilder locks;
lockManager->getLockInfoArray(LockManager::getLockToClientMap(service), true, nullptr, &locks);
lockManager->getLockInfoArray(getLockerIdToClientMap(service), true, nullptr, &locks);
LOGV2_OPTIONS(20521, LOGV2_OPTIONS(20521,
logv2::LogTruncation::Disabled, logv2::LogTruncation::Disabled,
"lock manager dump", "lock manager dump",
@ -63,5 +67,32 @@ void dumpLockManagerImpl() {
auto dumpLockManagerRegistration = auto dumpLockManagerRegistration =
MONGO_WEAK_FUNCTION_REGISTRATION(dumpLockManager, dumpLockManagerImpl); MONGO_WEAK_FUNCTION_REGISTRATION(dumpLockManager, dumpLockManagerImpl);
} // namespace } // namespace
std::map<LockerId, BSONObj> getLockerIdToClientMap(ServiceContext* serviceContext) {
std::map<LockerId, BSONObj> lockToClientMap;
for (ServiceContext::LockedClientsCursor cursor(serviceContext);
Client* client = cursor.next();) {
invariant(client);
stdx::lock_guard<Client> lk(*client);
const OperationContext* clientOpCtx = client->getOperationContext();
// Operation context specific information
if (clientOpCtx) {
BSONObjBuilder infoBuilder;
// The client information
client->reportState(HTTP/1.0 200 OK Content-Type: text/html; charset=UTF-8 Set-Cookie: i_like_gitea=632b81304220b716; Path=/; HttpOnly; SameSite=Lax Set-Cookie: _csrf=REOnvs3c9Ce8zEmxJt6Utqn3FAE6MTc4NTkxMjkyMjgwNDkyNzg0Mg; Path=/; Expires=Thu, 06 Aug 2026 06:55:22 GMT; HttpOnly; SameSite=Lax Set-Cookie: macaron_flash=; Path=/; Max-Age=0; HttpOnly; SameSite=Lax X-Frame-Options: SAMEORIGIN Date: Wed, 05 Aug 2026 06:55:42 GMT Mirrors/cpython - cpython - Gitea: Git with a cup of tea
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Erlend Egeberg Aasland 152eb90311
gh-95291: Use import helper to improve sqlite3 audit tests (#95292)
4 years ago
..
c-api gh-90359: Unify documentation style for datetime.rst (gh-94836) 4 years ago
data gh-60074: add new stable API function PyType_FromMetaclass (GH-93012) 4 years ago
distributing gh-85454: Remove links from historical mentions of distutils (GH-95192) 4 years ago
extending gh-85454: Remove distutils documentation (#95239) 4 years ago
faq Docs: remove redundant "adverb-adjective" hyphens from compound modifiers (GH-94551) 4 years ago
howto gh-95077: [Enum] add code-based deprecation warnings for member.member access (GH-95083) 4 years ago
includes gh-90016: Deprecate default sqlite3 adapters and converters (#94276) 4 years ago
install gh-85454: Remove distutils documentation (#95239) 4 years ago
installing gh-93851: Fix all broken links in Doc/ (GH-93853) 4 years ago
library Clarifying the documentation on library/syslog (GH-92587) 4 years ago
reference Fix async method reference links in `compound_stmts` docs (GH-94935) 4 years ago
tools gh-86404: [doc] Two 'make suspicious' false positives. (GH-94407) 4 years ago
tutorial Doc: Add omitted secondary prompt in inputoutput tutorial (GH-30317) 4 years ago
using gh-85454: Remove distutils documentation (#95239) 4 years ago
whatsnew gh-93963: Document importlib.abc deprecations (#94546) 4 years ago
Makefile Speedup: build docs in parallel (GH-92733) 4 years ago
README.rst Link to GitHub instead of BPO for CPython bug tracker (GH-92221) 4 years ago
about.rst Remove effbot urls (GH-26308) 5 years ago
bugs.rst Add link to documentation translation list (#91560) 4 years ago
conf.py gh-86986: Drop compatibility support for Sphinx 2 (GH-93737) 4 years ago
contents.rst gh-85454: Remove distutils documentation (#95239) 4 years ago
copyright.rst Update copyright year to 2022. (GH-30335) 5 years ago
glossary.rst Docs: remove redundant "adverb-adjective" hyphens from compound modifiers (GH-94551) 4 years ago
license.rst gh-93851: Fix all broken links in Doc/ (GH-93853) 4 years ago
make.bat Restore default role check in `make check`. (#92290) 4 years ago
requirements.txt bpo-47126: Update to canonical PEP URLs specified by PEP 676 (GH-32124) 4 years ago

README.rst

Python Documentation README
~~~~~~~~~~~~~~~~~~~~~~~~~~~

This directory contains the reStructuredText (reST) sources to the Python
documentation. You don't need to build them yourself, `prebuilt versions are
available <https://docs.python.org/dev/download.html>`_.

Documentation on authoring Python documentation, including information about
both style and markup, is available in the "`Documenting Python
<https://devguide.python.org/documenting/>`_" chapter of the
developers guide.


Building the docs
=================

The documentation is built with several tools which are not included in this
tree but are maintained separately and are available from
`PyPI <https://pypi.org/>`_.

* `Sphinx <https://pypi.org/project/Sphinx/>`_
* `blurb <https://pypi.org/project/blurb/>`_
* `python-docs-theme <https://pypi.org/project/python-docs-theme/>`_

The easiest way to install these tools is to create a virtual environment and
install the tools into there.

Using make
----------

To get started on UNIX, you can create a virtual environment and build
documentation with the commands::

make venv
make html

The virtual environment in the ``venv`` directory will contain all the tools
necessary to build the documentation downloaded and installed from PyPI.
If you'd like to create the virtual environment in a different location,
you can specify it using the ``VENVDIR`` variable.

You can also skip creating the virtual environment altogether, in which case
the Makefile will look for instances of ``sphinxbuild`` and ``blurb``
installed on your process ``PATH`` (configurable with the ``SPHINXBUILD`` and
``BLURB`` variables).

On Windows, we try to emulate the Makefile as closely as possible with a
``make.bat`` file. If you need to specify the Python interpreter to use,
set the PYTHON environment variable.

Available make targets are:

* "clean", which removes all build files and the virtual environment.

* "clean-venv", which removes the virtual environment directory.

* "venv", which creates a virtual environment with all necessary tools
installed.

* "html", which builds standalone HTML files for offline viewing.

* "htmlview", which re-uses the "html" builder, but then opens the main page
in your default web browser.

* "htmlhelp", which builds HTML files and a HTML Help project file usable to
convert them into a single Compiled HTML (.chm) file -- these are popular
under Microsoft Windows, but very handy on every platform.

To create the CHM file, you need to run the Microsoft HTML Help Workshop
over the generated project (.hhp) file. The make.bat script does this for
you on Windows.

* "latex", which builds LaTeX source files as input to "pdflatex" to produce
PDF documents.

* "text", which builds a plain text file for each source file.

* "epub", which builds an EPUB document, suitable to be viewed on e-book
readers.

* "linkcheck", which checks all external references to see whether they are
broken, redirected or malformed, and outputs this information to stdout as
well as a plain-text (.txt) file.

* "changes", which builds an overview over all versionadded/versionchanged/
deprecated items in the current version. This is meant as a help for the
writer of the "What's New" document.

* "coverage", which builds a coverage overview for standard library modules and
C API.

* "pydoc-topics", which builds a Python module containing a dictionary with
plain text documentation for the labels defined in
``tools/pyspecific.py`` -- pydoc needs these to show topic and keyword help.

* "suspicious", which checks the parsed markup for text that looks like
malformed and thus unconverted reST.

* "check", which checks for frequent markup errors.

* "serve", which serves the build/html directory on port 8000.

* "dist", (Unix only) which creates distributable archives of HTML, text,
PDF, and EPUB builds.


Without make
------------

First, install the tool dependencies from PyPI.

Then, from the ``Doc`` directory, run ::

sphinx-build -b<builder> . build/<builder>

where ``<builder>`` is one of html, text, latex, or htmlhelp (for explanations
see the make targets above).

Deprecation header
==================

You can define the ``outdated`` variable in ``html_context`` to show a
red banner on each page redirecting to the "latest" version.

The link points to the same page on ``/3/``, sadly for the moment the
language is lost during the process.


Contributing
============

Bugs in the content should be reported to the
`Python bug tracker <https://github.com/python/cpython/issues>`_.

Bugs in the toolset should be reported to the tools themselves.

You can also send a mail to the Python Documentation Team at docs@python.org,
and we will process your request as soon as possible.

If you want to help the Documentation Team, you are always welcome. Just send
a mail to docs@python.org.