Skip to content

Commit

Permalink
Allow updating vmodule levels after vmodule was parsed, invalidate al…
Browse files Browse the repository at this point in the history
…ready cached site flags
  • Loading branch information
romange committed May 11, 2021
1 parent d5c04ee commit da6efbc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
15 changes: 11 additions & 4 deletions src/glog/vlog_is_on.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@
// parsing of --vmodule flag and/or SetVLOGLevel calls.
#define VLOG_IS_ON(verboselevel) \
__extension__ \
({ static @ac_google_namespace@::int32* vlocal__ = NULL; \
({ static @ac_google_namespace@::SiteFlag vlocal__{NULL, NULL, 0, NULL}; \
@ac_google_namespace@::int32 verbose_level__ = (verboselevel); \
(vlocal__ == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \
__FILE__, verbose_level__) : *vlocal__ >= verbose_level__); \
(vlocal__.level == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \
__FILE__, verbose_level__) : *vlocal__.level >= verbose_level__); \
})
#else
// GNU extensions not available, so we do not support --vmodule.
Expand All @@ -105,6 +105,13 @@ extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,

// Various declarations needed for VLOG_IS_ON above: =========================

struct SiteFlag {
@ac_google_namespace@::int32* level;
const char* base_name;
size_t base_len;
SiteFlag* next;
};

// Helper routine which determines the logging info for a particalur VLOG site.
// site_flag is the address of the site-local pointer to the controlling
// verbosity level
Expand All @@ -114,7 +121,7 @@ extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
// We will return the return value for VLOG_IS_ON
// and if possible set *site_flag appropriately.
extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
@ac_google_namespace@::int32** site_flag,
@ac_google_namespace@::SiteFlag* site_flag,
@ac_google_namespace@::int32* site_default,
const char* fname,
@ac_google_namespace@::int32 verbose_level);
Expand Down
18 changes: 18 additions & 0 deletions src/logging_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ static void TestLogging(bool check_counts);
static void TestRawLogging();
static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
static void TestLoggingLevels();
static void TestVLogModule();
static void TestLogString();
static void TestLogSink();
static void TestLogToString();
Expand Down Expand Up @@ -219,6 +220,7 @@ int main(int argc, char **argv) {
TestLogging(true);
TestRawLogging();
TestLoggingLevels();
TestVLogModule();
TestLogString();
TestLogSink();
TestLogToString();
Expand Down Expand Up @@ -449,6 +451,22 @@ void TestLoggingLevels() {
LogWithLevels(1, GLOG_FATAL, false, true);
}

int TestVlogHelper() {
if (VLOG_IS_ON(1)) {
return 1;
}
return 0;
}

void TestVLogModule() {
int c = TestVlogHelper();
EXPECT_EQ(0, c);

EXPECT_EQ(0, SetVLOGLevel("logging_unittest", 1));
c = TestVlogHelper();
EXPECT_EQ(1, c);
}

TEST(DeathRawCHECK, logging) {
ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
"RAW: Check false failed: failure 1");
Expand Down
38 changes: 35 additions & 3 deletions src/vlog_is_on.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ static Mutex vmodule_lock;
// Pointer to head of the VModuleInfo list.
// It's a map from module pattern to logging level for those module(s).
static VModuleInfo* vmodule_list = 0;
static SiteFlag* cached_site_list = 0;

// Boolean initialization flag.
static bool inited_vmodule = false;

Expand Down Expand Up @@ -190,6 +192,23 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
info->vlog_level = log_level;
info->next = vmodule_list;
vmodule_list = info;

SiteFlag** item_ptr = &cached_site_list;
SiteFlag* item = cached_site_list;

// We traverse the list fully because the pattern can match several items
// from the list.
while (item) {
if (SafeFNMatch_(module_pattern, pattern_len, item->base_name,
item->base_len)) {
// Redirect the cached value to its module override.
item->level = &info->vlog_level;
*item_ptr = item->next; // Remove the item from the list.
} else {
item_ptr = &item->next;
}
item = *item_ptr;
}
}
}
RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level);
Expand All @@ -198,7 +217,7 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {

// NOTE: Individual VLOG statements cache the integer log level pointers.
// NOTE: This function must not allocate memory or require any locks.
bool InitVLOG3__(int32** site_flag, int32* site_default,
bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
const char* fname, int32 verbose_level) {
MutexLock l(&vmodule_lock);
bool read_vmodule_flag = inited_vmodule;
Expand All @@ -211,7 +230,7 @@ bool InitVLOG3__(int32** site_flag, int32* site_default,
int old_errno = errno;

// site_default normally points to FLAGS_v
int32* site_flag_value = site_default;
int32* site_flag_value = level_default;

// Get basename for file
const char* base = strrchr(fname, '/');
Expand Down Expand Up @@ -244,7 +263,20 @@ bool InitVLOG3__(int32** site_flag, int32* site_default,
ANNOTATE_BENIGN_RACE(site_flag,
"*site_flag may be written by several threads,"
" but the value will be the same");
if (read_vmodule_flag) *site_flag = site_flag_value;
if (read_vmodule_flag) {
site_flag->level = site_flag_value;
// If VLOG flag has been cached to the default site pointer,
// we want to add to the cached list in order to invalidate in case
// SetVModule is called afterwards with new modules.
// The performance penalty here is neglible, because InitVLOG3__ is called
// once per site.
if (site_flag_value == level_default && !site_flag->base_name) {
site_flag->base_name = base;
site_flag->base_len = base_length;
site_flag->next = cached_site_list;
cached_site_list = site_flag;
}
}

// restore the errno in case something recoverable went wrong during
// the initialization of the VLOG mechanism (see above note "protect the..")
Expand Down

0 comments on commit da6efbc

Please sign in to comment.