Skip to content

fix: mark reference management variables as volatile for thread safety#35211

Open
yihaoDeng wants to merge 3 commits intomainfrom
fix/fixInvalidVisit
Open

fix: mark reference management variables as volatile for thread safety#35211
yihaoDeng wants to merge 3 commits intomainfrom
fix/fixInvalidVisit

Conversation

@yihaoDeng
Copy link
Copy Markdown
Contributor

Description

Issue(s)

  • Close/close/Fix/fix/Resolve/resolve: Issue Link

Checklist

Please check the items in the checklist if applicable.

  • Is the user manual updated?
  • Are the test cases passed and automated?
  • Is there no significant decrease in test coverage?

Copilot AI review requested due to automatic review settings April 22, 2026 10:07
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds the volatile qualifier to several static variables in transComm.c and tref.c, alongside minor formatting and whitespace adjustments. The review feedback correctly points out that using volatile is not a substitute for proper thread synchronization in C, as it does not guarantee atomicity or memory barriers. Since these variables are already managed via synchronization primitives like mutexes or pthread_once, the volatile qualifier is redundant and potentially misleading. Additionally, a duplicate declaration of the mutex array was identified in transComm.c that should be removed for clarity.

Comment thread source/libs/transport/src/transComm.c Outdated
Comment on lines +28 to +31
static volatile int32_t refMgt;
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The use of volatile for thread safety is a common misconception in C. volatile only prevents the compiler from optimizing memory accesses; it does not provide atomicity or memory barriers required for multi-threaded synchronization. Since these variables are initialized within taosThreadOnce (which typically uses pthread_once), memory visibility is already guaranteed by the synchronization primitive. Using volatile here is unnecessary and misleading regarding the thread-safety guarantees of the code.

static int32_t refMgt;
static int32_t svrRefMgt;
static int32_t instMgt;
static int32_t transSyncMsgMgt;

Comment thread source/libs/transport/src/transComm.c Outdated
Comment on lines +1307 to +1310
static volatile int32_t refMgt;
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

As noted previously, volatile does not provide thread safety or atomicity. These variables are initialized in a thread-safe manner via taosThreadOnce, making the volatile qualifier redundant and potentially hindering compiler optimizations.

static int32_t refMgt;
static int32_t svrRefMgt;
static int32_t instMgt;
static int32_t transSyncMsgMgt;

Comment thread source/util/src/tref.c Outdated
Comment on lines +52 to +53
static volatile int32_t tsRefSetNum = 0;
static volatile int32_t tsNextId = 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In C, volatile is not a substitute for proper synchronization primitives. These variables (tsRefSetNum, tsNextId) are already accessed within critical sections protected by tsRefMutex (e.g., in taosOpenRef and taosDecRsetCount). The mutex provides the necessary atomicity and memory visibility guarantees. Adding volatile is redundant and does not add any additional thread safety.

static int32_t tsRefSetNum = 0;
static int32_t tsNextId = 0;

Comment thread source/libs/transport/src/transComm.c Outdated
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
TdThreadMutex mutex[2];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This declaration of mutex[2] is a duplicate of the one on line 1302. While C allows multiple tentative definitions of the same global variable, it is redundant and should be removed to improve code clarity.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Marks several global reference-management counters/IDs as volatile and applies a few minor whitespace / formatting cleanups in util ref handling and transport communication code.

Changes:

  • Change multiple global reference-management variables from int32_t to volatile int32_t
  • Minor formatting cleanup (blank lines / line wrapping) in tref.c and transComm.c

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
source/util/src/tref.c Makes tsRefSetNum/tsNextId volatile and cleans up whitespace in ref iteration/locking helpers
source/libs/transport/src/transComm.c Makes ref-manager IDs volatile, wraps a long log line, removes stray whitespace; touches both TD_ASTRA_RPC and non-TD_ASTRA_RPC branches

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread source/util/src/tref.c Outdated
Comment on lines +52 to +53
static volatile int32_t tsRefSetNum = 0;
static volatile int32_t tsNextId = 0;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declaring tsRefSetNum/tsNextId as volatile does not make the increments/decrements thread-safe (no atomicity / memory ordering). In this file these variables are already updated under tsRefMutex, so volatile is unnecessary and can give a false sense of correctness. Prefer keeping them non-volatile and relying on the mutex, or convert them to the project’s atomic_* primitives if you need lock-free access.

Suggested change
static volatile int32_t tsRefSetNum = 0;
static volatile int32_t tsNextId = 0;
static int32_t tsRefSetNum = 0;
static int32_t tsNextId = 0;

Copilot uses AI. Check for mistakes.
Comment thread source/libs/transport/src/transComm.c Outdated
Comment on lines +28 to +31
static volatile int32_t refMgt;
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking these globals volatile does not provide thread safety or safe publication between threads; it only inhibits certain compiler optimizations. If these IDs are written once in transInitEnv and then treated as immutable, ensure all consumers call transInit (pthread_once provides the needed synchronization) and keep them non-volatile; otherwise use the project’s atomic load/store primitives for cross-thread reads/writes.

Suggested change
static volatile int32_t refMgt;
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
static int32_t refMgt;
static int32_t svrRefMgt;
static int32_t instMgt;
static int32_t transSyncMsgMgt;

Copilot uses AI. Check for mistakes.
Comment thread source/libs/transport/src/transComm.c Outdated
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
TdThreadMutex mutex[2];
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the TD_ASTRA_RPC (#else) branch, mutex[2] is defined twice at file scope (once above with multiQ, and again here). This will cause a redefinition compile error when that branch is built. Remove one of the definitions or rename so there is a single shared mutex array.

Suggested change
TdThreadMutex mutex[2];

Copilot uses AI. Check for mistakes.
Comment thread source/libs/transport/src/transComm.c Outdated
Comment on lines +1307 to +1310
static volatile int32_t refMgt;
static volatile int32_t svrRefMgt;
static volatile int32_t instMgt;
static volatile int32_t transSyncMsgMgt;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the non-ASTRA branch: volatile does not make these reference manager IDs thread-safe. Use pthread_once + an initialization requirement for callers, or switch to atomic load/store if they can be read/written concurrently.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 22, 2026 12:24
@yihaoDeng yihaoDeng force-pushed the fix/fixInvalidVisit branch from c8d6f52 to eae5009 Compare April 22, 2026 12:24
@yihaoDeng yihaoDeng force-pushed the fix/fixInvalidVisit branch 2 times, most recently from 98ca8ca to 80e617b Compare April 22, 2026 12:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


static TdThreadOnce initPoolOnce = PTHREAD_ONCE_INIT;
int32_t fetchObjRefPool = -1;
volatile int32_t fetchObjRefPool = -1;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declaring fetchObjRefPool as volatile does not make it thread-safe and is generally not a substitute for atomic operations. This variable is already manipulated via atomic helpers / taosThreadOnce; if you need atomic state transitions, prefer using atomic_* operations (e.g., atomic_exchange_32) and keep the declaration consistent with those APIs rather than using volatile as a synchronization mechanism.

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +68
volatile int32_t clientReqRefPool = -1;
volatile int32_t clientConnRefPool = -1;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

volatile does not provide synchronization/atomicity for these ref-pool IDs. They are set during client environment init/cleanup and read across multiple threads; using volatile here can be misleading and doesn’t prevent races. Prefer guarding init/teardown with a mutex or using the project's atomic helpers (e.g., atomic exchange / load) and keep the variables non-volatile unless required by the atomic API signatures.

Copilot uses AI. Check for mistakes.
typedef struct {
tmr_h timer;
int32_t rsetId;
volatile tmr_h timer;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmr_h is typedef void*, so volatile tmr_h becomes volatile void*. Passing tmqMgmt.timer to APIs like taosTmrStart/taosTmrReset (which take void* handle) will discard the volatile qualifier and, with -Werror enabled in this repo, can break the build. Also, volatile does not provide thread-safety for this handle. Prefer keeping timer as plain tmr_h and use the existing tmqMgmt.lock (or atomics) to coordinate concurrent reads/writes instead.

Suggested change
volatile tmr_h timer;
tmr_h timer;

Copilot uses AI. Check for mistakes.
};

extern int32_t fetchObjRefPool;
extern volatile int32_t fetchObjRefPool;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header change propagates volatile to all users, but volatile does not provide thread-safety and often forces unnecessary volatile loads throughout the codebase. If fetchObjRefPool needs to be accessed concurrently, prefer using the project's atomic helpers at the access sites (and keep the declaration non-volatile unless the atomic API requires a volatile*).

Suggested change
extern volatile int32_t fetchObjRefPool;
extern int32_t fetchObjRefPool;

Copilot uses AI. Check for mistakes.
Comment on lines +397 to +398
extern volatile int32_t clientReqRefPool;
extern volatile int32_t clientConnRefPool;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exposing these globals as volatile in the public client internal header spreads volatile semantics to all translation units, but volatile is not a thread-safety mechanism. Consider keeping these as plain int32_t and enforcing proper synchronization via taosThreadOnce/mutex/atomic helpers at the points where they are written/read concurrently.

Suggested change
extern volatile int32_t clientReqRefPool;
extern volatile int32_t clientConnRefPool;
extern int32_t clientReqRefPool;
extern int32_t clientConnRefPool;

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 22, 2026 14:03
@yihaoDeng yihaoDeng force-pushed the fix/fixInvalidVisit branch from 80e617b to 85c5ddd Compare April 22, 2026 14:03
@yihaoDeng yihaoDeng requested a review from a team as a code owner April 22, 2026 14:03
@yihaoDeng yihaoDeng force-pushed the fix/fixInvalidVisit branch from 85c5ddd to 81f2a73 Compare April 22, 2026 14:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

volatile int32_t svrRefMgt;
volatile int32_t instMgt;
volatile int32_t transSyncMsgMgt;
TdThreadMutex mutex[2];
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the #else branch (when TD_ASTRA_RPC is defined), mutex[2] is defined twice (once earlier at line ~1301 and again here). If this branch is ever compiled, this will be a redefinition error. Remove one of the definitions or rename/scope them appropriately. While touching this area, also consider restoring static for the refMgt/svrRefMgt/instMgt/transSyncMsgMgt globals if they are not meant to be exported.

Suggested change
TdThreadMutex mutex[2];

Copilot uses AI. Check for mistakes.
@yihaoDeng yihaoDeng force-pushed the fix/fixInvalidVisit branch from 81f2a73 to 403457f Compare April 22, 2026 14:09
On GCC 7.3, compiler may cache global variable values in registers,
making changes from one thread invisible to others.
Copilot AI review requested due to automatic review settings April 23, 2026 00:58
@yihaoDeng yihaoDeng force-pushed the fix/fixInvalidVisit branch from 403457f to 8f772f7 Compare April 23, 2026 00:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread source/libs/index/src/index.c Outdated
Comment on lines +56 to +57
volatile void* indexQhandle = NULL;
volatile int32_t indexRefMgt;
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declaring indexQhandle as volatile void* will cause qualifier-discard diagnostics when passing it to APIs taking void* (e.g., taosCleanUpScheduler, taosScheduleTask) under -Werror. Also, volatile doesn’t make publication/use of the handle thread-safe; prefer pthread_once/atomics for safe initialization and keep the handle type unqualified.

Suggested change
volatile void* indexQhandle = NULL;
volatile int32_t indexRefMgt;
void* indexQhandle = NULL;
int32_t indexRefMgt;

Copilot uses AI. Check for mistakes.
Comment thread source/libs/index/inc/indexInt.h Outdated
// clang-format on

extern void* indexQhandle;
extern volatile void* indexQhandle;
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exporting indexQhandle as extern volatile void* will force qualifier-discarding conversions at call sites (functions accept void*) and can break builds under -Werror. Keep the declaration as extern void* and use proper synchronization/atomics if you need safe publication.

Suggested change
extern volatile void* indexQhandle;
extern void* indexQhandle;

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 23, 2026 07:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants