diff --git a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/code_cache.hpp b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/code_cache.hpp index b30587f549..9f24a5faab 100644 --- a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/code_cache.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/code_cache.hpp @@ -118,6 +118,7 @@ class code_cache_base { std::mutex _mtx; queued_compilies_t _queued_compiles; // protected by _mtx std::unordered_map _outstanding_compiles_and_poison; // protected by _mtx + std::atomic _outstanding_compiles{0}; size_t _free_bytes_eviction_threshold; void check_eviction_threshold(size_t free_bytes); diff --git a/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp b/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp index fc6e6bb9fd..9a482fde22 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp @@ -78,6 +78,8 @@ void code_cache_async::wait_on_compile_monitor_message() { return; } + --_outstanding_compiles; + const auto& msg = std::get(message); _result_queue.push(msg); @@ -92,10 +94,11 @@ void code_cache_async::wait_on_compile_monitor_message() { //called from non-main thread void code_cache_async::process_queued_compiles() { std::lock_guard g(_mtx); - while (_outstanding_compiles_and_poison.size() < _threads && !_queued_compiles.empty()) { + while (_outstanding_compiles < _threads && !_queued_compiles.empty()) { auto nextup = _queued_compiles.begin(); _outstanding_compiles_and_poison.emplace(nextup->code(), false); + ++_outstanding_compiles; FC_ASSERT(write_message_with_fds(_compile_monitor_write_socket, nextup->msg, nextup->fds_to_pass), "EOS VM failed to communicate to OOP manager"); _queued_compiles.erase(nextup); @@ -212,6 +215,7 @@ code_cache_async::get_descriptor_for_code(mode m, uint64_t executing_action_id, } _outstanding_compiles_and_poison.emplace(ct, false); + ++_outstanding_compiles; write_message_with_fds(_compile_monitor_write_socket, msg, fds_to_pass); failure = get_cd_failure::temporary; // Compile might not be done yet return nullptr; diff --git a/unittests/eosvmoc_interrupt_tests.cpp b/unittests/eosvmoc_interrupt_tests.cpp index d484969af3..8e7d0a9205 100644 --- a/unittests/eosvmoc_interrupt_tests.cpp +++ b/unittests/eosvmoc_interrupt_tests.cpp @@ -40,16 +40,16 @@ BOOST_AUTO_TEST_CASE( wasm_interrupt_test ) { try { auto pre_id = t.control->get_wasm_interface().get_executing_action_id(); // Use an infinite executing action. When oc compile completes it will kill the action and restart it under - // eosvmoc. That action will then fail when it hits the 60000ms deadline. - // 60000ms has to be long enough for oc compile to complete and kill the non-oc executing transaction + // eosvmoc. That action will then fail when it hits the 5000ms deadline. + // 5000ms has to be long enough for oc compile to complete and kill the non-oc executing transaction BOOST_CHECK_THROW( push_trx( t, test_api_action{}, - 0, 150, 60000, true, fc::raw::pack(10000000000000000000ULL) ), + 0, 150, 5000, true, fc::raw::pack(10000000000000000000ULL) ), deadline_exception ); auto post_id = t.control->get_wasm_interface().get_executing_action_id(); // each action uses 1 id, 2 if retried because of oc compile completion interruption - // if post_id == pre_id + 1, then likely that 60000ms above was not long enough for oc compile to complete + // if post_id == pre_id + 1, then likely that 5000ms above was not long enough for oc compile to complete BOOST_TEST(post_id == pre_id + 2); BOOST_REQUIRE_EQUAL( t.validate(), true );