Skip to content

fix(logging): read logger creator under lock in GetLogger - #464

Merged
lxy-9602 merged 1 commit into
apache:mainfrom
SteNicholas:PAIMON-463
Oct 26, 2026
Merged

lxy-9602 merged 1 commit into
apache:mainfrom
SteNicholas:PAIMON-463

Conversation

@SteNicholas

Copy link
Copy Markdown
Member

Purpose

Linked issue: close #463

Logger::GetLogger read the registered creator before taking the registry lock,
which raced with the first Logger::RegisterLogger call. It also called the
creator while holding the shared lock, so a creator that calls RegisterLogger
could deadlock. Without a registered creator, every call took the exclusive lock
just to check whether glog was initialized.

Hold the registered creator in a std::shared_ptr, copy the pointer under the
shared lock, and call the creator after unlocking. All calls share the registered
creator, so its state persists across calls, and a creator replaced while it runs
stays alive until that call finishes. Initialize glog once with std::call_once.

Tests

Unit tests in src/paimon/common/logging/logging_test.cpp. Each runs in an isolated
child process because a registered creator cannot be unset:

  • TestRegisterStatefulLoggerCreator: verifies that a creator with internal state
    keeps it across GetLogger calls.
  • TestRegisterLoggerCreatorWhileGettingLogger: registers the first creator while
    another thread gets loggers. ThreadSanitizer reports a data race if GetLogger
    reads the creator without holding the lock.
  • TestRegisterLoggerFromLoggerCreator: registers a creator from inside the running
    creator, and verifies that GetLogger does not deadlock and that the replaced
    creator's state stays alive until the call finishes.

API and Format

No API signature, storage format, or protocol changes. include/paimon/logging.h
only adds documentation for RegisterLogger and GetLogger.

Documentation

The public header now documents the thread safety of RegisterLogger and
GetLogger and what they require of the creator. No other documentation changes
are required for this bug fix.

Generative AI tooling

Generated-by: Claude Code 2.1.310 (Claude Opus 5.5)

🤖 Generated with Claude Code

GetLogger read the registered creator before taking the registry lock,
which raced with the first RegisterLogger call. It also called the
creator while holding the shared lock, so a creator that calls
RegisterLogger could deadlock. Without a registered creator, every
call took the exclusive lock just to check whether glog was
initialized.

Hold the registered creator in a shared_ptr, copy the pointer under
the shared lock, and call the creator after unlocking, so it keeps its
state across calls and stays alive if replaced. Initialize glog once
with std::call_once.

Document the thread safety of RegisterLogger and GetLogger, and what
they require of the creator.

@lucasfang lucasfang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

+1

@lxy-9602 lxy-9602 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1

@lxy-9602
lxy-9602 merged commit e6784e8 into apache:main Oct 26, 2026
16 checks passed
lucasfang pushed a commit to lucasfang/paimon-cpp that referenced this pull request Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Logger::GetLogger reads logger creator without lock and serializes default path

3 participants