-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lua: Change the TLS callback function type of ThreadLocalState to Upd… #11944
Changes from 4 commits
fd94452
cd3b07c
e679c26
7335c74
1def9ea
3064066
0f690af
97c59b8
a32f9ff
efd8074
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,8 +71,9 @@ int ThreadLocalState::getGlobalRef(uint64_t slot) { | |
} | ||
|
||
uint64_t ThreadLocalState::registerGlobal(const std::string& global) { | ||
tls_slot_->runOnAllThreads([this, global]() { | ||
LuaThreadLocal& tls = tls_slot_->getTyped<LuaThreadLocal>(); | ||
tls_slot_->runOnAllThreads([global](ThreadLocal::ThreadLocalObjectSharedPtr ptr) -> auto { | ||
ASSERT(std::dynamic_pointer_cast<LuaThreadLocal>(ptr)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this assert here? |
||
LuaThreadLocal& tls = *std::dynamic_pointer_cast<LuaThreadLocal>(ptr); | ||
lua_getglobal(tls.state_.get(), global.c_str()); | ||
if (lua_isfunction(tls.state_.get(), -1)) { | ||
tls.global_slots_.push_back(luaL_ref(tls.state_.get(), LUA_REGISTRYINDEX)); | ||
|
@@ -81,6 +82,7 @@ uint64_t ThreadLocalState::registerGlobal(const std::string& global) { | |
lua_pop(tls.state_.get(), 1); | ||
tls.global_slots_.push_back(LUA_REFNIL); | ||
} | ||
return ptr; | ||
}); | ||
|
||
return current_global_slot_++; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
#include <memory> | ||
|
||
#include "common/thread_local/thread_local_impl.h" | ||
|
||
#include "extensions/filters/common/lua/lua.h" | ||
|
||
#include "test/mocks/common.h" | ||
|
@@ -157,6 +159,55 @@ TEST_F(LuaTest, MarkDead) { | |
lua_gc(cr1->luaState(), LUA_GCCOLLECT, 0); | ||
} | ||
|
||
class ThreadSafeTest : public testing::Test { | ||
public: | ||
ThreadSafeTest() | ||
: api_(Api::createApiForTest()), main_dispatcher_(api_->allocateDispatcher("main")), | ||
worker_dispatcher_(api_->allocateDispatcher("worker")) {} | ||
|
||
// Use real dispatchers to verify that callback functions can be executed correctly. | ||
Api::ApiPtr api_; | ||
Event::DispatcherPtr main_dispatcher_; | ||
Event::DispatcherPtr worker_dispatcher_; | ||
ThreadLocal::InstanceImpl tls_; | ||
|
||
std::unique_ptr<ThreadLocalState> state_; | ||
}; | ||
|
||
// Test whether ThreadLocalState can be safely released. | ||
TEST_F(ThreadSafeTest, StateDestructedBeforeWorkerRun) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this test fail without the code change in this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it will be a crash. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for verifying! |
||
const std::string SCRIPT{R"EOF( | ||
function HelloWorld() | ||
print("Hello World!") | ||
end | ||
)EOF"}; | ||
|
||
tls_.registerThread(*main_dispatcher_, true); | ||
EXPECT_EQ(main_dispatcher_.get(), &tls_.dispatcher()); | ||
tls_.registerThread(*worker_dispatcher_, false); | ||
|
||
// Some callback functions waiting to be executed will be added to the dispatcher of the Worker | ||
// thread. The callback functions in the main thread will be executed directly. | ||
state_ = std::make_unique<ThreadLocalState>(SCRIPT, tls_); | ||
state_->registerType<TestObject>(); | ||
|
||
main_dispatcher_->run(Event::Dispatcher::RunType::Block); | ||
|
||
// Destroy state_. | ||
state_.reset(nullptr); | ||
|
||
// Start a new worker thread to execute the callback functions in the worker dispatcher. | ||
Thread::ThreadPtr thread = Thread::threadFactoryForTest().createThread([this]() { | ||
worker_dispatcher_->run(Event::Dispatcher::RunType::Block); | ||
// Verify we have the expected dispatcher for the new thread thread. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the new worker thread? |
||
EXPECT_EQ(worker_dispatcher_.get(), &tls_.dispatcher()); | ||
}); | ||
thread->join(); | ||
|
||
tls_.shutdownGlobalThreading(); | ||
tls_.shutdownThread(); | ||
} | ||
|
||
} // namespace | ||
} // namespace Lua | ||
} // namespace Common | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does spelling out
-> auto
(-> ThreadLocal::ThreadLocalObjectSharedPtr
) here will be a problem for clang-tidy?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And let's rename
ptr
asprevious
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the existing code, it is acceptable to spell out the return type or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, I will remove it to make the code more concise.