|
MythTV 0.25-pre
|
00001 #include <QMutex> 00002 #include <QMutexLocker> 00003 #include <QList> 00004 #include <QQueue> 00005 #include <QThread> 00006 #include <QHash> 00007 #include <QCoreApplication> 00008 00009 #define _LogLevelNames_ 00010 #include "mythlogging.h" 00011 #include "mythverbose.h" 00012 #include "mythconfig.h" 00013 #include "mythdb.h" 00014 #include "mythcorecontext.h" 00015 #include "dbutil.h" 00016 00017 #include <stdlib.h> 00018 #define SYSLOG_NAMES 00019 #include <syslog.h> 00020 #include <stdarg.h> 00021 #include <string.h> 00022 #include <sys/stat.h> 00023 #include <sys/types.h> 00024 #include <fcntl.h> 00025 #include <stdio.h> 00026 #include <unistd.h> 00027 #if HAVE_GETTIMEOFDAY 00028 #include <sys/time.h> 00029 #endif 00030 #include <signal.h> 00031 00032 // Various ways to get to thread's tid 00033 #if defined(linux) 00034 #include <sys/syscall.h> 00035 #elif defined(__FreeBSD__) 00036 #include <sys/ucontext.h> 00037 #include <sys/thr.h> 00038 #elif CONFIG_DARWIN 00039 #include <mach/mach.h> 00040 #endif 00041 00042 QMutex loggerListMutex; 00043 QList<LoggerBase *> loggerList; 00044 00045 QMutex logQueueMutex; 00046 QQueue<LoggingItem_t *> logQueue; 00047 00048 QMutex logThreadMutex; 00049 QHash<uint64_t, char *> logThreadHash; 00050 00051 QMutex logThreadTidMutex; 00052 QHash<uint64_t, int64_t> logThreadTidHash; 00053 00054 LoggerThread logThread; 00055 bool debugRegistration = false; 00056 00057 #define TIMESTAMP_MAX 30 00058 #define MAX_STRING_LENGTH 2048 00059 00060 LogLevel_t LogLevel = LOG_UNKNOWN; 00064 char *getThreadName( LoggingItem_t *item ); 00065 int64_t getThreadTid( LoggingItem_t *item ); 00066 void setThreadTid( LoggingItem_t *item ); 00067 void deleteItem( LoggingItem_t *item ); 00068 void logSighup( int signum, siginfo_t *info, void *secret ); 00069 00070 LoggerBase::LoggerBase(char *string, int number) 00071 { 00072 QMutexLocker locker(&loggerListMutex); 00073 if (string) 00074 { 00075 m_handle.string = strdup(string); 00076 m_string = true; 00077 } 00078 else 00079 { 00080 m_handle.number = number; 00081 m_string = false; 00082 } 00083 loggerList.append(this); 00084 } 00085 00086 LoggerBase::~LoggerBase() 00087 { 00088 QMutexLocker locker(&loggerListMutex); 00089 00090 QList<LoggerBase *>::iterator it; 00091 00092 for(it = loggerList.begin(); it != loggerList.end(); it++) 00093 { 00094 if( *it == this ) 00095 { 00096 loggerList.erase(it); 00097 break; 00098 } 00099 } 00100 00101 if (m_string) 00102 free(m_handle.string); 00103 } 00104 00105 00106 FileLogger::FileLogger(char *filename) : LoggerBase(filename, 0), 00107 m_opened(false), m_fd(-1) 00108 { 00109 if( !strcmp(filename, "-") ) 00110 { 00111 m_opened = true; 00112 m_fd = 1; 00113 LogPrint( VB_IMPORTANT, LOG_INFO, "Added logging to the console" ); 00114 } 00115 else 00116 { 00117 m_fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0664); 00118 m_opened = (m_fd != -1); 00119 LogPrint( VB_IMPORTANT, LOG_INFO, "Added logging to %s", filename ); 00120 } 00121 } 00122 00123 FileLogger::~FileLogger() 00124 { 00125 if( m_opened ) 00126 { 00127 if( m_fd != 1 ) 00128 { 00129 LogPrint( VB_IMPORTANT, LOG_INFO, "Removed logging to %s", 00130 m_handle.string ); 00131 close( m_fd ); 00132 } 00133 else 00134 LogPrint( VB_IMPORTANT, LOG_INFO, 00135 "Removed logging to the console" ); 00136 } 00137 } 00138 00139 void FileLogger::reopen(void) 00140 { 00141 char *filename = m_handle.string; 00142 00143 // Skip console 00144 if( !strcmp(filename, "-") ) 00145 return; 00146 00147 close(m_fd); 00148 00149 m_fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0664); 00150 m_opened = (m_fd != -1); 00151 LogPrint( VB_IMPORTANT, LOG_INFO, "Rolled logging on %s", filename ); 00152 } 00153 00154 bool FileLogger::logmsg(LoggingItem_t *item) 00155 { 00156 char line[MAX_STRING_LENGTH]; 00157 char usPart[9]; 00158 char timestamp[TIMESTAMP_MAX]; 00159 int length; 00160 char *threadName = NULL; 00161 pid_t pid = getpid(); 00162 pid_t tid = 0; 00163 00164 if (!m_opened) 00165 return false; 00166 00167 strftime( timestamp, TIMESTAMP_MAX-8, "%Y-%m-%d %H:%M:%S", 00168 (const struct tm *)&item->tm ); 00169 snprintf( usPart, 9, ".%06d", (int)(item->usec) ); 00170 strcat( timestamp, usPart ); 00171 length = strlen( timestamp ); 00172 00173 if (m_fd == 1) 00174 { 00175 // Stdout 00176 snprintf( line, MAX_STRING_LENGTH, "%s %c %s\n", timestamp, 00177 LogLevelShortNames[item->level], item->message ); 00178 } 00179 else 00180 { 00181 threadName = getThreadName(item); 00182 tid = getThreadTid(item); 00183 00184 if( tid ) 00185 snprintf( line, MAX_STRING_LENGTH, 00186 "%s %c [%d/%d] %s %s:%d (%s) - %s\n", 00187 timestamp, LogLevelShortNames[item->level], pid, tid, 00188 threadName, item->file, item->line, item->function, 00189 item->message ); 00190 else 00191 snprintf( line, MAX_STRING_LENGTH, 00192 "%s %c [%d] %s %s:%d (%s) - %s\n", 00193 timestamp, LogLevelShortNames[item->level], pid, 00194 threadName, item->file, item->line, item->function, 00195 item->message ); 00196 } 00197 00198 int result = write( m_fd, line, strlen(line) ); 00199 00200 { 00201 QMutexLocker locker((QMutex *)item->refmutex); 00202 item->refcount--; 00203 } 00204 00205 if( result == -1 ) 00206 { 00207 LogPrint( VB_IMPORTANT, LOG_UNKNOWN, 00208 "Closed Log output on fd %d due to errors", m_fd ); 00209 m_opened = false; 00210 if( m_fd != 1 ) 00211 close( m_fd ); 00212 return false; 00213 } 00214 return true; 00215 } 00216 00217 00218 SyslogLogger::SyslogLogger(int facility) : LoggerBase(NULL, facility), 00219 m_opened(false) 00220 { 00221 CODE *name; 00222 00223 m_application = strdup((char *)QCoreApplication::applicationName() 00224 .toLocal8Bit().constData()); 00225 00226 openlog( m_application, LOG_NDELAY | LOG_PID, facility ); 00227 m_opened = true; 00228 00229 for( name = &facilitynames[0]; 00230 name->c_name && name->c_val != facility; name++ ); 00231 00232 LogPrint(VB_IMPORTANT, LOG_INFO, "Added syslogging to facility %s", 00233 name->c_name); 00234 } 00235 00236 SyslogLogger::~SyslogLogger() 00237 { 00238 LogPrint(VB_IMPORTANT, LOG_INFO, "Removing syslogging"); 00239 free(m_application); 00240 closelog(); 00241 } 00242 00243 bool SyslogLogger::logmsg(LoggingItem_t *item) 00244 { 00245 if (!m_opened) 00246 return false; 00247 00248 syslog( item->level, "%s", item->message ); 00249 00250 { 00251 QMutexLocker locker((QMutex *)item->refmutex); 00252 item->refcount--; 00253 } 00254 00255 return true; 00256 } 00257 00258 00259 DatabaseLogger::DatabaseLogger(char *table) : LoggerBase(table, 0), 00260 m_host(NULL), m_opened(false), 00261 m_loggingTableExists(false) 00262 { 00263 static const char *queryFmt = 00264 "INSERT INTO %s (host, application, pid, thread, " 00265 "msgtime, level, message) VALUES (:HOST, :APPLICATION, " 00266 ":PID, :THREAD, :MSGTIME, :LEVEL, :MESSAGE)"; 00267 00268 LogPrint(VB_IMPORTANT, LOG_INFO, "Added database logging to table %s", 00269 m_handle.string); 00270 00271 if (gCoreContext && !gCoreContext->GetHostName().isEmpty()) 00272 m_host = strdup((char *)gCoreContext->GetHostName() 00273 .toLocal8Bit().constData()); 00274 00275 m_application = strdup((char *)QCoreApplication::applicationName() 00276 .toLocal8Bit().constData()); 00277 m_pid = getpid(); 00278 00279 m_query = (char *)malloc(strlen(queryFmt) + strlen(m_handle.string)); 00280 sprintf(m_query, queryFmt, m_handle.string); 00281 00282 m_thread = new DBLoggerThread(this); 00283 m_thread->start(); 00284 00285 m_opened = true; 00286 } 00287 00288 DatabaseLogger::~DatabaseLogger() 00289 { 00290 LogPrint(VB_IMPORTANT, LOG_INFO, "Removing database logging"); 00291 00292 if( m_thread ) 00293 { 00294 m_thread->stop(); 00295 m_thread->wait(); 00296 delete m_thread; 00297 } 00298 00299 if( m_query ) 00300 free(m_query); 00301 if( m_application ) 00302 free(m_application); 00303 if( m_host ) 00304 free(m_host); 00305 } 00306 00307 bool DatabaseLogger::logmsg(LoggingItem_t *item) 00308 { 00309 if( m_thread ) 00310 m_thread->enqueue(item); 00311 return true; 00312 } 00313 00314 bool DatabaseLogger::logqmsg(LoggingItem_t *item) 00315 { 00316 char timestamp[TIMESTAMP_MAX]; 00317 char *threadName = getThreadName(item);; 00318 00319 if( !isDatabaseReady() ) 00320 return false; 00321 00322 strftime( timestamp, TIMESTAMP_MAX-8, "%Y-%m-%d %H:%M:%S", 00323 (const struct tm *)&item->tm ); 00324 00325 if( gCoreContext && !m_host ) 00326 m_host = strdup((char *)gCoreContext->GetHostName() 00327 .toLocal8Bit().constData()); 00328 00329 MSqlQuery query(MSqlQuery::InitCon()); 00330 query.prepare( m_query ); 00331 query.bindValue(":HOST", m_host); 00332 query.bindValue(":APPLICATION", m_application); 00333 query.bindValue(":PID", m_pid); 00334 query.bindValue(":THREAD", threadName); 00335 query.bindValue(":MSGTIME", timestamp); 00336 query.bindValue(":LEVEL", item->level); 00337 query.bindValue(":MESSAGE", item->message); 00338 00339 { 00340 QMutexLocker locker((QMutex *)item->refmutex); 00341 item->refcount--; 00342 } 00343 00344 if (!query.exec()) 00345 { 00346 MythDB::DBError("DBLogging", query); 00347 return false; 00348 } 00349 00350 return true; 00351 } 00352 00353 void DBLoggerThread::run(void) 00354 { 00355 threadRegister("DBLogger"); 00356 LoggingItem_t *item; 00357 00358 aborted = false; 00359 00360 QMutexLocker qLock(&m_queueMutex); 00361 00362 while(!aborted || !m_queue->isEmpty()) 00363 { 00364 if (m_queue->isEmpty()) 00365 { 00366 qLock.unlock(); 00367 msleep(100); 00368 qLock.relock(); 00369 continue; 00370 } 00371 00372 item = m_queue->dequeue(); 00373 if (!item) 00374 continue; 00375 00376 qLock.unlock(); 00377 00378 if( item->message && !aborted ) 00379 { 00380 m_logger->logqmsg(item); 00381 } 00382 00383 deleteItem(item); 00384 00385 qLock.relock(); 00386 } 00387 } 00388 00389 bool DatabaseLogger::isDatabaseReady() 00390 { 00391 bool ready = false; 00392 MythDB *db; 00393 00394 if ( !m_loggingTableExists ) 00395 m_loggingTableExists = DBUtil::TableExists(m_handle.string); 00396 00397 if ( m_loggingTableExists && (db = GetMythDB()) && db->HaveValidDatabase() ) 00398 ready = true; 00399 00400 return ready; 00401 } 00402 00403 char *getThreadName( LoggingItem_t *item ) 00404 { 00405 static const char *unknown = "thread_unknown"; 00406 char *threadName; 00407 00408 if( !item ) 00409 return( (char *)unknown ); 00410 00411 if( !item->threadName ) 00412 { 00413 QMutexLocker locker(&logThreadMutex); 00414 if( logThreadHash.contains(item->threadId) ) 00415 threadName = logThreadHash[item->threadId]; 00416 else 00417 threadName = (char *)unknown; 00418 } 00419 else 00420 { 00421 threadName = item->threadName; 00422 } 00423 00424 return( threadName ); 00425 } 00426 00427 int64_t getThreadTid( LoggingItem_t *item ) 00428 { 00429 pid_t tid = 0; 00430 00431 if( !item ) 00432 return( 0 ); 00433 00434 QMutexLocker locker(&logThreadTidMutex); 00435 if( logThreadTidHash.contains(item->threadId) ) 00436 tid = logThreadTidHash[item->threadId]; 00437 00438 return( tid ); 00439 } 00440 00441 void setThreadTid( LoggingItem_t *item ) 00442 { 00443 int64_t tid = 0; 00444 00445 QMutexLocker locker(&logThreadTidMutex); 00446 00447 if( ! logThreadTidHash.contains(item->threadId) ) 00448 { 00449 #if defined(linux) 00450 tid = (int64_t)syscall(SYS_gettid); 00451 #elif defined(__FreeBSD__) && 0 00452 long lwpid; 00453 int dummy = thr_self( &lwpid ); 00454 tid = (int64_t)lwpid; 00455 #elif CONFIG_DARWIN 00456 tid = (int64_t)mach_thread_self(); 00457 #endif 00458 logThreadTidHash[item->threadId] = tid; 00459 } 00460 } 00461 00462 00463 LoggerThread::LoggerThread() 00464 { 00465 char *debug = getenv("VERBOSE_THREADS"); 00466 if (debug != NULL) 00467 { 00468 VERBOSE(VB_IMPORTANT, "Logging thread registration/deregistration " 00469 "enabled!"); 00470 debugRegistration = true; 00471 } 00472 } 00473 00474 LoggerThread::~LoggerThread() 00475 { 00476 QMutexLocker locker(&loggerListMutex); 00477 00478 QList<LoggerBase *>::iterator it; 00479 00480 for(it = loggerList.begin(); it != loggerList.end(); it++) 00481 { 00482 (*it)->deleteLater(); 00483 } 00484 } 00485 00486 void LoggerThread::run(void) 00487 { 00488 threadRegister("Logger"); 00489 LoggingItem_t *item; 00490 00491 aborted = false; 00492 00493 QMutexLocker qLock(&logQueueMutex); 00494 00495 while(!aborted || !logQueue.isEmpty()) 00496 { 00497 if (logQueue.isEmpty()) 00498 { 00499 qLock.unlock(); 00500 msleep(100); 00501 qLock.relock(); 00502 continue; 00503 } 00504 00505 item = logQueue.dequeue(); 00506 if (!item) 00507 continue; 00508 00509 qLock.unlock(); 00510 00511 if (item->registering) 00512 { 00513 int64_t tid = getThreadTid(item); 00514 00515 QMutexLocker locker(&logThreadMutex); 00516 logThreadHash[item->threadId] = strdup(item->threadName); 00517 00518 if( debugRegistration ) 00519 { 00520 item->message = (char *)malloc(LOGLINE_MAX+1); 00521 if( item->message ) 00522 { 00523 snprintf( item->message, LOGLINE_MAX, 00524 "Thread 0x%llX (%lld) registered as \'%s\'", 00525 (long long unsigned int)item->threadId, 00526 (long long int)tid, 00527 logThreadHash[item->threadId] ); 00528 } 00529 } 00530 } 00531 else if (item->deregistering) 00532 { 00533 int64_t tid = 0; 00534 00535 { 00536 QMutexLocker locker(&logThreadTidMutex); 00537 if( logThreadTidHash.contains(item->threadId) ) 00538 { 00539 tid = logThreadTidHash[item->threadId]; 00540 logThreadTidHash.remove(item->threadId); 00541 } 00542 } 00543 00544 QMutexLocker locker(&logThreadMutex); 00545 if( logThreadHash.contains(item->threadId) ) 00546 { 00547 if( debugRegistration ) 00548 { 00549 item->message = (char *)malloc(LOGLINE_MAX+1); 00550 if( item->message ) 00551 { 00552 snprintf( item->message, LOGLINE_MAX, 00553 "Thread 0x%llX (%lld) deregistered as \'%s\'", 00554 (long long unsigned int)item->threadId, 00555 (long long int)tid, 00556 logThreadHash[item->threadId] ); 00557 } 00558 } 00559 item->threadName = logThreadHash[item->threadId]; 00560 logThreadHash.remove(item->threadId); 00561 } 00562 } 00563 00564 if( item->message ) 00565 { 00566 QMutexLocker locker(&loggerListMutex); 00567 00568 QList<LoggerBase *>::iterator it; 00569 00570 item->refcount = loggerList.size(); 00571 item->refmutex = new QMutex; 00572 00573 for(it = loggerList.begin(); it != loggerList.end(); it++) 00574 { 00575 (*it)->logmsg(item); 00576 } 00577 } 00578 00579 deleteItem(item); 00580 00581 qLock.relock(); 00582 } 00583 } 00584 00585 void deleteItem( LoggingItem_t *item ) 00586 { 00587 if( !item ) 00588 return; 00589 00590 { 00591 QMutexLocker locker((QMutex *)item->refmutex); 00592 if( item->refcount != 0 ) 00593 return; 00594 00595 if( item->message ) 00596 free(item->message); 00597 00598 if( item->threadName ) 00599 free( item->threadName ); 00600 } 00601 00602 delete (QMutex *)item->refmutex; 00603 delete item; 00604 } 00605 00606 void LogTimeStamp( time_t *epoch, uint32_t *usec ) 00607 { 00608 if( !epoch || !usec ) 00609 return; 00610 00611 #if HAVE_GETTIMEOFDAY 00612 struct timeval tv; 00613 gettimeofday(&tv, NULL); 00614 *epoch = tv.tv_sec; 00615 *usec = tv.tv_usec; 00616 #else 00617 /* Stupid system has no gettimeofday, use less precise QDateTime */ 00618 QDateTime date = QDateTime::currentDateTime(); 00619 QTime time = date.time(); 00620 *epoch = date.toTime_t(); 00621 *usec = time.msec() * 1000; 00622 #endif 00623 } 00624 00625 void LogPrintLine( uint32_t mask, LogLevel_t level, const char *file, int line, 00626 const char *function, const char *format, ... ) 00627 { 00628 va_list arguments; 00629 char *message; 00630 LoggingItem_t *item; 00631 time_t epoch; 00632 uint32_t usec; 00633 00634 if( !VERBOSE_LEVEL_CHECK(mask) ) 00635 return; 00636 00637 if( level > LogLevel ) 00638 return; 00639 00640 item = new LoggingItem_t; 00641 if (!item) 00642 return; 00643 00644 memset( item, 0, sizeof(LoggingItem_t) ); 00645 00646 message = (char *)malloc(LOGLINE_MAX+1); 00647 if( !message ) 00648 return; 00649 00650 va_start(arguments, format); 00651 vsnprintf(message, LOGLINE_MAX, format, arguments); 00652 va_end(arguments); 00653 00654 LogTimeStamp( &epoch, &usec ); 00655 00656 localtime_r(&epoch, &item->tm); 00657 item->usec = usec; 00658 00659 item->level = level; 00660 item->file = file; 00661 item->line = line; 00662 item->function = function; 00663 item->threadId = (uint64_t)QThread::currentThreadId(); 00664 item->message = message; 00665 setThreadTid(item); 00666 00667 QMutexLocker qLock(&logQueueMutex); 00668 logQueue.enqueue(item); 00669 } 00670 00671 void logSighup( int signum, siginfo_t *info, void *secret ) 00672 { 00673 VERBOSE(VB_GENERAL, "SIGHUP received, rolling log files."); 00674 00675 /* SIGHUP was sent. Close and reopen debug logfiles */ 00676 QMutexLocker locker(&loggerListMutex); 00677 00678 QList<LoggerBase *>::iterator it; 00679 for(it = loggerList.begin(); it != loggerList.end(); it++) 00680 { 00681 (*it)->reopen(); 00682 } 00683 } 00684 00685 00686 void logStart(QString logfile, int quiet, int facility, bool dblog) 00687 { 00688 LoggerBase *logger; 00689 struct sigaction sa; 00690 00691 if (logThread.isRunning()) 00692 return; 00693 00694 /* log to the console */ 00695 if( !quiet ) 00696 logger = new FileLogger((char *)"-"); 00697 00698 /* Debug logfile */ 00699 if( !logfile.isEmpty() ) 00700 logger = new FileLogger((char *)logfile.toLocal8Bit().constData()); 00701 00702 /* Syslog */ 00703 if( facility < 0 ) 00704 LogPrint(VB_IMPORTANT, LOG_CRIT, 00705 "Syslogging facility unknown, disabling syslog output"); 00706 else if( facility > 0 ) 00707 logger = new SyslogLogger(facility); 00708 00709 /* Database */ 00710 if( dblog ) 00711 logger = new DatabaseLogger((char *)"logging"); 00712 00713 /* Setup SIGHUP */ 00714 LogPrint(VB_IMPORTANT, LOG_CRIT, "Setting up SIGHUP handler"); 00715 sa.sa_sigaction = logSighup; 00716 sigemptyset( &sa.sa_mask ); 00717 sa.sa_flags = SA_RESTART | SA_SIGINFO; 00718 sigaction( SIGHUP, &sa, NULL ); 00719 00720 logThread.start(); 00721 } 00722 00723 void logStop(void) 00724 { 00725 struct sigaction sa; 00726 00727 logThread.stop(); 00728 logThread.wait(); 00729 00730 /* Tear down SIGHUP */ 00731 sa.sa_handler = SIG_DFL; 00732 sigemptyset( &sa.sa_mask ); 00733 sa.sa_flags = SA_RESTART; 00734 sigaction( SIGHUP, &sa, NULL ); 00735 00736 QMutexLocker locker(&loggerListMutex); 00737 QList<LoggerBase *>::iterator it; 00738 00739 for(it = loggerList.begin(); it != loggerList.end(); ) 00740 { 00741 locker.unlock(); 00742 delete *it; 00743 locker.relock(); 00744 it = loggerList.begin(); 00745 } 00746 } 00747 00748 void threadRegister(QString name) 00749 { 00750 uint64_t id = (uint64_t)QThread::currentThreadId(); 00751 LoggingItem_t *item; 00752 time_t epoch; 00753 uint32_t usec; 00754 00755 item = new LoggingItem_t; 00756 if (!item) 00757 return; 00758 00759 memset( item, 0, sizeof(LoggingItem_t) ); 00760 LogTimeStamp( &epoch, &usec ); 00761 00762 localtime_r(&epoch, &item->tm); 00763 item->usec = usec; 00764 00765 item->level = (LogLevel_t)LOG_DEBUG; 00766 item->threadId = id; 00767 item->line = __LINE__; 00768 item->file = (char *)__FILE__; 00769 item->function = (char *)__FUNCTION__; 00770 item->threadName = strdup((char *)name.toLocal8Bit().constData()); 00771 item->registering = true; 00772 setThreadTid(item); 00773 00774 QMutexLocker qLock(&logQueueMutex); 00775 logQueue.enqueue(item); 00776 } 00777 00778 void threadDeregister(void) 00779 { 00780 uint64_t id = (uint64_t)QThread::currentThreadId(); 00781 LoggingItem_t *item; 00782 time_t epoch; 00783 uint32_t usec; 00784 00785 item = new LoggingItem_t; 00786 if (!item) 00787 return; 00788 00789 memset( item, 0, sizeof(LoggingItem_t) ); 00790 LogTimeStamp( &epoch, &usec ); 00791 00792 localtime_r(&epoch, &item->tm); 00793 item->usec = usec; 00794 00795 item->level = (LogLevel_t)LOG_DEBUG; 00796 item->threadId = id; 00797 item->line = __LINE__; 00798 item->file = (char *)__FILE__; 00799 item->function = (char *)__FUNCTION__; 00800 item->deregistering = true; 00801 00802 QMutexLocker qLock(&logQueueMutex); 00803 logQueue.enqueue(item); 00804 } 00805 00806 int syslogGetFacility(QString facility) 00807 { 00808 CODE *name; 00809 int i; 00810 char *string = (char *)facility.toLocal8Bit().constData(); 00811 00812 for( i = 0, name = &facilitynames[0]; 00813 name->c_name && strcmp(name->c_name, string); i++, name++ ); 00814 00815 return( name->c_val ); 00816 } 00817 00818 /* 00819 * vim:ts=4:sw=4:ai:et:si:sts=4 00820 */
1.7.4