Commit b3427e71 authored by Emanuele Altieri's avatar Emanuele Altieri Committed by Facebook GitHub Bot

FB_LOG_ONCE()

Summary: We need a thread-safe alternative to `LOG_FIRST_N(severity, n)` -- specifically when n = 1, the most common case.

Reviewed By: yfeldblum, ot, luciang

Differential Revision: D28884240

fbshipit-source-id: 41c937bf37dba036b71f1c62fd70445e79a3924a
parent db723b64
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#pragma once #pragma once
#include <folly/Likely.h>
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
...@@ -57,3 +59,27 @@ ...@@ -57,3 +59,27 @@
LOG(severity) LOG(severity)
#endif #endif
/**
* Issues a LOG(severity) once.
*
* FB_LOG_ONCE(ERROR) << "Log this error only once";
*
* This macro is thread-safe and does not impact surrounding statements.
*
* NOTE: A load() is used in the fast-path scenario (steady state) in order to
* avoid a locked RMW operation.
*/
#ifndef FB_LOG_ONCE
#define FB_LOG_ONCE(severity) \
for (auto __folly_detail_glog_once = true; __folly_detail_glog_once;) \
for (static ::std::atomic_bool __folly_detail_glog_logged{false}; \
__folly_detail_glog_once; \
__folly_detail_glog_once = false) \
if (FOLLY_LIKELY( \
__folly_detail_glog_logged.load(::std::memory_order_relaxed)) || \
__folly_detail_glog_logged.exchange( \
true, ::std::memory_order_relaxed)) { \
} else \
LOG(severity)
#endif
...@@ -104,8 +104,7 @@ static void fetchStackLimits() { ...@@ -104,8 +104,7 @@ static void fetchStackLimits() {
pthread_attr_t attr; pthread_attr_t attr;
if ((err = pthread_getattr_np(pthread_self(), &attr))) { if ((err = pthread_getattr_np(pthread_self(), &attr))) {
// some restricted environments can't access /proc // some restricted environments can't access /proc
FB_LOG_EVERY_MS(WARNING, 60000) FB_LOG_ONCE(ERROR) << "pthread_getaddr_np failed errno=" << err;
<< "pthread_getaddr_np failed errno=" << err;
tls_stackSize = 1; tls_stackSize = 1;
return; return;
} }
...@@ -115,7 +114,7 @@ static void fetchStackLimits() { ...@@ -115,7 +114,7 @@ static void fetchStackLimits() {
size_t rawSize; size_t rawSize;
if ((err = pthread_attr_getstack(&attr, &addr, &rawSize))) { if ((err = pthread_attr_getstack(&attr, &addr, &rawSize))) {
// unexpected, but it is better to continue in prod than do nothing // unexpected, but it is better to continue in prod than do nothing
FB_LOG_EVERY_MS(ERROR, 10000) << "pthread_attr_getstack error " << err; FB_LOG_ONCE(ERROR) << "pthread_attr_getstack error " << err;
assert(false); assert(false);
tls_stackSize = 1; tls_stackSize = 1;
return; return;
...@@ -131,8 +130,8 @@ static void fetchStackLimits() { ...@@ -131,8 +130,8 @@ static void fetchStackLimits() {
// //
// Very large stack size is a bug (hence the assert), but we can // Very large stack size is a bug (hence the assert), but we can
// carry on if we are in prod. // carry on if we are in prod.
FB_LOG_EVERY_MS(ERROR, 10000) FB_LOG_ONCE(ERROR) << "pthread_attr_getstack returned insane stack size "
<< "pthread_attr_getstack returned insane stack size " << rawSize; << rawSize;
assert(false); assert(false);
tls_stackSize = 1; tls_stackSize = 1;
return; return;
......
...@@ -242,9 +242,8 @@ bool RequestContext::State::doSetContextData( ...@@ -242,9 +242,8 @@ bool RequestContext::State::doSetContextData(
result = doSetContextDataHelper(token, data, behaviour, safe); result = doSetContextDataHelper(token, data, behaviour, safe);
} }
if (result.unexpected) { if (result.unexpected) {
FB_LOG_EVERY_MS(WARNING, 60000) FB_LOG_ONCE(WARNING) << "Calling RequestContext::setContextData for "
<< "Calling RequestContext::setContextData for " << token.getDebugString() << " but it is already set";
<< token.getDebugString() << " but it is already set";
} }
if (result.replaced) { if (result.replaced) {
result.replaced->retire(); // Retire to hazptr library result.replaced->retire(); // Retire to hazptr library
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment