Switch db_mutex to a std::mutex. Use modern locking with it. Use zmDbDo or dbQueue.push where appropriate. code cleanup.
This commit is contained in:
parent
fdf515ca10
commit
8aeb4ab758
|
@ -23,7 +23,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
MYSQL dbconn;
|
MYSQL dbconn;
|
||||||
RecursiveMutex db_mutex;
|
std::mutex db_mutex;
|
||||||
zmDbQueue dbQueue;
|
zmDbQueue dbQueue;
|
||||||
|
|
||||||
bool zmDbConnected = false;
|
bool zmDbConnected = false;
|
||||||
|
@ -108,46 +108,36 @@ bool zmDbConnect() {
|
||||||
|
|
||||||
void zmDbClose() {
|
void zmDbClose() {
|
||||||
if (zmDbConnected) {
|
if (zmDbConnected) {
|
||||||
db_mutex.lock();
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
mysql_close(&dbconn);
|
mysql_close(&dbconn);
|
||||||
// mysql_init() call implicitly mysql_library_init() but
|
// mysql_init() call implicitly mysql_library_init() but
|
||||||
// mysql_close() does not call mysql_library_end()
|
// mysql_close() does not call mysql_library_end()
|
||||||
mysql_library_end();
|
mysql_library_end();
|
||||||
zmDbConnected = false;
|
zmDbConnected = false;
|
||||||
db_mutex.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MYSQL_RES * zmDbFetch(const char * query) {
|
MYSQL_RES * zmDbFetch(const char * query) {
|
||||||
if ( !zmDbConnected ) {
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
Error("Not connected.");
|
if (!zmDbConnected) {
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
db_mutex.lock();
|
|
||||||
// Might have been disconnected while we waited for the lock
|
|
||||||
if ( !zmDbConnected ) {
|
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Not connected.");
|
Error("Not connected.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, query) ) {
|
if (mysql_query(&dbconn, query)) {
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Debug(4, "Success running query: %s", query);
|
|
||||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||||
if ( !result ) {
|
if (!result) {
|
||||||
Error("Can't use query result: %s for query %s", mysql_error(&dbconn), query);
|
Error("Can't use query result: %s for query %s", mysql_error(&dbconn), query);
|
||||||
}
|
}
|
||||||
db_mutex.unlock();
|
|
||||||
return result;
|
return result;
|
||||||
} // end MYSQL_RES * zmDbFetch(const char * query);
|
} // end MYSQL_RES * zmDbFetch(const char * query);
|
||||||
|
|
||||||
zmDbRow *zmDbFetchOne(const char *query) {
|
zmDbRow *zmDbFetchOne(const char *query) {
|
||||||
zmDbRow *row = new zmDbRow();
|
zmDbRow *row = new zmDbRow();
|
||||||
if ( row->fetch(query) ) {
|
if (row->fetch(query)) {
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
delete row;
|
delete row;
|
||||||
|
@ -156,10 +146,10 @@ zmDbRow *zmDbFetchOne(const char *query) {
|
||||||
|
|
||||||
MYSQL_RES *zmDbRow::fetch(const char *query) {
|
MYSQL_RES *zmDbRow::fetch(const char *query) {
|
||||||
result_set = zmDbFetch(query);
|
result_set = zmDbFetch(query);
|
||||||
if ( ! result_set ) return result_set;
|
if (!result_set) return result_set;
|
||||||
|
|
||||||
int n_rows = mysql_num_rows(result_set);
|
int n_rows = mysql_num_rows(result_set);
|
||||||
if ( n_rows != 1 ) {
|
if (n_rows != 1) {
|
||||||
Error("Bogus number of lines return from query, %d returned for query %s.", n_rows, query);
|
Error("Bogus number of lines return from query, %d returned for query %s.", n_rows, query);
|
||||||
mysql_free_result(result_set);
|
mysql_free_result(result_set);
|
||||||
result_set = nullptr;
|
result_set = nullptr;
|
||||||
|
@ -167,7 +157,7 @@ MYSQL_RES *zmDbRow::fetch(const char *query) {
|
||||||
}
|
}
|
||||||
|
|
||||||
row = mysql_fetch_row(result_set);
|
row = mysql_fetch_row(result_set);
|
||||||
if ( !row ) {
|
if (!row) {
|
||||||
mysql_free_result(result_set);
|
mysql_free_result(result_set);
|
||||||
result_set = nullptr;
|
result_set = nullptr;
|
||||||
Error("Error getting row from query %s. Error is %s", query, mysql_error(&dbconn));
|
Error("Error getting row from query %s. Error is %s", query, mysql_error(&dbconn));
|
||||||
|
@ -178,38 +168,34 @@ MYSQL_RES *zmDbRow::fetch(const char *query) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmDbDo(const char *query) {
|
int zmDbDo(const char *query) {
|
||||||
db_mutex.lock();
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
|
if (!zmDbConnected)
|
||||||
|
return 0;
|
||||||
int rc;
|
int rc;
|
||||||
while ( (rc = mysql_query(&dbconn, query)) and !zm_terminate) {
|
while ((rc = mysql_query(&dbconn, query)) and !zm_terminate) {
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Can't run query %s: %s", query, mysql_error(&dbconn));
|
Error("Can't run query %s: %s", query, mysql_error(&dbconn));
|
||||||
if ( (mysql_errno(&dbconn) != ER_LOCK_WAIT_TIMEOUT) )
|
if ( (mysql_errno(&dbconn) != ER_LOCK_WAIT_TIMEOUT) ) {
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
db_mutex.lock();
|
|
||||||
}
|
}
|
||||||
db_mutex.unlock();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmDbDoInsert(const char *query) {
|
int zmDbDoInsert(const char *query) {
|
||||||
db_mutex.lock();
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
|
if (!zmDbConnected) return 0;
|
||||||
int rc;
|
int rc;
|
||||||
while ( (rc = mysql_query(&dbconn, query)) and !zm_terminate) {
|
while ( (rc = mysql_query(&dbconn, query)) and !zm_terminate) {
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Can't run query %s: %s", query, mysql_error(&dbconn));
|
Error("Can't run query %s: %s", query, mysql_error(&dbconn));
|
||||||
if ( (mysql_errno(&dbconn) != ER_LOCK_WAIT_TIMEOUT) )
|
if ( (mysql_errno(&dbconn) != ER_LOCK_WAIT_TIMEOUT) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
db_mutex.lock();
|
|
||||||
}
|
}
|
||||||
int id = mysql_insert_id(&dbconn);
|
int id = mysql_insert_id(&dbconn);
|
||||||
db_mutex.unlock();
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
zmDbRow::~zmDbRow() {
|
zmDbRow::~zmDbRow() {
|
||||||
if ( result_set ) {
|
if (result_set) {
|
||||||
mysql_free_result(result_set);
|
mysql_free_result(result_set);
|
||||||
result_set = nullptr;
|
result_set = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ class zmDbRow {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MYSQL dbconn;
|
extern MYSQL dbconn;
|
||||||
extern RecursiveMutex db_mutex;
|
extern std::mutex db_mutex;
|
||||||
extern zmDbQueue dbQueue;
|
extern zmDbQueue dbQueue;
|
||||||
|
|
||||||
extern bool zmDbConnected;
|
extern bool zmDbConnected;
|
||||||
|
|
|
@ -251,28 +251,25 @@ Event::~Event() {
|
||||||
frames, alarm_frames,
|
frames, alarm_frames,
|
||||||
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
||||||
id);
|
id);
|
||||||
db_mutex.lock();
|
{ // scope for lock
|
||||||
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
|
|
||||||
db_mutex.lock();
|
|
||||||
}
|
|
||||||
if ( !mysql_affected_rows(&dbconn) ) {
|
|
||||||
// Name might have been changed during recording, so just do the update without changing the name.
|
|
||||||
snprintf(sql, sizeof(sql),
|
|
||||||
"UPDATE Events SET EndDateTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
|
|
||||||
end_time.tv_sec,
|
|
||||||
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
|
||||||
frames, alarm_frames,
|
|
||||||
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
|
||||||
id);
|
|
||||||
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
|
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
|
||||||
db_mutex.lock();
|
|
||||||
}
|
}
|
||||||
} // end if no changed rows due to Name change during recording
|
if ( !mysql_affected_rows(&dbconn) ) {
|
||||||
db_mutex.unlock();
|
// Name might have been changed during recording, so just do the update without changing the name.
|
||||||
|
snprintf(sql, sizeof(sql),
|
||||||
|
"UPDATE Events SET EndDateTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
|
||||||
|
end_time.tv_sec,
|
||||||
|
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
||||||
|
frames, alarm_frames,
|
||||||
|
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
||||||
|
id);
|
||||||
|
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
||||||
|
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
|
||||||
|
}
|
||||||
|
} // end if no changed rows due to Name change during recording
|
||||||
|
}
|
||||||
} // Event::~Event()
|
} // Event::~Event()
|
||||||
|
|
||||||
void Event::createNotes(std::string ¬es) {
|
void Event::createNotes(std::string ¬es) {
|
||||||
|
@ -489,14 +486,7 @@ void Event::AddFramesInternal(int n_frames, int start_frame, Image **images, str
|
||||||
|
|
||||||
if ( frameCount ) {
|
if ( frameCount ) {
|
||||||
*(frame_insert_values-1) = '\0';
|
*(frame_insert_values-1) = '\0';
|
||||||
db_mutex.lock();
|
zmDbDo(frame_insert_sql);
|
||||||
int rc = mysql_query(&dbconn, frame_insert_sql);
|
|
||||||
db_mutex.unlock();
|
|
||||||
if ( rc ) {
|
|
||||||
Error("Can't insert frames: %s, sql was (%s)", mysql_error(&dbconn), frame_insert_sql);
|
|
||||||
} else {
|
|
||||||
Debug(1, "INSERT %d/%d frames sql %s", frameCount, n_frames, frame_insert_sql);
|
|
||||||
}
|
|
||||||
last_db_frame = frames;
|
last_db_frame = frames;
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "No valid pre-capture frames to add");
|
Debug(1, "No valid pre-capture frames to add");
|
||||||
|
@ -548,16 +538,7 @@ void Event::WriteDbFrames() {
|
||||||
delete frame;
|
delete frame;
|
||||||
}
|
}
|
||||||
*(frame_insert_values_ptr-1) = '\0'; // The -1 is for the extra , added for values above
|
*(frame_insert_values_ptr-1) = '\0'; // The -1 is for the extra , added for values above
|
||||||
db_mutex.lock();
|
zmDbDo(frame_insert_sql);
|
||||||
int rc = mysql_query(&dbconn, frame_insert_sql);
|
|
||||||
db_mutex.unlock();
|
|
||||||
|
|
||||||
if ( rc ) {
|
|
||||||
Error("Can't insert frames: %s, sql was %s", mysql_error(&dbconn), frame_insert_sql);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
Debug(1, "INSERT FRAMES: sql was %s", frame_insert_sql);
|
|
||||||
}
|
|
||||||
} // end void Event::WriteDbFrames()
|
} // end void Event::WriteDbFrames()
|
||||||
|
|
||||||
void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *alarm_image) {
|
void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *alarm_image) {
|
||||||
|
|
|
@ -132,7 +132,7 @@ VncCamera::VncCamera(
|
||||||
}
|
}
|
||||||
|
|
||||||
VncCamera::~VncCamera() {
|
VncCamera::~VncCamera() {
|
||||||
if (capture) {
|
if (capture and mRfb) {
|
||||||
if (mRfb->frameBuffer)
|
if (mRfb->frameBuffer)
|
||||||
free(mRfb->frameBuffer);
|
free(mRfb->frameBuffer);
|
||||||
(*rfbClientCleanup_f)(mRfb);
|
(*rfbClientCleanup_f)(mRfb);
|
||||||
|
@ -164,6 +164,7 @@ int VncCamera::PrimeCapture() {
|
||||||
mRfb->GetCredential = GetCredentialsCallback;
|
mRfb->GetCredential = GetCredentialsCallback;
|
||||||
|
|
||||||
mRfb->programName = "Zoneminder VNC Monitor";
|
mRfb->programName = "Zoneminder VNC Monitor";
|
||||||
|
if ( mRfb->serverHost ) free(mRfb->serverHost);
|
||||||
mRfb->serverHost = strdup(mHost.c_str());
|
mRfb->serverHost = strdup(mHost.c_str());
|
||||||
mRfb->serverPort = atoi(mPort.c_str());
|
mRfb->serverPort = atoi(mPort.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,7 @@
|
||||||
|
|
||||||
#include "zm_db.h"
|
#include "zm_db.h"
|
||||||
#include "zm_utils.h"
|
#include "zm_utils.h"
|
||||||
#include <cerrno>
|
|
||||||
#include <csignal>
|
|
||||||
#include <cstdarg>
|
|
||||||
#include <cstring>
|
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -32,6 +29,11 @@
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#include <sys/thr.h>
|
#include <sys/thr.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cerrno>
|
||||||
|
#include <csignal>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
bool Logger::smInitialised = false;
|
bool Logger::smInitialised = false;
|
||||||
Logger *Logger::smInstance = nullptr;
|
Logger *Logger::smInstance = nullptr;
|
||||||
|
@ -57,16 +59,15 @@ Logger::Logger() :
|
||||||
mEffectiveLevel(NOLOG),
|
mEffectiveLevel(NOLOG),
|
||||||
mDbConnected(false),
|
mDbConnected(false),
|
||||||
mLogPath(staticConfig.PATH_LOGS.c_str()),
|
mLogPath(staticConfig.PATH_LOGS.c_str()),
|
||||||
//mLogFile( mLogPath+"/"+mId+".log" ),
|
// mLogFile( mLogPath+"/"+mId+".log" ),
|
||||||
mLogFileFP(nullptr),
|
mLogFileFP(nullptr),
|
||||||
mHasTerminal(false),
|
mHasTerminal(false),
|
||||||
mFlush(false) {
|
mFlush(false) {
|
||||||
|
if (smInstance) {
|
||||||
if ( smInstance ) {
|
|
||||||
Panic("Attempt to create second instance of Logger class");
|
Panic("Attempt to create second instance of Logger class");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !smInitialised ) {
|
if (!smInitialised) {
|
||||||
smCodes[INFO] = "INF";
|
smCodes[INFO] = "INF";
|
||||||
smCodes[WARNING] = "WAR";
|
smCodes[WARNING] = "WAR";
|
||||||
smCodes[ERROR] = "ERR";
|
smCodes[ERROR] = "ERR";
|
||||||
|
@ -81,16 +82,16 @@ Logger::Logger() :
|
||||||
smSyslogPriorities[PANIC] = LOG_ERR;
|
smSyslogPriorities[PANIC] = LOG_ERR;
|
||||||
|
|
||||||
char code[4] = "";
|
char code[4] = "";
|
||||||
for ( int i = DEBUG1; i <= DEBUG9; i++ ) {
|
for (int i = DEBUG1; i <= DEBUG9; i++) {
|
||||||
snprintf(code, sizeof(code), "DB%d", i);
|
snprintf(code, sizeof(code), "DB%d", i);
|
||||||
smCodes[i] = code;
|
smCodes[i] = code;
|
||||||
smSyslogPriorities[i] = LOG_DEBUG;
|
smSyslogPriorities[i] = LOG_DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
smInitialised = true;
|
smInitialised = true;
|
||||||
}
|
} // end if ! smInitialised
|
||||||
|
|
||||||
if ( fileno(stderr) && isatty(fileno(stderr)) ) {
|
if (fileno(stderr) && isatty(fileno(stderr))) {
|
||||||
mHasTerminal = true;
|
mHasTerminal = true;
|
||||||
mTerminalLevel = WARNING;
|
mTerminalLevel = WARNING;
|
||||||
}
|
}
|
||||||
|
@ -101,14 +102,6 @@ Logger::~Logger() {
|
||||||
smCodes.clear();
|
smCodes.clear();
|
||||||
smSyslogPriorities.clear();
|
smSyslogPriorities.clear();
|
||||||
smInitialised = false;
|
smInitialised = false;
|
||||||
#if 0
|
|
||||||
for ( StringMap::iterator itr = smCodes.begin(); itr != smCodes.end(); itr ++ ) {
|
|
||||||
smCodes.erase( itr );
|
|
||||||
}
|
|
||||||
for ( IntMap::iterator itr = smSyslogPriorities.begin(); itr != smSyslogPriorities.end(); itr ++ ) {
|
|
||||||
smSyslogPriorities.erase(itr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::initialise(const std::string &id, const Options &options) {
|
void Logger::initialise(const std::string &id, const Options &options) {
|
||||||
|
@ -185,7 +178,7 @@ void Logger::initialise(const std::string &id, const Options &options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end foreach target
|
} // end foreach target
|
||||||
} else {
|
} else {
|
||||||
// if we don't have debug turned on, then the max effective log level is INFO
|
// if we don't have debug turned on, then the max effective log level is INFO
|
||||||
if ( tempSyslogLevel > INFO ) tempSyslogLevel = INFO;
|
if ( tempSyslogLevel > INFO ) tempSyslogLevel = INFO;
|
||||||
|
@ -193,7 +186,7 @@ void Logger::initialise(const std::string &id, const Options &options) {
|
||||||
if ( tempTerminalLevel > INFO ) tempTerminalLevel = INFO;
|
if ( tempTerminalLevel > INFO ) tempTerminalLevel = INFO;
|
||||||
if ( tempDatabaseLevel > INFO ) tempDatabaseLevel = INFO;
|
if ( tempDatabaseLevel > INFO ) tempDatabaseLevel = INFO;
|
||||||
if ( tempLevel > INFO ) tempLevel = INFO;
|
if ( tempLevel > INFO ) tempLevel = INFO;
|
||||||
} // end if config.log_debug
|
} // end if config.log_debug
|
||||||
|
|
||||||
logFile(tempLogFile);
|
logFile(tempLogFile);
|
||||||
|
|
||||||
|
@ -355,11 +348,11 @@ Logger::Level Logger::databaseLevel(Logger::Level databaseLevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Level Logger::fileLevel(Logger::Level fileLevel) {
|
Logger::Level Logger::fileLevel(Logger::Level fileLevel) {
|
||||||
if ( fileLevel > NOOPT ) {
|
if (fileLevel > NOOPT) {
|
||||||
fileLevel = limit(fileLevel);
|
fileLevel = limit(fileLevel);
|
||||||
// Always close, because we may have changed file names
|
// Always close, because we may have changed file names
|
||||||
if ( mFileLevel > NOLOG )
|
if (mFileLevel > NOLOG)
|
||||||
closeFile();
|
closeFile();
|
||||||
mFileLevel = fileLevel;
|
mFileLevel = fileLevel;
|
||||||
// Don't try to open it here because it will create the log file even if we never write to it.
|
// Don't try to open it here because it will create the log file even if we never write to it.
|
||||||
}
|
}
|
||||||
|
@ -367,13 +360,13 @@ Logger::Level Logger::fileLevel(Logger::Level fileLevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Level Logger::syslogLevel(Logger::Level syslogLevel) {
|
Logger::Level Logger::syslogLevel(Logger::Level syslogLevel) {
|
||||||
if ( syslogLevel > NOOPT ) {
|
if (syslogLevel > NOOPT) {
|
||||||
syslogLevel = limit(syslogLevel);
|
syslogLevel = limit(syslogLevel);
|
||||||
if ( mSyslogLevel != syslogLevel ) {
|
if (mSyslogLevel != syslogLevel) {
|
||||||
if ( mSyslogLevel > NOLOG )
|
if (mSyslogLevel > NOLOG)
|
||||||
closeSyslog();
|
closeSyslog();
|
||||||
mSyslogLevel = syslogLevel;
|
mSyslogLevel = syslogLevel;
|
||||||
if ( mSyslogLevel > NOLOG )
|
if (mSyslogLevel > NOLOG)
|
||||||
openSyslog();
|
openSyslog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,31 +376,31 @@ Logger::Level Logger::syslogLevel(Logger::Level syslogLevel) {
|
||||||
void Logger::logFile(const std::string &logFile) {
|
void Logger::logFile(const std::string &logFile) {
|
||||||
bool addLogPid = false;
|
bool addLogPid = false;
|
||||||
std::string tempLogFile = logFile;
|
std::string tempLogFile = logFile;
|
||||||
if ( tempLogFile[tempLogFile.length()-1] == '+' ) {
|
if (tempLogFile[tempLogFile.length()-1] == '+') {
|
||||||
tempLogFile.resize(tempLogFile.length()-1);
|
tempLogFile.resize(tempLogFile.length()-1);
|
||||||
addLogPid = true;
|
addLogPid = true;
|
||||||
}
|
}
|
||||||
if ( addLogPid )
|
if (addLogPid)
|
||||||
mLogFile = stringtf("%s.%05d", tempLogFile.c_str(), getpid());
|
mLogFile = stringtf("%s.%05d", tempLogFile.c_str(), getpid());
|
||||||
else
|
else
|
||||||
mLogFile = tempLogFile;
|
mLogFile = tempLogFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::openFile() {
|
void Logger::openFile() {
|
||||||
if ( mLogFile.size() ) {
|
if (mLogFile.size()) {
|
||||||
if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == nullptr ) {
|
if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == nullptr ) {
|
||||||
mFileLevel = NOLOG;
|
mFileLevel = NOLOG;
|
||||||
Error("fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno));
|
Error("fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
puts("Called Logger::openFile() without a filename");
|
puts("Called Logger::openFile() without a filename");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::closeFile() {
|
void Logger::closeFile() {
|
||||||
if ( mLogFileFP ) {
|
if (mLogFileFP) {
|
||||||
fflush(mLogFileFP);
|
fflush(mLogFileFP);
|
||||||
if ( fclose(mLogFileFP) < 0 ) {
|
if (fclose(mLogFileFP) < 0) {
|
||||||
mLogFileFP = nullptr;
|
mLogFileFP = nullptr;
|
||||||
Error("fclose(), error = %s", strerror(errno));
|
Error("fclose(), error = %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -416,7 +409,6 @@ void Logger::closeFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::closeDatabase() {
|
void Logger::closeDatabase() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::openSyslog() {
|
void Logger::openSyslog() {
|
||||||
|
@ -428,12 +420,12 @@ void Logger::closeSyslog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::logPrint(bool hex, const char * const filepath, const int line, const int level, const char *fstring, ...) {
|
void Logger::logPrint(bool hex, const char * const filepath, const int line, const int level, const char *fstring, ...) {
|
||||||
|
if (level > mEffectiveLevel) return;
|
||||||
if ( level > mEffectiveLevel ) {
|
if (level < PANIC || level > DEBUG9)
|
||||||
return;
|
Panic("Invalid logger level %d", level);
|
||||||
}
|
|
||||||
|
|
||||||
log_mutex.lock();
|
log_mutex.lock();
|
||||||
|
// Can we save some cycles by having these as members and not allocate them on the fly? I think so.
|
||||||
char timeString[64];
|
char timeString[64];
|
||||||
char logString[8192];
|
char logString[8192];
|
||||||
va_list argPtr;
|
va_list argPtr;
|
||||||
|
@ -443,9 +435,6 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con
|
||||||
const char *file = base ? base+1 : filepath;
|
const char *file = base ? base+1 : filepath;
|
||||||
const char *classString = smCodes[level].c_str();
|
const char *classString = smCodes[level].c_str();
|
||||||
|
|
||||||
if ( level < PANIC || level > DEBUG9 )
|
|
||||||
Panic("Invalid logger level %d", level);
|
|
||||||
|
|
||||||
gettimeofday(&timeVal, nullptr);
|
gettimeofday(&timeVal, nullptr);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -474,12 +463,12 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_SYSCALL
|
#ifdef HAVE_SYSCALL
|
||||||
#ifdef __FreeBSD_kernel__
|
#ifdef __FreeBSD_kernel__
|
||||||
if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id
|
if ((syscall(SYS_thr_self, &tid)) < 0) // Thread/Process id
|
||||||
|
|
||||||
# else
|
# else
|
||||||
// SOLARIS doesn't have SYS_gettid; don't assume
|
// SOLARIS doesn't have SYS_gettid; don't assume
|
||||||
#ifdef SYS_gettid
|
#ifdef SYS_gettid
|
||||||
if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id
|
if ((tid = syscall(SYS_gettid)) < 0) // Thread/Process id
|
||||||
#endif // SYS_gettid
|
#endif // SYS_gettid
|
||||||
#endif
|
#endif
|
||||||
#endif // HAVE_SYSCALL
|
#endif // HAVE_SYSCALL
|
||||||
|
@ -513,61 +502,63 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con
|
||||||
char *syslogEnd = logPtr;
|
char *syslogEnd = logPtr;
|
||||||
strncpy(logPtr, "]\n", sizeof(logString)-(logPtr-logString));
|
strncpy(logPtr, "]\n", sizeof(logString)-(logPtr-logString));
|
||||||
|
|
||||||
if ( level <= mTerminalLevel ) {
|
if (level <= mTerminalLevel) {
|
||||||
puts(logString);
|
puts(logString);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( level <= mFileLevel ) {
|
if (level <= mFileLevel) {
|
||||||
if ( !mLogFileFP ) {
|
if (!mLogFileFP) {
|
||||||
// We do this here so that we only create the file if we ever write to it.
|
// FIXME unlocking here is a problem. Another thread could sneak in.
|
||||||
log_mutex.unlock();
|
log_mutex.unlock();
|
||||||
|
// We do this here so that we only create the file if we ever write to it.
|
||||||
openFile();
|
openFile();
|
||||||
log_mutex.lock();
|
log_mutex.lock();
|
||||||
}
|
}
|
||||||
if ( mLogFileFP ) {
|
if (mLogFileFP) {
|
||||||
fputs(logString, mLogFileFP);
|
fputs(logString, mLogFileFP);
|
||||||
if ( mFlush )
|
if (mFlush) fflush(mLogFileFP);
|
||||||
fflush(mLogFileFP);
|
|
||||||
} else {
|
} else {
|
||||||
puts("Logging to file, but failed to open it\n");
|
puts("Logging to file, but failed to open it\n");
|
||||||
}
|
}
|
||||||
} // end if level <= mFileLevel
|
} // end if level <= mFileLevel
|
||||||
|
|
||||||
if ( level <= mDatabaseLevel ) {
|
if (level <= mDatabaseLevel) {
|
||||||
int syslogSize = syslogEnd-syslogStart;
|
if (zmDbConnected) {
|
||||||
char escapedString[(syslogSize*2)+1];
|
int syslogSize = syslogEnd-syslogStart;
|
||||||
mysql_real_escape_string(&dbconn, escapedString, syslogStart, syslogSize);
|
char escapedString[(syslogSize*2)+1];
|
||||||
|
mysql_real_escape_string(&dbconn, escapedString, syslogStart, syslogSize);
|
||||||
|
|
||||||
std::string sql_string = stringtf(
|
std::string sql_string = stringtf(
|
||||||
"INSERT INTO `Logs` "
|
"INSERT INTO `Logs` "
|
||||||
"( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` )"
|
"( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` )"
|
||||||
" VALUES "
|
" VALUES "
|
||||||
"( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
|
"( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
|
||||||
timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line
|
timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line
|
||||||
);
|
);
|
||||||
dbQueue.push(sql_string);
|
dbQueue.push(sql_string);
|
||||||
|
} else {
|
||||||
|
puts("Db is closed");
|
||||||
|
}
|
||||||
} // end if level <= mDatabaseLevel
|
} // end if level <= mDatabaseLevel
|
||||||
|
|
||||||
if ( level <= mSyslogLevel ) {
|
if (level <= mSyslogLevel) {
|
||||||
*syslogEnd = '\0';
|
*syslogEnd = '\0';
|
||||||
syslog(smSyslogPriorities[level], "%s [%s] [%s]", classString, mId.c_str(), syslogStart);
|
syslog(smSyslogPriorities[level], "%s [%s] [%s]", classString, mId.c_str(), syslogStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_mutex.unlock();
|
log_mutex.unlock();
|
||||||
if ( level <= FATAL ) {
|
if (level <= FATAL) {
|
||||||
logTerm();
|
logTerm();
|
||||||
zmDbClose();
|
zmDbClose();
|
||||||
if ( level <= PANIC )
|
if (level <= PANIC) abort();
|
||||||
abort();
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
} // end logPrint
|
} // end logPrint
|
||||||
|
|
||||||
void logInit(const char *name, const Logger::Options &options) {
|
void logInit(const char *name, const Logger::Options &options) {
|
||||||
if ( Logger::smInstance ) {
|
if (Logger::smInstance) {
|
||||||
delete Logger::smInstance;
|
delete Logger::smInstance;
|
||||||
Logger::smInstance = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::smInstance = new Logger();
|
Logger::smInstance = new Logger();
|
||||||
|
@ -575,7 +566,7 @@ void logInit(const char *name, const Logger::Options &options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void logTerm() {
|
void logTerm() {
|
||||||
if ( Logger::smInstance ) {
|
if (Logger::smInstance) {
|
||||||
delete Logger::smInstance;
|
delete Logger::smInstance;
|
||||||
Logger::smInstance = nullptr;
|
Logger::smInstance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,18 +153,12 @@ public:
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
const std::string &id(const std::string &id);
|
const std::string &id(const std::string &id);
|
||||||
const std::string &id() const {
|
const std::string &id() const { return mId; }
|
||||||
return mId;
|
|
||||||
}
|
|
||||||
|
|
||||||
Level level() const {
|
Level level() const { return mLevel; }
|
||||||
return mLevel;
|
|
||||||
}
|
|
||||||
Level level(Level=NOOPT);
|
Level level(Level=NOOPT);
|
||||||
|
|
||||||
bool debugOn() const {
|
bool debugOn() const { return mEffectiveLevel >= DEBUG1; }
|
||||||
return mEffectiveLevel >= DEBUG1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Level terminalLevel(Level=NOOPT);
|
Level terminalLevel(Level=NOOPT);
|
||||||
Level databaseLevel(Level=NOOPT);
|
Level databaseLevel(Level=NOOPT);
|
||||||
|
|
|
@ -1692,7 +1692,6 @@ void Monitor::UpdateCaptureFPS() {
|
||||||
last_fps_time = now_double;
|
last_fps_time = now_double;
|
||||||
last_capture_image_count = image_count;
|
last_capture_image_count = image_count;
|
||||||
|
|
||||||
db_mutex.lock();
|
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
// The reason we update the Status as well is because if mysql restarts, the Monitor_Status table is lost,
|
// The reason we update the Status as well is because if mysql restarts, the Monitor_Status table is lost,
|
||||||
// and nothing else will update the status until zmc restarts. Since we are successfully capturing we can
|
// and nothing else will update the status until zmc restarts. Since we are successfully capturing we can
|
||||||
|
@ -1702,9 +1701,7 @@ void Monitor::UpdateCaptureFPS() {
|
||||||
"VALUES (%d, %.2lf, %u, 'Connected') ON DUPLICATE KEY UPDATE "
|
"VALUES (%d, %.2lf, %u, 'Connected') ON DUPLICATE KEY UPDATE "
|
||||||
"CaptureFPS = %.2lf, CaptureBandwidth=%u, Status='Connected'",
|
"CaptureFPS = %.2lf, CaptureBandwidth=%u, Status='Connected'",
|
||||||
id, new_capture_fps, new_capture_bandwidth, new_capture_fps, new_capture_bandwidth);
|
id, new_capture_fps, new_capture_bandwidth, new_capture_fps, new_capture_bandwidth);
|
||||||
int rc = mysql_query(&dbconn, sql);
|
dbQueue.push(sql);
|
||||||
db_mutex.unlock();
|
|
||||||
if ( rc ) Error("Can't run query: %s", mysql_error(&dbconn));
|
|
||||||
} // now != last_fps_time
|
} // now != last_fps_time
|
||||||
} // end if report fps
|
} // end if report fps
|
||||||
} // void Monitor::UpdateCaptureFPS()
|
} // void Monitor::UpdateCaptureFPS()
|
||||||
|
@ -1745,10 +1742,7 @@ void Monitor::UpdateAnalysisFPS() {
|
||||||
"INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf)"
|
"INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf)"
|
||||||
" ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf",
|
" ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf",
|
||||||
id, new_analysis_fps, new_analysis_fps);
|
id, new_analysis_fps, new_analysis_fps);
|
||||||
db_mutex.lock();
|
dbQueue.push(sql);
|
||||||
int rc = mysql_query(&dbconn, sql);
|
|
||||||
db_mutex.unlock();
|
|
||||||
if ( rc ) Error("Can't run query: %s", mysql_error(&dbconn));
|
|
||||||
last_analysis_fps_time = now_double;
|
last_analysis_fps_time = now_double;
|
||||||
last_motion_frame_count = motion_frame_count;
|
last_motion_frame_count = motion_frame_count;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2324,7 +2318,7 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
||||||
for ( int i = 0; i < n_link_ids; i++ ) {
|
for ( int i = 0; i < n_link_ids; i++ ) {
|
||||||
Debug(1, "Checking linked monitor %d", link_ids[i]);
|
Debug(1, "Checking linked monitor %d", link_ids[i]);
|
||||||
|
|
||||||
db_mutex.lock();
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT `Id`, `Name` FROM `Monitors`"
|
"SELECT `Id`, `Name` FROM `Monitors`"
|
||||||
|
@ -2333,14 +2327,12 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
||||||
" AND `Function` != 'Monitor'"
|
" AND `Function` != 'Monitor'"
|
||||||
" AND `Enabled`=1",
|
" AND `Enabled`=1",
|
||||||
link_ids[i]);
|
link_ids[i]);
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if (mysql_query(&dbconn, sql)) {
|
||||||
db_mutex.unlock();
|
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||||
db_mutex.unlock();
|
|
||||||
if ( !result ) {
|
if ( !result ) {
|
||||||
Error("Can't use query result: %s", mysql_error(&dbconn));
|
Error("Can't use query result: %s", mysql_error(&dbconn));
|
||||||
continue;
|
continue;
|
||||||
|
@ -2354,11 +2346,11 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
||||||
Warning("Can't link to monitor %d, invalid id, function or not enabled", link_ids[i]);
|
Warning("Can't link to monitor %d, invalid id, function or not enabled", link_ids[i]);
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
} // end foreach link_id
|
} // end foreach link_id
|
||||||
n_linked_monitors = count;
|
n_linked_monitors = count;
|
||||||
} // end if has link_ids
|
} // end if has link_ids
|
||||||
} // end if p_linked_monitors
|
} // end if p_linked_monitors
|
||||||
} // end void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors)
|
} // end void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors)
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Monitor>> Monitor::LoadMonitors(std::string sql, Purpose purpose) {
|
std::vector<std::shared_ptr<Monitor>> Monitor::LoadMonitors(std::string sql, Purpose purpose) {
|
||||||
Debug(1, "Loading Monitors with %s", sql.c_str());
|
Debug(1, "Loading Monitors with %s", sql.c_str());
|
||||||
|
|
|
@ -134,16 +134,11 @@ Zone::~Zone() {
|
||||||
|
|
||||||
void Zone::RecordStats(const Event *event) {
|
void Zone::RecordStats(const Event *event) {
|
||||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
db_mutex.lock();
|
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"INSERT INTO Stats SET MonitorId=%d, ZoneId=%d, EventId=%" PRIu64 ", FrameId=%d, PixelDiff=%d, AlarmPixels=%d, FilterPixels=%d, BlobPixels=%d, Blobs=%d, MinBlobSize=%d, MaxBlobSize=%d, MinX=%d, MinY=%d, MaxX=%d, MaxY=%d, Score=%d",
|
"INSERT INTO Stats SET MonitorId=%d, ZoneId=%d, EventId=%" PRIu64 ", FrameId=%d, PixelDiff=%d, AlarmPixels=%d, FilterPixels=%d, BlobPixels=%d, Blobs=%d, MinBlobSize=%d, MaxBlobSize=%d, MinX=%d, MinY=%d, MaxX=%d, MaxY=%d, Score=%d",
|
||||||
monitor->Id(), id, event->Id(), event->Frames(), pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, min_blob_size, max_blob_size, alarm_box.LoX(), alarm_box.LoY(), alarm_box.HiX(), alarm_box.HiY(), score
|
monitor->Id(), id, event->Id(), event->Frames(), pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, min_blob_size, max_blob_size, alarm_box.LoX(), alarm_box.LoY(), alarm_box.HiX(), alarm_box.HiY(), score
|
||||||
);
|
);
|
||||||
int rc = mysql_query(&dbconn, sql);
|
zmDbDo(sql);
|
||||||
db_mutex.unlock();
|
|
||||||
if ( rc ) {
|
|
||||||
Error("Can't insert event stats: %s", mysql_error(&dbconn));
|
|
||||||
}
|
|
||||||
} // end void Zone::RecordStats( const Event *event )
|
} // end void Zone::RecordStats( const Event *event )
|
||||||
|
|
||||||
bool Zone::CheckOverloadCount() {
|
bool Zone::CheckOverloadCount() {
|
||||||
|
@ -824,23 +819,24 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
|
||||||
|
|
||||||
int Zone::Load(Monitor *monitor, Zone **&zones) {
|
int Zone::Load(Monitor *monitor, Zone **&zones) {
|
||||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
|
MYSQL_RES *result;
|
||||||
|
|
||||||
db_mutex.lock();
|
{ // scope for lock
|
||||||
snprintf(sql, sizeof(sql), "SELECT Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,"
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
"MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,"
|
snprintf(sql, sizeof(sql), "SELECT Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,"
|
||||||
"FilterX,FilterY,MinFilterPixels,MaxFilterPixels,"
|
"MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,"
|
||||||
"MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,"
|
"FilterX,FilterY,MinFilterPixels,MaxFilterPixels,"
|
||||||
"OverloadFrames,ExtendAlarmFrames"
|
"MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,"
|
||||||
" FROM Zones WHERE MonitorId = %d ORDER BY Type, Id", monitor->Id());
|
"OverloadFrames,ExtendAlarmFrames"
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
" FROM Zones WHERE MonitorId = %d ORDER BY Type, Id", monitor->Id());
|
||||||
db_mutex.unlock();
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mysql_store_result(&dbconn);
|
||||||
}
|
}
|
||||||
|
if (!result) {
|
||||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
|
||||||
db_mutex.unlock();
|
|
||||||
if ( !result ) {
|
|
||||||
Error("Can't use query result: %s", mysql_error(&dbconn));
|
Error("Can't use query result: %s", mysql_error(&dbconn));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -848,7 +844,7 @@ int Zone::Load(Monitor *monitor, Zone **&zones) {
|
||||||
Debug(1, "Got %d zones for monitor %s", n_zones, monitor->Name());
|
Debug(1, "Got %d zones for monitor %s", n_zones, monitor->Name());
|
||||||
delete[] zones;
|
delete[] zones;
|
||||||
zones = new Zone *[n_zones];
|
zones = new Zone *[n_zones];
|
||||||
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) {
|
for(int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++) {
|
||||||
int col = 0;
|
int col = 0;
|
||||||
|
|
||||||
int Id = atoi(dbrow[col++]);
|
int Id = atoi(dbrow[col++]);
|
||||||
|
|
|
@ -266,6 +266,7 @@ int main(int argc, char *argv[]) {
|
||||||
monitor->Id());
|
monitor->Id());
|
||||||
zmDbDo(sql);
|
zmDbDo(sql);
|
||||||
} // end foreach monitor
|
} // end foreach monitor
|
||||||
|
if (zm_terminate) break;
|
||||||
|
|
||||||
#if HAVE_RTSP_SERVER
|
#if HAVE_RTSP_SERVER
|
||||||
RTSPServerThread ** rtsp_server_threads = nullptr;
|
RTSPServerThread ** rtsp_server_threads = nullptr;
|
||||||
|
@ -418,9 +419,7 @@ int main(int argc, char *argv[]) {
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='NotRunning'",
|
"INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='NotRunning'",
|
||||||
monitor->Id());
|
monitor->Id());
|
||||||
if (mysql_query(&dbconn, sql)) {
|
zmDbDo(sql);
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Deinitialise();
|
Image::Deinitialise();
|
||||||
|
|
Loading…
Reference in New Issue