Skip to content

Commit dd5f4b5

Browse files
liuh-80arfeigin
authored andcommitted
RedisPipeline ignore flush when call dtor from another thread. (sonic-net#736)
#### Why I did it Because RedisPipeline is not thread safe, in c++ if code call exit() from another thread, the dtor of RedisPipeline will be called from another thread and trigger a race condition issue. #### How I did it RedisPipeline ignore flush when call dtor from another thread. #### How to verify it Pass all UT and E2E test cases. #### Which release branch to backport (provide reason below if selected) <!-- - Note we only backport fixes to a release branch, *not* features! - Please also provide a reason for the backporting below. - e.g. - [x] 202006 --> - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 #### Description for the changelog RedisPipeline ignore flush when call dtor from another thread. #### Link to config_db schema for YANG module changes <!-- Provide a link to config_db schema for the table for which YANG model is defined Link should point to correct section on https://github.com/Azure/SONiC/wiki/Configuration. --> #### A picture of a cute animal (not mandatory but encouraged)
1 parent 1ef6a3f commit dd5f4b5

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

common/redispipeline.h

+22-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
#include "redisreply.h"
77
#include "rediscommand.h"
88
#include "dbconnector.h"
9+
#include "logger.h"
10+
11+
#include "unistd.h"
12+
#include "sys/syscall.h"
13+
#define gettid() syscall(SYS_gettid)
914

1015
namespace swss {
1116

@@ -19,10 +24,20 @@ class RedisPipeline {
1924
, m_remaining(0)
2025
{
2126
m_db = db->newConnector(NEWCONNECTOR_TIMEOUT);
27+
initializeOwnerTid();
2228
}
2329

2430
~RedisPipeline() {
25-
flush();
31+
if (m_ownerTid == gettid())
32+
{
33+
// call flush from different thread will trigger race condition issue.
34+
flush();
35+
}
36+
else
37+
{
38+
SWSS_LOG_NOTICE("RedisPipeline dtor is called from another thread, possibly due to exit(), Database: %s", getDbName().c_str());
39+
}
40+
2641
delete m_db;
2742
}
2843

@@ -125,10 +140,16 @@ class RedisPipeline {
125140
return m_db;
126141
}
127142

143+
void initializeOwnerTid()
144+
{
145+
m_ownerTid = gettid();
146+
}
147+
128148
private:
129149
DBConnector *m_db;
130150
std::queue<int> m_expectedTypes;
131151
size_t m_remaining;
152+
long int m_ownerTid;
132153

133154
void mayflush()
134155
{

0 commit comments

Comments
 (0)