namespace utils {
namespace logging {
-static LogLevel parseLogLevelConfiguration()
+namespace internal
{
- (void)getInitializationMutex(); // ensure initialization of global objects
- static cv::String param_log_level = utils::getConfigurationParameterString("OPENCV_LOG_LEVEL",
+// Combining several things that require static dynamic initialization in a
+// well-defined order into a struct.
+//
+struct GlobalLoggingInitStruct
+{
+public:
#if defined NDEBUG
- "WARNING"
+ static const bool m_isDebugBuild = false;
#else
- "INFO"
+ static const bool m_isDebugBuild = true;
#endif
- );
- if (param_log_level == "DISABLED" || param_log_level == "disabled" ||
- param_log_level == "0" || param_log_level == "OFF" || param_log_level == "off")
- return LOG_LEVEL_SILENT;
- if (param_log_level == "FATAL" || param_log_level == "fatal")
- return LOG_LEVEL_FATAL;
- if (param_log_level == "ERROR" || param_log_level == "error")
- return LOG_LEVEL_ERROR;
- if (param_log_level == "WARNING" || param_log_level == "warning" ||
- param_log_level == "WARNINGS" || param_log_level == "warnings" ||
- param_log_level == "WARN" || param_log_level == "warn")
- return LOG_LEVEL_WARNING;
- if (param_log_level == "INFO" || param_log_level == "info")
- return LOG_LEVEL_INFO;
- if (param_log_level == "DEBUG" || param_log_level == "debug")
- return LOG_LEVEL_DEBUG;
- if (param_log_level == "VERBOSE" || param_log_level == "verbose")
- return LOG_LEVEL_VERBOSE;
- std::cerr << "ERROR: Unexpected logging level value: " << param_log_level << std::endl;
- return LOG_LEVEL_INFO;
+
+public:
+ static LogLevel m_defaultUnconfiguredGlobalLevel;
+
+public:
+ LogTagManager logTagManager;
+
+ GlobalLoggingInitStruct()
+ : logTagManager(m_defaultUnconfiguredGlobalLevel)
+ {
++ (void)getInitializationMutex(); // ensure initialization of global objects
++
+ applyConfigString();
+ handleMalformed();
+ }
+
+private:
+ void applyConfigString()
+ {
+ logTagManager.setConfigString(utils::getConfigurationParameterString("OPENCV_LOG_LEVEL", ""));
+ }
+
+ void handleMalformed()
+ {
+ // need to print warning for malformed log tag config strings?
+ if (m_isDebugBuild)
+ {
+ const auto& parser = logTagManager.getConfigParser();
+ if (parser.hasMalformed())
+ {
+ const auto& malformedList = parser.getMalformed();
+ for (const auto& malformed : malformedList)
+ {
+ std::cout << "Malformed log level config: \"" << malformed << "\"\n";
+ }
+ std::cout.flush();
+ }
+ }
+ }
+};
+
+LogLevel GlobalLoggingInitStruct::m_defaultUnconfiguredGlobalLevel = GlobalLoggingInitStruct::m_isDebugBuild
+ ? LOG_LEVEL_INFO
+ : LOG_LEVEL_WARNING;
+
+
+// Static dynamic initialization guard function for the combined struct
+// just defined above
+//
+// An initialization guard function guarantees that outside code cannot
+// accidentally see not-yet-dynamically-initialized data, by routing
+// all outside access request to this function, so that this function
+// has a chance to run the initialization code if necessary.
+//
+// An initialization guard function only guarantees initialization upon
+// the first call to this function.
+//
+static GlobalLoggingInitStruct& getGlobalLoggingInitStruct()
+{
+ static GlobalLoggingInitStruct globalLoggingInitInstance;
+ return globalLoggingInitInstance;
+}
+
+// To ensure that the combined struct defined above is initialized even
+// if the initialization guard function wasn't called, a dummy static
+// instance of a struct is defined below, which will call the
+// initialization guard function.
+//
+struct GlobalLoggingInitCall
+{
+ GlobalLoggingInitCall()
+ {
+ getGlobalLoggingInitStruct();
+ }
+};
+
+static GlobalLoggingInitCall globalLoggingInitCall;
+
+static LogTagManager& getLogTagManager()
+{
+ static LogTagManager& logTagManagerInstance = getGlobalLoggingInitStruct().logTagManager;
+ return logTagManagerInstance;
}
static LogLevel& getLogLevelVariable()
return true;
}
- bool CvCaptureCAM_V4L::tryIoctl(unsigned long ioctlCode, void *parameter) const
+ bool CvCaptureCAM_V4L::tryIoctl(unsigned long ioctlCode, void *parameter, bool failIfBusy, int attempts) const
{
- CV_LOG_DEBUG(NULL, "tryIoctl(handle=" << deviceHandle << ", ioctl=0x" << std::hex << ioctlCode << ", ...)")
++ CV_LOG_DEBUG(NULL, "tryIoctl(handle=" << deviceHandle << ", ioctl=0x" << std::hex << ioctlCode << ", ...)");
+ if (attempts == 0) {
+ return false;
+ }
while (-1 == ioctl(deviceHandle, ioctlCode, parameter)) {
- if (!(errno == EBUSY || errno == EAGAIN))
+ const bool isBusy = (errno == EBUSY);
+ if (isBusy & failIfBusy) {
+ return false;
+ }
+ if ((attempts > 0) && (--attempts == 0)) {
+ return false;
+ }
+
+ if (!(isBusy || errno == EAGAIN))
return false;
fd_set fds;