diff --git a/thread_notifications_lackey_dll/CMakeLists.txt b/thread_notifications_lackey_dll/CMakeLists.txt index 6bf824f1..8ac60819 100644 --- a/thread_notifications_lackey_dll/CMakeLists.txt +++ b/thread_notifications_lackey_dll/CMakeLists.txt @@ -15,7 +15,7 @@ set(thread_notifications_lackey_dll_def_files add_library(thread_notifications_lackey_dll SHARED ${thread_notifications_lackey_dll_c_files} ${thread_notifications_lackey_dll_h_files} ${thread_notifications_lackey_dll_def_files}) target_include_directories(thread_notifications_lackey_dll PUBLIC $) -target_link_libraries(thread_notifications_lackey_dll c_logging_v2 c_pal) +target_link_libraries(thread_notifications_lackey_dll c_pal) function(copy_thread_notifications_lackey_outputs target output_directory) add_custom_command(TARGET ${target} POST_BUILD diff --git a/thread_notifications_lackey_dll/devdoc/thread_notifications_lackey_dll_requirements.md b/thread_notifications_lackey_dll/devdoc/thread_notifications_lackey_dll_requirements.md index 8c069e02..9461aeec 100644 --- a/thread_notifications_lackey_dll/devdoc/thread_notifications_lackey_dll_requirements.md +++ b/thread_notifications_lackey_dll/devdoc/thread_notifications_lackey_dll_requirements.md @@ -65,17 +65,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); `DllMain` implements the DLL main entry point. -**SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [** If `fdwReason` is `DLL_PROCESS_ATTACH`: **]** - -- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_006: [** `DllMain` shall call `logger_init` to initialize logging for the module. **]** +`DllMain` runs under the loader lock and, at process exit, other DLLs may have already been detached. For this reason it does not initialize or clean up anything (including logging) for process attach/detach. -- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_008: [** If `logger_init` fails, `DllMain` shall return FALSE. **]** +**SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [** If `fdwReason` is `DLL_PROCESS_ATTACH`: **]** -- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [** Otherwise, `DllMain` shall initialize the callback maintained by the module with `NULL` and return `TRUE`. **]** +- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [** `DllMain` shall return `TRUE`. **]** **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [** If `fdwReason` is `DLL_PROCESS_DETACH`: **]** -- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [** `DllMain` shall call `logger_deinit` and return `TRUE`. **]** +- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [** `DllMain` shall return `TRUE`. **]** **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_011: [** If `fdwReason` is `DLL_THREAD_ATTACH`: **]** diff --git a/thread_notifications_lackey_dll/src/thread_notifications_lackey_dll.c b/thread_notifications_lackey_dll/src/thread_notifications_lackey_dll.c index 70b85cf2..ce83d170 100644 --- a/thread_notifications_lackey_dll/src/thread_notifications_lackey_dll.c +++ b/thread_notifications_lackey_dll/src/thread_notifications_lackey_dll.c @@ -5,8 +5,6 @@ #include "macro_utils/macro_utils.h" -#include "c_logging/logger.h" - #include "c_pal/interlocked.h" #include "c_pal/ps_util.h" @@ -23,7 +21,6 @@ int thread_notifications_lackey_dll_init_callback(THREAD_NOTIFICATIONS_LACKEY_DL /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_001: [ If thread_notification_cb is NULL, thread_notifications_lackey_set_callback shall fail and return a non-zero value. ]*/ if (thread_notifications_cb == NULL) { - LogError("Invalid arguments: THREAD_NOTIFICATIONS_LACKEY_DLL_CALLBACK_FUNC thread_notifications_cb=%p", thread_notifications_cb); result = MU_FAILURE; } else @@ -33,7 +30,6 @@ int thread_notifications_lackey_dll_init_callback(THREAD_NOTIFICATIONS_LACKEY_DL if (existing_callback != NULL) { /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_003: [ If the callback was already initialized, thread_notifications_lackey_dll_init_callback shall fail and return a non-zero value. ] */ - LogError("User error: callback already set to %p, thread_notifications_cb=%p", existing_callback, thread_notifications_cb); result = MU_FAILURE; } else @@ -61,6 +57,8 @@ BOOL WINAPI DllMain( (void)hinstDLL; (void)lpvReserved; + /* DllMain runs under the loader lock and, at process exit, after other DLLs may already have detached. + It therefore does no initialization or cleanup, only forwards thread notifications. */ switch (fdwReason) { default: @@ -70,17 +68,8 @@ BOOL WINAPI DllMain( /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [ If fdwReason is DLL_PROCESS_ATTACH: ]*/ case DLL_PROCESS_ATTACH: - /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_006: [ DllMain shall call logger_init to initialize logging for the module. ]*/ - if (logger_init() != 0) - { - /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_008: [ If logger_init fails, DllMain shall return FALSE. ]*/ - result = FALSE; - } - else - { - /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ Otherwise, DllMain shall initialize the callback maintained by the module with NULL and return TRUE. ]*/ - result = TRUE; - } + /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ DllMain shall return TRUE. ]*/ + result = TRUE; break; /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_011: [ If fdwReason is DLL_THREAD_ATTACH: ]*/ @@ -114,8 +103,7 @@ BOOL WINAPI DllMain( /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [ If fdwReason is DLL_PROCESS_DETACH: ]*/ case DLL_PROCESS_DETACH: - /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [DllMain shall call logger_deinit and return TRUE.]*/ - logger_deinit(); + /* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [ DllMain shall return TRUE. ]*/ result = TRUE; break; } diff --git a/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut.c b/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut.c index 0780c47a..db22e4b6 100644 --- a/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut.c +++ b/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut.c @@ -3,16 +3,6 @@ #include "thread_notif_lackey_dll_wo_init_ut_pch.h" -#include "umock_c/umock_c_ENABLE_MOCKS.h" // ============================== ENABLE_MOCKS -#undef ENABLE_MOCKS_DECL -#include "umock_c/umock_c_prod.h" -MOCK_FUNCTION_WITH_CODE(, int, mock_logger_init); -MOCK_FUNCTION_END(0) - -MOCK_FUNCTION_WITH_CODE(, void, mock_logger_deinit); -MOCK_FUNCTION_END() -#include "umock_c/umock_c_DISABLE_MOCKS.h" // ============================== DISABLE_MOCKS - MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES) static void on_umock_c_error(UMOCK_C_ERROR_CODE error_code) @@ -26,15 +16,10 @@ TEST_SUITE_INITIALIZE(suite_init) { ASSERT_ARE_EQUAL(int, 0, umock_c_init(on_umock_c_error), "umock_c_init failed"); ASSERT_ARE_EQUAL(int, 0, umocktypes_windows_register_types(), "umocktypes_windows_register_types failed"); - - REGISTER_GLOBAL_MOCK_FAIL_RETURN(mock_logger_init, MU_FAILURE); - - ASSERT_ARE_EQUAL(int, 0, umock_c_negative_tests_init()); } TEST_SUITE_CLEANUP(suite_cleanup) { - umock_c_negative_tests_deinit(); umock_c_deinit(); } diff --git a/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut_pch.h b/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut_pch.h index 1f9cc28a..eec088a4 100644 --- a/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut_pch.h +++ b/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notif_lackey_dll_wo_init_ut_pch.h @@ -15,11 +15,8 @@ #include "macro_utils/macro_utils.h" #include "testrunnerswitcher.h" -#include "c_logging/logger.h" - #include "umock_c/umock_c.h" #include "umock_c/umocktypes_windows.h" -#include "umock_c/umock_c_negative_tests.h" #include "c_pal/interlocked.h" diff --git a/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notifications_lackey_dll_mocked.c b/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notifications_lackey_dll_mocked.c index 2d33bd26..3dc52e76 100644 --- a/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notifications_lackey_dll_mocked.c +++ b/thread_notifications_lackey_dll/tests/thread_notif_lackey_dll_wo_init_ut/thread_notifications_lackey_dll_mocked.c @@ -1,9 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license.See LICENSE file in the project root for full license information. -#define logger_init mock_logger_init -#define logger_deinit mock_logger_deinit - // Since we mightbe running in an environment where a DllMain exists (like running under VS CppUnittest) // we want to rename it to something else #define DllMain DllMain_under_test diff --git a/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_mocked.c b/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_mocked.c index 2d33bd26..3dc52e76 100644 --- a/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_mocked.c +++ b/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_mocked.c @@ -1,9 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license.See LICENSE file in the project root for full license information. -#define logger_init mock_logger_init -#define logger_deinit mock_logger_deinit - // Since we mightbe running in an environment where a DllMain exists (like running under VS CppUnittest) // we want to rename it to something else #define DllMain DllMain_under_test diff --git a/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut.c b/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut.c index 4b4e6eb8..ec7fccf3 100644 --- a/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut.c +++ b/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut.c @@ -11,12 +11,6 @@ MOCK_FUNCTION_END() MOCK_FUNCTION_WITH_CODE(, void, test_thread_notifications_callback_2, THREAD_NOTIFICATIONS_LACKEY_DLL_REASON, reason); MOCK_FUNCTION_END() - -MOCK_FUNCTION_WITH_CODE(, int, mock_logger_init); -MOCK_FUNCTION_END(0) - -MOCK_FUNCTION_WITH_CODE(, void, mock_logger_deinit); -MOCK_FUNCTION_END() #include "umock_c/umock_c_DISABLE_MOCKS.h" // ============================== DISABLE_MOCKS static HMODULE test_module_handle = (HMODULE)0x42; @@ -36,15 +30,11 @@ TEST_SUITE_INITIALIZE(suite_init) ASSERT_ARE_EQUAL(int, 0, umock_c_init(on_umock_c_error), "umock_c_init failed"); ASSERT_ARE_EQUAL(int, 0, umocktypes_windows_register_types(), "umocktypes_windows_register_types failed"); - REGISTER_GLOBAL_MOCK_FAIL_RETURN(mock_logger_init, MU_FAILURE); REGISTER_TYPE(THREAD_NOTIFICATIONS_LACKEY_DLL_REASON, THREAD_NOTIFICATIONS_LACKEY_DLL_REASON); - - ASSERT_ARE_EQUAL(int, 0, umock_c_negative_tests_init()); } TEST_SUITE_CLEANUP(suite_cleanup) { - umock_c_negative_tests_deinit(); umock_c_deinit(); } @@ -135,12 +125,10 @@ TEST_FUNCTION(thread_notifications_lackey_dll_deinit_callback_when_not_initializ /* DllMain */ /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [ If fdwReason is DLL_PROCESS_ATTACH: ]*/ - /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_006: [ DllMain shall call logger_init to initialize logging for the module. ]*/ - /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ Otherwise, DllMain shall initialize the callback maintained by the module with NULL and return TRUE. ]*/ + /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ DllMain shall return TRUE. ]*/ TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_ATTACH_returns_TRUE) { // arrange - STRICT_EXPECTED_CALL(mock_logger_init()); // act BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_ATTACH, NULL); @@ -150,39 +138,29 @@ TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_ATTACH_return ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); } -/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_008: [ If logger_init fails, DllMain shall return FALSE. ]*/ -TEST_FUNCTION(when_underlying_calls_fail_thread_notifications_lackey_DllMain_with_DLL_PROCESS_ATTACH_returns_FALSE) +/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [ If fdwReason is DLL_PROCESS_DETACH: ]*/ + /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [ DllMain shall return TRUE. ]*/ +TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_DETACH_on_dynamic_unload_returns_TRUE) { // arrange - STRICT_EXPECTED_CALL(mock_logger_init()); - - umock_c_negative_tests_snapshot(); - - for (size_t i = 0; i < umock_c_negative_tests_call_count(); i++) - { - if (umock_c_negative_tests_can_call_fail(i)) - { - umock_c_negative_tests_reset(); - umock_c_negative_tests_fail_call(i); - // act - BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_ATTACH, NULL); + // act + BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_DETACH, NULL); - // assert - ASSERT_IS_FALSE(result); - } - } + // assert + ASSERT_IS_TRUE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); } /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [ If fdwReason is DLL_PROCESS_DETACH: ]*/ - /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [DllMain shall call logger_deinit and return TRUE.]*/ -TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_DETACH_returns_TRUE) + /* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [ DllMain shall return TRUE. ]*/ +TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_DETACH_during_process_termination_returns_TRUE) { // arrange - STRICT_EXPECTED_CALL(mock_logger_deinit()); + int process_termination_context = 0; // act - BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_DETACH, NULL); + BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_DETACH, &process_termination_context); // assert ASSERT_IS_TRUE(result); diff --git a/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut_pch.h b/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut_pch.h index 07368213..29b56a1e 100644 --- a/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut_pch.h +++ b/thread_notifications_lackey_dll/tests/thread_notifications_lackey_dll_ut/thread_notifications_lackey_dll_ut_pch.h @@ -15,11 +15,8 @@ #include "macro_utils/macro_utils.h" #include "testrunnerswitcher.h" -#include "c_logging/logger.h" - #include "umock_c/umock_c.h" #include "umock_c/umocktypes_windows.h" -#include "umock_c/umock_c_negative_tests.h" #include "c_pal/interlocked.h"