Changeset 90829 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Aug 24, 2021 10:26:07 AM (3 years ago)
- Location:
- trunk/src/VBox/Runtime/common/log
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/log/log.cpp
r90803 r90829 34 34 #ifndef IN_RC 35 35 # include <iprt/alloc.h> 36 # include <iprt/crc.h> 36 37 # include <iprt/process.h> 37 38 # include <iprt/semaphore.h> … … 89 90 AssertCompile(sizeof(RTLOG_RINGBUF_EYE_CATCHER_END) == 16); 90 91 92 /** The default buffer size. */ 93 #define RTLOG_BUFFER_DEFAULT_SIZE _64K 94 /** Buffer alignment used RTLogCreateExV. */ 95 #define RTLOG_BUFFER_ALIGN 64 96 91 97 92 98 /********************************************************************************************************************************* … … 94 100 *********************************************************************************************************************************/ 95 101 /** 96 * Arguments passed to the output function.97 */98 typedef struct RTLOGOUTPUTPREFIXEDARGS99 {100 /** The logger instance. */101 PRTLOGGER pLogger;102 /** The flags. (used for prefixing.) */103 unsigned fFlags;104 /** The group. (used for prefixing.) */105 unsigned iGroup;106 } RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS;107 108 #ifndef IN_RC109 110 /**111 102 * Internal logger data. 112 103 * … … 115 106 typedef struct RTLOGGERINTERNAL 116 107 { 108 /** The public logger core. */ 109 RTLOGGER Core; 110 117 111 /** The structure revision (RTLOGGERINTERNAL_REV). */ 118 112 uint32_t uRevision; 119 113 /** The size of the internal logger structure. */ 120 114 uint32_t cbSelf; 115 116 /** Logger instance flags - RTLOGFLAGS. */ 117 uint64_t fFlags; 118 /** Destination flags - RTLOGDEST. */ 119 uint32_t fDestFlags; 120 121 /** Number of buffer descriptors. */ 122 uint8_t cBufDescs; 123 /** Index of the current buffer descriptor. */ 124 uint8_t idxBufDesc; 125 /** Pointer to buffer the descriptors. */ 126 PRTLOGBUFFERDESC paBufDescs; 127 /** Pointer to the current buffer the descriptor. */ 128 PRTLOGBUFFERDESC pBufDesc; 121 129 122 130 /** Spinning mutex semaphore. Can be NIL. */ … … 181 189 char szR0ThreadName[16]; 182 190 183 # ifdef IN_RING3 /* Note! Must be at the end!*/191 #ifdef IN_RING3 /* Note! Must be at the end! */ /** @todo r=bird: figure out why it must be at the end... */ 184 192 /** @name File logging bits for the logger. 185 193 * @{ */ … … 205 213 char szFilename[RTPATH_MAX]; 206 214 /** @} */ 207 # endif /* IN_RING3 */ 215 #endif /* IN_RING3 */ 216 217 /** Number of groups in the afGroups and papszGroups members. */ 218 uint32_t cGroups; 219 /** Group flags array - RTLOGGRPFLAGS. 220 * This member have variable length and may extend way beyond 221 * the declared size of 1 entry. */ 222 RT_FLEXIBLE_ARRAY_EXTENSION 223 uint32_t afGroups[RT_FLEXIBLE_ARRAY]; 208 224 } RTLOGGERINTERNAL; 209 225 210 226 /** The revision of the internal logger structure. */ 211 # define RTLOGGERINTERNAL_REV UINT32_C(11) 212 213 # ifdef IN_RING3 227 # define RTLOGGERINTERNAL_REV UINT32_C(12) 228 229 AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t)); 230 #ifdef IN_RING3 214 231 /** The size of the RTLOGGERINTERNAL structure in ring-0. */ 215 # 232 # define RTLOGGERINTERNAL_R0_SIZE RT_UOFFSETOF(RTLOGGERINTERNAL, pfnPhase) 216 233 AssertCompileMemberAlignment(RTLOGGERINTERNAL, hFile, sizeof(void *)); 217 234 AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbHistoryFileMax, sizeof(uint64_t)); 218 # endif 219 AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t)); 220 221 #endif /* !IN_RC */ 235 #endif 236 237 238 /** Pointer to internal logger bits. */ 239 typedef struct RTLOGGERINTERNAL *PRTLOGGERINTERNAL; 240 /** 241 * Arguments passed to the output function. 242 */ 243 typedef struct RTLOGOUTPUTPREFIXEDARGS 244 { 245 /** The logger instance. */ 246 PRTLOGGERINTERNAL pLoggerInt; 247 /** The flags. (used for prefixing.) */ 248 unsigned fFlags; 249 /** The group. (used for prefixing.) */ 250 unsigned iGroup; 251 } RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS; 222 252 223 253 … … 233 263 #endif 234 264 #ifdef IN_RING3 235 static int rtR3LogOpenFileDestination(PRTLOGGER pLogger, PRTERRINFO pErrInfo);265 static int rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo); 236 266 #endif 237 267 #ifndef IN_RC 238 static void rtLogRingBufFlush(PRTLOGGER pLogger);268 static void rtLogRingBufFlush(PRTLOGGERINTERNAL pLoggerInt); 239 269 #endif 240 static void rtlogFlush(PRTLOGGER pLogger, bool fNeedSpace);270 static void rtlogFlush(PRTLOGGERINTERNAL pLoggerInt, bool fNeedSpace); 241 271 static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars); 242 static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars);243 static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,const char *pszFormat, va_list args);272 static void rtlogLoggerExVLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, 273 const char *pszFormat, va_list args); 244 274 #ifndef IN_RC 245 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);275 static void rtlogLoggerExFLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...); 246 276 #endif 247 277 … … 250 280 * Global Variables * 251 281 *********************************************************************************************************************************/ 252 #ifdef IN_RC 282 #ifndef IN_RC 283 /** Default logger instance. */ 284 static PRTLOGGER g_pLogger; 285 /** Default release logger instance. */ 286 static PRTLOGGER g_pRelLogger; 287 #else 253 288 /** Default logger instance. Make it weak because our RC module loader does not 254 289 * necessarily resolve this symbol and the compiler _must_ check if this is … … 256 291 * .weak_reference (must specify "-dynamic" to be used'') */ 257 292 # ifdef RT_OS_DARWIN 258 extern "C" DECLIMPORT(RTLOGGERRC) g_Logger; 293 extern "C" DECLIMPORT(RTLOGGERRC) g_Logger; 294 /** Default release logger instance. */ 295 extern "C" DECLIMPORT(RTLOGGERRC) g_RelLogger; 259 296 # else 260 297 extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_Logger; 298 /** Default release logger instance. */ 299 extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_RelLogger; 261 300 # endif 262 #else /* !IN_RC */ 263 /** Default logger instance. */ 264 static PRTLOGGER g_pLogger; 265 #endif /* !IN_RC */ 301 #endif /* IN_RC */ 266 302 #ifdef IN_RING3 267 303 /** The RTThreadGetWriteLockCount() change caused by the logger mutex semaphore. */ … … 303 339 const char *pszInstr; /**< The name */ 304 340 size_t cchInstr; /**< The size of the name. */ 305 uint 32_t fFlag; /**< The flag value. */341 uint64_t fFlag; /**< The flag value. */ 306 342 bool fInverted; /**< Inverse meaning? */ 307 343 uint32_t fFixedDest; /**< RTLOGDEST_FIXED_XXX flags blocking this. */ … … 381 417 * 382 418 * @returns See RTSemSpinMutexRequest(). 383 * @param pLogger 384 */ 385 DECLINLINE(int) rtlogLock(PRTLOGGER pLogger)419 * @param pLoggerInt The logger instance. 420 */ 421 DECLINLINE(int) rtlogLock(PRTLOGGERINTERNAL pLoggerInt) 386 422 { 387 423 #ifndef IN_RC 388 PRTLOGGERINTERNAL pInt = pLogger->pInt; 389 AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV), 424 AssertMsgReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, ("%#x != %#x\n", pLoggerInt->Core.u32Magic, RTLOGGER_MAGIC), 425 VERR_INVALID_MAGIC); 426 AssertMsgReturn(pLoggerInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pLoggerInt->uRevision, RTLOGGERINTERNAL_REV), 390 427 VERR_LOG_REVISION_MISMATCH); 391 AssertMsgReturn(p Int->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)),428 AssertMsgReturn(pLoggerInt->cbSelf == sizeof(*pLoggerInt), ("%#x != %#x\n", pLoggerInt->cbSelf, sizeof(*pLoggerInt)), 392 429 VERR_LOG_REVISION_MISMATCH); 393 if (p Int->hSpinMtx != NIL_RTSEMSPINMUTEX)394 { 395 int rc = RTSemSpinMutexRequest(p Int->hSpinMtx);430 if (pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX) 431 { 432 int rc = RTSemSpinMutexRequest(pLoggerInt->hSpinMtx); 396 433 if (RT_FAILURE(rc)) 397 434 return rc; 398 435 } 399 436 #else 400 NOREF(pLogger );437 NOREF(pLoggerInt); 401 438 #endif 402 439 return VINF_SUCCESS; … … 406 443 /** 407 444 * Unlocks the logger instance. 408 * @param pLogger 409 */ 410 DECLINLINE(void) rtlogUnlock(PRTLOGGER pLogger)445 * @param pLoggerInt The logger instance. 446 */ 447 DECLINLINE(void) rtlogUnlock(PRTLOGGERINTERNAL pLoggerInt) 411 448 { 412 449 #ifndef IN_RC 413 if (pLogger ->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)414 RTSemSpinMutexRelease(pLogger ->pInt->hSpinMtx);450 if (pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX) 451 RTSemSpinMutexRelease(pLoggerInt->hSpinMtx); 415 452 #else 416 NOREF(pLogger );453 NOREF(pLoggerInt); 417 454 #endif 418 455 return; … … 432 469 static DECLCALLBACK(size_t) rtlogPhaseWrite(void *pvArg, const char *pachChars, size_t cbChars) 433 470 { 434 PRTLOGGER pLogger = (PRTLOGGER)pvArg;435 RTFileWrite(pLogger ->pInt->hFile, pachChars, cbChars, NULL);471 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pvArg; 472 RTFileWrite(pLoggerInt->hFile, pachChars, cbChars, NULL); 436 473 return cbChars; 437 474 } … … 477 514 static DECLCALLBACK(void) rtlogPhaseMsgLocked(PRTLOGGER pLogger, const char *pszFormat, ...) 478 515 { 516 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 517 AssertPtrReturnVoid(pLoggerInt); 518 Assert(pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX); 519 479 520 va_list args; 480 AssertPtrReturnVoid(pLogger);481 AssertPtrReturnVoid(pLogger->pInt);482 Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);483 484 521 va_start(args, pszFormat); 485 rtlogLoggerExVLocked(pLogger , 0, ~0U, pszFormat, args);522 rtlogLoggerExVLocked(pLoggerInt, 0, ~0U, pszFormat, args); 486 523 va_end(args); 487 524 } … … 497 534 static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *pszFormat, ...) 498 535 { 536 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 537 AssertPtrReturnVoid(pLoggerInt); 538 Assert(pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX); 539 499 540 va_list args; 500 AssertPtrReturnVoid(pLogger);501 AssertPtrReturnVoid(pLogger->pInt);502 Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);503 504 541 va_start(args, pszFormat); 505 RTLogLoggerExV( pLogger, 0, ~0U, pszFormat, args);542 RTLogLoggerExV(&pLoggerInt->Core, 0, ~0U, pszFormat, args); 506 543 va_end(args); 507 544 } … … 513 550 * 514 551 * @returns IPRT status code. 515 * @param pLogger 552 * @param pLoggerInt The logger instance. 516 553 * @param cbNewSize The new ring buffer size (0 == default). 517 554 * @param fForce Whether to do this even if the logger instance hasn't 518 555 * really been fully created yet (i.e. during RTLogCreate). 519 556 */ 520 static int rtLogRingBufAdjust(PRTLOGGER pLogger, uint32_t cbNewSize, bool fForce)557 static int rtLogRingBufAdjust(PRTLOGGERINTERNAL pLoggerInt, uint32_t cbNewSize, bool fForce) 521 558 { 522 559 /* 523 560 * If this is early logger init, don't do anything. 524 561 */ 525 if (!pLogger ->pInt->fCreated && !fForce)562 if (!pLoggerInt->fCreated && !fForce) 526 563 return VINF_SUCCESS; 527 564 … … 529 566 * Lock the logger and make the necessary changes. 530 567 */ 531 int rc = rtlogLock(pLogger );568 int rc = rtlogLock(pLoggerInt); 532 569 if (RT_SUCCESS(rc)) 533 570 { 534 571 if (cbNewSize == 0) 535 572 cbNewSize = RTLOG_RINGBUF_DEFAULT_SIZE; 536 if ( pLogger ->pInt->cbRingBuf != cbNewSize537 || !pLogger ->pInt->pchRingBufCur)538 { 539 uintptr_t offOld = pLogger ->pInt->pchRingBufCur - pLogger->pInt->pszRingBuf;573 if ( pLoggerInt->cbRingBuf != cbNewSize 574 || !pLoggerInt->pchRingBufCur) 575 { 576 uintptr_t offOld = pLoggerInt->pchRingBufCur - pLoggerInt->pszRingBuf; 540 577 if (offOld < sizeof(RTLOG_RINGBUF_EYE_CATCHER)) 541 578 offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER); 542 579 else if (offOld >= cbNewSize) 543 580 { 544 memmove(pLogger ->pInt->pszRingBuf, &pLogger->pInt->pszRingBuf[offOld - cbNewSize], cbNewSize);581 memmove(pLoggerInt->pszRingBuf, &pLoggerInt->pszRingBuf[offOld - cbNewSize], cbNewSize); 545 582 offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER); 546 583 } 547 584 548 void *pvNew = RTMemRealloc(pLogger ->pInt->pchRingBufCur, cbNewSize);585 void *pvNew = RTMemRealloc(pLoggerInt->pchRingBufCur, cbNewSize); 549 586 if (pvNew) 550 587 { 551 pLogger ->pInt->pszRingBuf = (char *)pvNew;552 pLogger ->pInt->pchRingBufCur = (char *)pvNew + offOld;553 pLogger ->pInt->cbRingBuf = cbNewSize;588 pLoggerInt->pszRingBuf = (char *)pvNew; 589 pLoggerInt->pchRingBufCur = (char *)pvNew + offOld; 590 pLoggerInt->cbRingBuf = cbNewSize; 554 591 memcpy(pvNew, RTLOG_RINGBUF_EYE_CATCHER, sizeof(RTLOG_RINGBUF_EYE_CATCHER)); 555 592 memcpy((char *)pvNew + cbNewSize - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END), … … 560 597 rc = VERR_NO_MEMORY; 561 598 } 562 rtlogUnlock(pLogger );599 rtlogUnlock(pLoggerInt); 563 600 } 564 601 … … 642 679 * Flushes the ring buffer to all the other log destinations. 643 680 * 644 * @param pLogger 645 */ 646 static void rtLogRingBufFlush(PRTLOGGER pLogger)681 * @param pLoggerInt The logger instance which ring buffer should be flushed. 682 */ 683 static void rtLogRingBufFlush(PRTLOGGERINTERNAL pLoggerInt) 647 684 { 648 685 const char *pszPreamble; … … 657 694 * part of the buffer. 658 695 */ 659 uint64_t cchUnflushed = pLogger ->pInt->cbRingBufUnflushed;660 char * const pszBuf = &pLogger ->pInt->pszRingBuf[sizeof(RTLOG_RINGBUF_EYE_CATCHER)];661 size_t const cchBuf = pLogger ->pInt->cbRingBuf - sizeof(RTLOG_RINGBUF_EYE_CATCHER) - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END);662 size_t offCur = pLogger ->pInt->pchRingBufCur - pszBuf;696 uint64_t cchUnflushed = pLoggerInt->cbRingBufUnflushed; 697 char * const pszBuf = &pLoggerInt->pszRingBuf[sizeof(RTLOG_RINGBUF_EYE_CATCHER)]; 698 size_t const cchBuf = pLoggerInt->cbRingBuf - sizeof(RTLOG_RINGBUF_EYE_CATCHER) - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END); 699 size_t offCur = pLoggerInt->pchRingBufCur - pszBuf; 663 700 size_t cchAfter; 664 701 if (RT_LIKELY(offCur < cchBuf)) … … 670 707 } 671 708 672 pLogger ->pInt->cbRingBufUnflushed = 0;709 pLoggerInt->cbRingBufUnflushed = 0; 673 710 674 711 /* … … 711 748 * Write the ring buffer to all other destiations. 712 749 */ 713 if (pLogger ->fDestFlags & RTLOGDEST_USER)750 if (pLoggerInt->fDestFlags & RTLOGDEST_USER) 714 751 { 715 752 if (cchPreamble) … … 721 758 } 722 759 723 if (pLogger ->fDestFlags & RTLOGDEST_DEBUGGER)760 if (pLoggerInt->fDestFlags & RTLOGDEST_DEBUGGER) 724 761 { 725 762 if (cchPreamble) … … 732 769 733 770 # ifdef IN_RING3 734 if (pLogger ->fDestFlags & RTLOGDEST_FILE)735 { 736 if (pLogger ->pInt->hFile != NIL_RTFILE)771 if (pLoggerInt->fDestFlags & RTLOGDEST_FILE) 772 { 773 if (pLoggerInt->hFile != NIL_RTFILE) 737 774 { 738 775 if (cchPreamble) 739 RTFileWrite(pLogger ->pInt->hFile, pszPreamble, cchPreamble, NULL);776 RTFileWrite(pLoggerInt->hFile, pszPreamble, cchPreamble, NULL); 740 777 if (cchFirst) 741 RTFileWrite(pLogger ->pInt->hFile, pszFirst, cchFirst, NULL);778 RTFileWrite(pLoggerInt->hFile, pszFirst, cchFirst, NULL); 742 779 if (cchSecond) 743 RTFileWrite(pLogger ->pInt->hFile, pszSecond, cchSecond, NULL);744 if (pLogger ->fFlags & RTLOGFLAGS_FLUSH)745 RTFileFlush(pLogger ->pInt->hFile);746 } 747 if (pLogger ->pInt->cHistory)748 pLogger ->pInt->cbHistoryFileWritten += cchFirst + cchSecond;780 RTFileWrite(pLoggerInt->hFile, pszSecond, cchSecond, NULL); 781 if (pLoggerInt->fFlags & RTLOGFLAGS_FLUSH) 782 RTFileFlush(pLoggerInt->hFile); 783 } 784 if (pLoggerInt->cHistory) 785 pLoggerInt->cbHistoryFileWritten += cchFirst + cchSecond; 749 786 } 750 787 # endif 751 788 752 if (pLogger ->fDestFlags & RTLOGDEST_STDOUT)789 if (pLoggerInt->fDestFlags & RTLOGDEST_STDOUT) 753 790 { 754 791 if (cchPreamble) … … 760 797 } 761 798 762 if (pLogger ->fDestFlags & RTLOGDEST_STDERR)799 if (pLoggerInt->fDestFlags & RTLOGDEST_STDERR) 763 800 { 764 801 if (cchPreamble) … … 771 808 772 809 # if defined(IN_RING0) && !defined(LOG_NO_COM) 773 if (pLogger ->fDestFlags & RTLOGDEST_COM)810 if (pLoggerInt->fDestFlags & RTLOGDEST_COM) 774 811 { 775 812 if (cchPreamble) … … 784 821 785 822 786 RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, const char *pszEnvVarBase,787 u nsignedcGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,788 uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,789 uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,823 RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings, 824 uint32_t cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup, 825 PFNRTLOGFLUSH pfnFlush, uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags, 826 PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot, 790 827 PRTERRINFO pErrInfo, const char *pszFilenameFmt, va_list args) 791 828 { 792 int rc; 793 size_t offInternal; 794 size_t cbLogger; 795 PRTLOGGER pLogger; 829 int rc; 830 size_t cbLogger; 831 size_t offBuffers; 832 PRTLOGGERINTERNAL pLoggerInt; 833 uint32_t i; 796 834 797 835 /* 798 836 * Validate input. 799 837 */ 800 if ( (cGroups && !papszGroups) 801 || !RT_VALID_PTR(ppLogger) ) 802 { 803 AssertMsgFailed(("Invalid parameters!\n")); 804 return VERR_INVALID_PARAMETER; 805 } 838 AssertPtrReturn(ppLogger, VERR_INVALID_POINTER); 806 839 *ppLogger = NULL; 807 840 if (cGroups) 841 { 842 AssertPtrReturn(papszGroups, VERR_INVALID_POINTER); 843 AssertReturn(cGroups < _8K, VERR_OUT_OF_RANGE); 844 } 808 845 AssertMsgReturn(cHistory < _1M, ("%#x", cHistory), VERR_OUT_OF_RANGE); 809 810 /* 811 * Allocate a logger instance.812 * /813 offInternal = RT_UOFFSETOF_DYN(RTLOGGER, afGroups[cGroups]);814 offInternal = RT_ALIGN_Z(offInternal, sizeof(uint64_t));815 cbLogger = offInternal + sizeof(RTLOGGERINTERNAL);846 AssertReturn(cBufDescs <= 128, VERR_OUT_OF_RANGE); 847 848 /* 849 * Calculate the logger size. 850 */ 851 AssertCompileSize(RTLOGGER, 32); 852 cbLogger = RT_UOFFSETOF_DYN(RTLOGGERINTERNAL, afGroups[cGroups]); 816 853 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 817 854 cbLogger += cGroups * sizeof(uint32_t); 818 pLogger = (PRTLOGGER)RTMemAllocZVarTag(cbLogger, "may-leak:log-instance"); 819 if (pLogger) 855 if (cBufDescs == 0) 856 { 857 /* Allocate one buffer descriptor and a default sized buffer. */ 858 cbLogger = RT_ALIGN_Z(cbLogger, RTLOG_BUFFER_ALIGN); 859 offBuffers = cbLogger; 860 cbLogger += RT_ALIGN_Z(sizeof(paBufDescs[0]), RTLOG_BUFFER_ALIGN) + RTLOG_BUFFER_DEFAULT_SIZE; 861 } 862 else 863 { 864 /* Caller-supplied buffer descriptors. If pchBuf is NULL, we have to allocate the buffers. */ 865 AssertPtrReturn(paBufDescs, VERR_INVALID_POINTER); 866 if (paBufDescs[0].pchBuf != NULL) 867 offBuffers = 0; 868 else 869 { 870 cbLogger = RT_ALIGN_Z(cbLogger, RTLOG_BUFFER_ALIGN); 871 offBuffers = cbLogger; 872 } 873 874 for (i = 0; i < cBufDescs; i++) 875 { 876 AssertReturn(paBufDescs[i].u32Magic == RTLOGBUFFERDESC_MAGIC, VERR_INVALID_MAGIC); 877 AssertReturn(paBufDescs[i].uReserved == 0, VERR_INVALID_PARAMETER); 878 AssertMsgReturn(paBufDescs[i].cbBuf >= _1K && paBufDescs[i].cbBuf <= _64M, 879 ("paBufDesc[%u].cbBuf=%#x\n", i, paBufDescs[i].cbBuf), VERR_OUT_OF_RANGE); 880 AssertReturn(paBufDescs[i].offBuf == 0, VERR_INVALID_PARAMETER); 881 if (offBuffers != 0) 882 { 883 cbLogger += RT_ALIGN_Z(paBufDescs[i].cbBuf, RTLOG_BUFFER_ALIGN); 884 AssertReturn(paBufDescs[i].pchBuf == NULL, VERR_INVALID_PARAMETER); 885 AssertReturn(paBufDescs[i].pAux == NULL, VERR_INVALID_PARAMETER); 886 } 887 else 888 { 889 AssertPtrReturn(paBufDescs[i].pchBuf, VERR_INVALID_POINTER); 890 AssertPtrNullReturn(paBufDescs[i].pAux, VERR_INVALID_POINTER); 891 } 892 } 893 } 894 895 /* 896 * Allocate a logger instance. 897 */ 898 pLoggerInt = (PRTLOGGERINTERNAL)RTMemAllocZVarTag(cbLogger, "may-leak:log-instance"); 899 if (pLoggerInt) 820 900 { 821 901 # if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC)) 822 902 uint8_t *pu8Code; 823 903 # endif 824 pLogger->u32Magic = RTLOGGER_MAGIC; 825 pLogger->cGroups = cGroups; 826 pLogger->fFlags = fFlags; 827 pLogger->fDestFlags = fDestFlags; 828 pLogger->pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger + offInternal); 829 pLogger->pInt->uRevision = RTLOGGERINTERNAL_REV; 830 pLogger->pInt->cbSelf = sizeof(RTLOGGERINTERNAL); 831 pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX; 832 pLogger->pInt->pfnFlush = NULL; 833 pLogger->pInt->pfnPrefix = NULL; 834 pLogger->pInt->pvPrefixUserArg = NULL; 835 pLogger->pInt->fPendingPrefix = true; 836 pLogger->pInt->fCreated = false; 837 pLogger->pInt->nsR0ProgramStart = 0; 838 RT_ZERO(pLogger->pInt->szR0ThreadName); 839 pLogger->pInt->cMaxGroups = cGroups; 840 pLogger->pInt->papszGroups = papszGroups; 904 pLoggerInt->Core.u32Magic = RTLOGGER_MAGIC; 905 pLoggerInt->cGroups = cGroups; 906 pLoggerInt->fFlags = fFlags; 907 pLoggerInt->fDestFlags = fDestFlags; 908 pLoggerInt->uRevision = RTLOGGERINTERNAL_REV; 909 pLoggerInt->cbSelf = sizeof(RTLOGGERINTERNAL); 910 pLoggerInt->hSpinMtx = NIL_RTSEMSPINMUTEX; 911 pLoggerInt->pfnFlush = pfnFlush; 912 pLoggerInt->pfnPrefix = NULL; 913 pLoggerInt->pvPrefixUserArg = NULL; 914 pLoggerInt->fPendingPrefix = true; 915 pLoggerInt->fCreated = false; 916 pLoggerInt->nsR0ProgramStart = 0; 917 RT_ZERO(pLoggerInt->szR0ThreadName); 918 pLoggerInt->cMaxGroups = cGroups; 919 pLoggerInt->papszGroups = papszGroups; 841 920 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 842 pLogger ->pInt->pacEntriesPerGroup = (uint32_t *)(pLogger->pInt + 1);921 pLoggerInt->pacEntriesPerGroup = (uint32_t *)(pLoggerInt + 1); 843 922 else 844 pLogger ->pInt->pacEntriesPerGroup= NULL;845 pLogger ->pInt->cMaxEntriesPerGroup= cMaxEntriesPerGroup ? cMaxEntriesPerGroup : UINT32_MAX;923 pLoggerInt->pacEntriesPerGroup = NULL; 924 pLoggerInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup ? cMaxEntriesPerGroup : UINT32_MAX; 846 925 # ifdef IN_RING3 847 pLogger ->pInt->pfnPhase= pfnPhase;848 pLogger ->pInt->hFile= NIL_RTFILE;849 pLogger ->pInt->cHistory= cHistory;926 pLoggerInt->pfnPhase = pfnPhase; 927 pLoggerInt->hFile = NIL_RTFILE; 928 pLoggerInt->cHistory = cHistory; 850 929 if (cbHistoryFileMax == 0) 851 pLogger ->pInt->cbHistoryFileMax= UINT64_MAX;930 pLoggerInt->cbHistoryFileMax = UINT64_MAX; 852 931 else 853 pLogger ->pInt->cbHistoryFileMax= cbHistoryFileMax;932 pLoggerInt->cbHistoryFileMax = cbHistoryFileMax; 854 933 if (cSecsHistoryTimeSlot == 0) 855 pLogger ->pInt->cSecsHistoryTimeSlot= UINT32_MAX;934 pLoggerInt->cSecsHistoryTimeSlot = UINT32_MAX; 856 935 else 857 pLogger ->pInt->cSecsHistoryTimeSlot= cSecsHistoryTimeSlot;936 pLoggerInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot; 858 937 # else /* !IN_RING3 */ 859 938 RT_NOREF_PV(pfnPhase); RT_NOREF_PV(cHistory); RT_NOREF_PV(cbHistoryFileMax); RT_NOREF_PV(cSecsHistoryTimeSlot); 860 939 # endif /* !IN_RING3 */ 861 940 if (pszGroupSettings) 862 RTLogGroupSettings(pLogger, pszGroupSettings); 941 RTLogGroupSettings(&pLoggerInt->Core, pszGroupSettings); 942 943 /* 944 * Buffer descriptors. 945 */ 946 if (!offBuffers) 947 { 948 /* Caller-supplied descriptors: */ 949 pLoggerInt->cBufDescs = cBufDescs; 950 pLoggerInt->paBufDescs = paBufDescs; 951 } 952 else if (cBufDescs) 953 { 954 /* Caller-supplied descriptors, but we allocate the actual buffers: */ 955 pLoggerInt->cBufDescs = cBufDescs; 956 pLoggerInt->paBufDescs = paBufDescs; 957 for (i = 0; i < cBufDescs; i++) 958 { 959 paBufDescs[i].pchBuf = (char *)pLoggerInt + offBuffers; 960 offBuffers = RT_ALIGN_Z(offBuffers + paBufDescs[i].cbBuf, RTLOG_BUFFER_ALIGN); 961 } 962 Assert(offBuffers == cbLogger); 963 } 964 else 965 { 966 /* One descriptor with a default sized buffer. */ 967 pLoggerInt->cBufDescs = cBufDescs = 1; 968 pLoggerInt->paBufDescs = paBufDescs = (PRTLOGBUFFERDESC)((char *)(char *)pLoggerInt + offBuffers); 969 offBuffers = RT_ALIGN_Z(offBuffers + sizeof(paBufDescs[0]) * cBufDescs, RTLOG_BUFFER_ALIGN); 970 for (i = 0; i < cBufDescs; i++) 971 { 972 paBufDescs[i].u32Magic = RTLOGBUFFERDESC_MAGIC; 973 paBufDescs[i].uReserved = 0; 974 paBufDescs[i].cbBuf = RTLOG_BUFFER_DEFAULT_SIZE; 975 paBufDescs[i].offBuf = 0; 976 paBufDescs[i].pAux = NULL; 977 paBufDescs[i].pchBuf = (char *)pLoggerInt + offBuffers; 978 offBuffers = RT_ALIGN_Z(offBuffers + RTLOG_BUFFER_DEFAULT_SIZE, RTLOG_BUFFER_ALIGN); 979 } 980 Assert(offBuffers == cbLogger); 981 } 982 pLoggerInt->pBufDesc = paBufDescs; 983 pLoggerInt->idxBufDesc = 0; 863 984 864 985 # if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC)) … … 869 990 if (pu8Code) 870 991 { 871 pLogger ->pfnLogger = *(PFNRTLOGGER*)&pu8Code;992 pLoggerInt->Core.pfnLogger = *(PFNRTLOGGER *)&pu8Code; 872 993 *pu8Code++ = 0x68; /* push imm32 */ 873 *(void **)pu8Code = pLogger;994 *(void **)pu8Code = &pLoggerInt->Core; 874 995 pu8Code += sizeof(void *); 875 996 *pu8Code++ = 0xe8; /* call rel32 */ … … 881 1002 *pu8Code++ = 0x04; 882 1003 *pu8Code++ = 0xc3; /* ret near */ 883 AssertMsg((uintptr_t)pu8Code - (uintptr_t)pLogger ->pfnLogger <= 64,884 ("Wrapper assembly is too big! %d bytes\n", (uintptr_t)pu8Code - (uintptr_t)pLogger ->pfnLogger));1004 AssertMsg((uintptr_t)pu8Code - (uintptr_t)pLoggerInt->Core.pfnLogger <= 64, 1005 ("Wrapper assembly is too big! %d bytes\n", (uintptr_t)pu8Code - (uintptr_t)pLoggerInt->Core.pfnLogger)); 885 1006 rc = VINF_SUCCESS; 886 1007 } … … 889 1010 rc = VERR_NO_MEMORY; 890 1011 # ifdef RT_OS_LINUX 891 1012 /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */ 892 1013 RTErrInfoSet(pErrInfo, rc, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?")); 893 1014 # endif … … 903 1024 { 904 1025 /** @todo validate the length, fail on overflow. */ 905 RTStrPrintfV(pLogger ->pInt->szFilename, sizeof(pLogger->pInt->szFilename), pszFilenameFmt, args);906 if (pLogger ->pInt->szFilename[0])907 pLogger ->fDestFlags |= RTLOGDEST_FILE;1026 RTStrPrintfV(pLoggerInt->szFilename, sizeof(pLoggerInt->szFilename), pszFilenameFmt, args); 1027 if (pLoggerInt->szFilename[0]) 1028 pLoggerInt->fDestFlags |= RTLOGDEST_FILE; 908 1029 } 909 1030 … … 924 1045 const char *pszValue = RTEnvGet(pszEnvVar); 925 1046 if (pszValue) 926 RTLogDestinations( pLogger, pszValue);1047 RTLogDestinations(&pLoggerInt->Core, pszValue); 927 1048 928 1049 /* … … 932 1053 pszValue = RTEnvGet(pszEnvVar); 933 1054 if (pszValue) 934 RTLogFlags( pLogger, pszValue);1055 RTLogFlags(&pLoggerInt->Core, pszValue); 935 1056 936 1057 /* … … 940 1061 pszValue = RTEnvGet(pszEnvVar); 941 1062 if (pszValue) 942 RTLogGroupSettings( pLogger, pszValue);1063 RTLogGroupSettings(&pLoggerInt->Core, pszValue); 943 1064 944 1065 /* … … 952 1073 rc = RTStrToUInt32Full(pszValue, 0, &cMax); 953 1074 if (RT_SUCCESS(rc)) 954 pLogger ->pInt->cMaxEntriesPerGroup = cMax ? cMax : UINT32_MAX;1075 pLoggerInt->cMaxEntriesPerGroup = cMax ? cMax : UINT32_MAX; 955 1076 else 956 1077 AssertMsgFailed(("Invalid group limit! %s=%s\n", pszEnvVar, pszValue)); … … 966 1087 */ 967 1088 rc = VINF_SUCCESS; 968 if ((pLogger ->fDestFlags & (RTLOGDEST_F_DELAY_FILE | RTLOGDEST_FILE)) == RTLOGDEST_F_DELAY_FILE)969 pLogger ->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE;1089 if ((pLoggerInt->fDestFlags & (RTLOGDEST_F_DELAY_FILE | RTLOGDEST_FILE)) == RTLOGDEST_F_DELAY_FILE) 1090 pLoggerInt->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE; 970 1091 # ifdef IN_RING3 971 if ((pLogger ->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_F_DELAY_FILE)) == RTLOGDEST_FILE)972 rc = rtR3LogOpenFileDestination(pLogger , pErrInfo);1092 if ((pLoggerInt->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_F_DELAY_FILE)) == RTLOGDEST_FILE) 1093 rc = rtR3LogOpenFileDestination(pLoggerInt, pErrInfo); 973 1094 # endif 974 1095 975 if ((pLogger ->fDestFlags & RTLOGDEST_RINGBUF) && RT_SUCCESS(rc))976 rc = rtLogRingBufAdjust(pLogger , pLogger->pInt->cbRingBuf, true /*fForce*/);1096 if ((pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF) && RT_SUCCESS(rc)) 1097 rc = rtLogRingBufAdjust(pLoggerInt, pLoggerInt->cbRingBuf, true /*fForce*/); 977 1098 978 1099 /* … … 982 1103 if (RT_SUCCESS(rc)) 983 1104 { 984 rc = RTSemSpinMutexCreate(&pLogger->pInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE); 1105 if (!(fFlags & RTLOG_F_NO_LOCKING)) 1106 rc = RTSemSpinMutexCreate(&pLoggerInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE); 985 1107 if (RT_SUCCESS(rc)) 986 1108 { … … 990 1112 { 991 1113 int32_t c = RTLockValidatorWriteLockGetCount(Thread); 992 RTSemSpinMutexRequest(pLogger ->pInt->hSpinMtx);1114 RTSemSpinMutexRequest(pLoggerInt->hSpinMtx); 993 1115 c = RTLockValidatorWriteLockGetCount(Thread) - c; 994 RTSemSpinMutexRelease(pLogger ->pInt->hSpinMtx);1116 RTSemSpinMutexRelease(pLoggerInt->hSpinMtx); 995 1117 ASMAtomicWriteU32(&g_cLoggerLockCount, c); 996 1118 } 997 1119 998 1120 /* Use the callback to generate some initial log contents. */ 999 Assert (RT_VALID_PTR(pLogger->pInt->pfnPhase) || pLogger->pInt->pfnPhase == NULL);1000 if (pLogger ->pInt->pfnPhase)1001 pLogger ->pInt->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);1121 AssertPtrNull(pLoggerInt->pfnPhase); 1122 if (pLoggerInt->pfnPhase) 1123 pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal); 1002 1124 # endif 1003 pLogger ->pInt->fCreated = true;1004 *ppLogger = pLogger;1125 pLoggerInt->fCreated = true; 1126 *ppLogger = &pLoggerInt->Core; 1005 1127 return VINF_SUCCESS; 1006 1128 } … … 1009 1131 } 1010 1132 # ifdef IN_RING3 1011 RTFileClose(pLogger ->pInt->hFile);1133 RTFileClose(pLoggerInt->hFile); 1012 1134 # endif 1013 1135 # if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC) 1014 RTMemFree(*(void **)&pLogger ->pfnLogger);1136 RTMemFree(*(void **)&pLoggerInt->Core.pfnLogger); 1015 1137 # else 1016 RTMemExecFree(*(void **)&pLogger ->pfnLogger, 64);1138 RTMemExecFree(*(void **)&pLoggerInt->Core.pfnLogger, 64); 1017 1139 # endif 1018 1140 } 1019 RTMemFree(pLogger );1141 RTMemFree(pLoggerInt); 1020 1142 } 1021 1143 else … … 1027 1149 1028 1150 1029 RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint 32_t fFlags, const char *pszGroupSettings,1151 RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint64_t fFlags, const char *pszGroupSettings, 1030 1152 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups, 1031 1153 uint32_t fDestFlags, const char *pszFilenameFmt, ...) 1032 1154 { 1033 va_list args; 1034 int rc; 1035 1036 va_start(args, pszFilenameFmt); 1037 rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, 1038 cGroups, papszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/, fDestFlags, 1155 va_list va; 1156 int rc; 1157 1158 va_start(va, pszFilenameFmt); 1159 rc = RTLogCreateExV(ppLogger, pszEnvVarBase, fFlags, pszGroupSettings, cGroups, papszGroups, 1160 UINT32_MAX /*cMaxEntriesPerGroup*/, 1161 NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, fDestFlags, 1039 1162 NULL /*pfnPhase*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*cSecsHistoryTimeSlot*/, 1040 NULL /*pErrInfo*/, pszFilenameFmt, args);1041 va_end( args);1163 NULL /*pErrInfo*/, pszFilenameFmt, va); 1164 va_end(va); 1042 1165 return rc; 1043 1166 } … … 1045 1168 1046 1169 1047 RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, const char *pszEnvVarBase,1170 RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings, 1048 1171 unsigned cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup, 1049 uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,1050 uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,1172 PFNRTLOGFLUSH pfnFlush, uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags, 1173 PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot, 1051 1174 PRTERRINFO pErrInfo, const char *pszFilenameFmt, ...) 1052 1175 { 1053 va_list args; 1054 int rc; 1055 1056 va_start(args, pszFilenameFmt); 1057 rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, cMaxEntriesPerGroup, 1058 fDestFlags, pfnPhase, cHistory, cbHistoryFileMax, cSecsHistoryTimeSlot, 1059 pErrInfo, pszFilenameFmt, args); 1060 va_end(args); 1176 va_list va; 1177 int rc; 1178 1179 va_start(va, pszFilenameFmt); 1180 rc = RTLogCreateExV(ppLogger, pszEnvVarBase, fFlags, pszGroupSettings, cGroups, papszGroups, cMaxEntriesPerGroup, 1181 pfnFlush, cBufDescs, paBufDescs, fDestFlags, 1182 pfnPhase, cHistory, cbHistoryFileMax, cSecsHistoryTimeSlot, 1183 pErrInfo, pszFilenameFmt, va); 1184 va_end(va); 1061 1185 return rc; 1062 1186 } … … 1074 1198 RTDECL(int) RTLogDestroy(PRTLOGGER pLogger) 1075 1199 { 1076 int rc; 1077 uint32_t iGroup; 1078 RTSEMSPINMUTEX hSpinMtx; 1200 int rc; 1201 uint32_t iGroup; 1202 RTSEMSPINMUTEX hSpinMtx; 1203 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 1079 1204 1080 1205 /* 1081 1206 * Validate input. 1082 1207 */ 1083 if (!pLogger )1208 if (!pLoggerInt) 1084 1209 return VINF_SUCCESS; 1085 AssertPtrReturn(pLogger, VERR_INVALID_POINTER); 1086 AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 1087 AssertPtrReturn(pLogger->pInt, VERR_INVALID_POINTER); 1210 AssertPtrReturn(pLoggerInt, VERR_INVALID_POINTER); 1211 AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 1088 1212 1089 1213 /* 1090 1214 * Acquire logger instance sem and disable all logging. (paranoia) 1091 1215 */ 1092 rc = rtlogLock(pLogger );1216 rc = rtlogLock(pLoggerInt); 1093 1217 AssertMsgRCReturn(rc, ("%Rrc\n", rc), rc); 1094 1218 1095 pLogger ->fFlags |= RTLOGFLAGS_DISABLED;1096 iGroup = pLogger ->cGroups;1219 pLoggerInt->fFlags |= RTLOGFLAGS_DISABLED; 1220 iGroup = pLoggerInt->cGroups; 1097 1221 while (iGroup-- > 0) 1098 pLogger ->afGroups[iGroup] = 0;1222 pLoggerInt->afGroups[iGroup] = 0; 1099 1223 1100 1224 /* 1101 1225 * Flush it. 1102 1226 */ 1103 rtlogFlush(pLogger , false /*fNeedSpace*/);1227 rtlogFlush(pLoggerInt, false /*fNeedSpace*/); 1104 1228 1105 1229 # ifdef IN_RING3 … … 1107 1231 * Add end of logging message. 1108 1232 */ 1109 if ( (pLogger ->fDestFlags & RTLOGDEST_FILE)1110 && pLogger ->pInt->hFile != NIL_RTFILE)1111 pLogger ->pInt->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);1233 if ( (pLoggerInt->fDestFlags & RTLOGDEST_FILE) 1234 && pLoggerInt->hFile != NIL_RTFILE) 1235 pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_END, rtlogPhaseMsgLocked); 1112 1236 1113 1237 /* 1114 1238 * Close output stuffs. 1115 1239 */ 1116 if (pLogger ->pInt->hFile != NIL_RTFILE)1117 { 1118 int rc2 = RTFileClose(pLogger ->pInt->hFile);1240 if (pLoggerInt->hFile != NIL_RTFILE) 1241 { 1242 int rc2 = RTFileClose(pLoggerInt->hFile); 1119 1243 AssertRC(rc2); 1120 1244 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 1121 1245 rc = rc2; 1122 pLogger ->pInt->hFile = NIL_RTFILE;1246 pLoggerInt->hFile = NIL_RTFILE; 1123 1247 } 1124 1248 # endif … … 1127 1251 * Free the mutex, the wrapper and the instance memory. 1128 1252 */ 1129 hSpinMtx = pLogger ->pInt->hSpinMtx;1130 pLogger ->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;1253 hSpinMtx = pLoggerInt->hSpinMtx; 1254 pLoggerInt->hSpinMtx = NIL_RTSEMSPINMUTEX; 1131 1255 if (hSpinMtx != NIL_RTSEMSPINMUTEX) 1132 1256 { … … 1139 1263 } 1140 1264 1141 if (pLogger ->pfnLogger)1265 if (pLoggerInt->Core.pfnLogger) 1142 1266 { 1143 1267 # if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC) 1144 RTMemFree(*(void **)&pLogger ->pfnLogger);1268 RTMemFree(*(void **)&pLoggerInt->Core.pfnLogger); 1145 1269 # else 1146 RTMemExecFree(*(void **)&pLogger ->pfnLogger, 64);1270 RTMemExecFree(*(void **)&pLoggerInt->Core.pfnLogger, 64); 1147 1271 # endif 1148 pLogger ->pfnLogger = NULL;1149 } 1150 RTMemFree(pLogger );1272 pLoggerInt->Core.pfnLogger = NULL; 1273 } 1274 RTMemFree(pLoggerInt); 1151 1275 1152 1276 return rc; … … 1155 1279 1156 1280 1281 # if 0 /* obsolete */ 1157 1282 /** 1158 1283 * Create a logger instance clone for RC usage. … … 1237 1362 } 1238 1363 RT_EXPORT_SYMBOL(RTLogCloneRC); 1239 1240 1364 # endif 1365 1366 1367 # if 0 /* obsolete */ 1241 1368 /** 1242 1369 * Flushes a RC logger instance to a R3 logger. … … 1294 1421 } 1295 1422 RT_EXPORT_SYMBOL(RTLogFlushRC); 1423 # endif 1296 1424 1297 1425 # ifdef IN_RING3 1298 1426 # if 0 /* obsolete */ 1299 1427 RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, 1300 1428 RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr, … … 1472 1600 RT_EXPORT_SYMBOL(RTLogFlushR0); 1473 1601 1602 # endif /* obsolete */ 1474 1603 # endif /* IN_RING3 */ 1475 1604 1476 1605 1606 #if 0 1477 1607 /** 1478 1608 * Flushes the buffer in one logger instance onto another logger. … … 1486 1616 RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger) 1487 1617 { 1618 PRTLOGGERINTERNAL pSrcLoggerInt = (PRTLOGGERINTERNAL)pSrcLogger; 1619 PRTLOGGERINTERNAL pDstLoggerInt = (PRTLOGGERINTERNAL)pDstLogger; 1620 1488 1621 /* 1489 1622 * Resolve defaults. 1490 1623 */ 1491 if (!pDstLogger )1492 { 1493 pDstLogger =RTLogDefaultInstance();1494 if (!pDstLogger )1624 if (!pDstLoggerInt) 1625 { 1626 pDstLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 1627 if (!pDstLoggerInt) 1495 1628 { 1496 1629 /* flushing to "/dev/null". */ 1497 if (pSrcLogger ->offScratch)1630 if (pSrcLoggerInt->offScratch) 1498 1631 { 1499 int rc = rtlogLock(pSrcLogger );1632 int rc = rtlogLock(pSrcLoggerInt); 1500 1633 if (RT_SUCCESS(rc)) 1501 1634 { 1502 pSrcLogger ->offScratch = 0;1503 rtlogUnlock(pSrcLogger );1635 pSrcLoggerInt->offScratch = 0; 1636 rtlogUnlock(pSrcLoggerInt); 1504 1637 } 1505 1638 } … … 1511 1644 * Any thing to flush? 1512 1645 */ 1513 if ( pSrcLogger ->offScratch1514 || pDstLogger ->offScratch)1646 if ( pSrcLoggerInt->offScratch 1647 || pDstLoggerInt->offScratch) 1515 1648 { 1516 1649 /* 1517 1650 * Acquire logger semaphores. 1518 1651 */ 1519 int rc = rtlogLock(pDstLogger );1652 int rc = rtlogLock(pDstLoggerInt); 1520 1653 if (RT_FAILURE(rc)) 1521 1654 return; 1522 rc = rtlogLock(pSrcLogger );1655 rc = rtlogLock(pSrcLoggerInt); 1523 1656 if (RT_SUCCESS(rc)) 1524 1657 { … … 1527 1660 * flush the HC instance. 1528 1661 */ 1529 if (pSrcLogger ->offScratch)1662 if (pSrcLoggerInt->offScratch) 1530 1663 { 1531 rtLogOutput(pDstLogger , pSrcLogger->achScratch, pSrcLogger->offScratch);1532 rtLogOutput(pDstLogger , NULL, 0);1533 pSrcLogger ->offScratch = 0;1664 rtLogOutput(pDstLoggerInt, pSrcLoggerInt->achScratch, pSrcLoggerInt->offScratch); 1665 rtLogOutput(pDstLoggerInt, NULL, 0); 1666 pSrcLoggerInt->offScratch = 0; 1534 1667 } 1535 1668 … … 1537 1670 * Release the semaphores. 1538 1671 */ 1539 rtlogUnlock(pSrcLogger );1540 } 1541 rtlogUnlock(pDstLogger );1672 rtlogUnlock(pSrcLoggerInt); 1673 } 1674 rtlogUnlock(pDstLoggerInt); 1542 1675 } 1543 1676 } 1544 1677 RT_EXPORT_SYMBOL(RTLogFlushToLogger); 1678 #endif 1545 1679 1546 1680 … … 1558 1692 * Resolve defaults. 1559 1693 */ 1560 if (!pLogger) 1561 { 1562 pLogger = RTLogDefaultInstance(); 1563 if (!pLogger) 1694 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 1695 if (!pLoggerInt) 1696 { 1697 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 1698 if (!pLoggerInt) 1564 1699 return VINF_SUCCESS; 1565 1700 } 1566 AssertReturn(pLogger ->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);1701 AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 1567 1702 1568 1703 /* 1569 1704 * Do the work. 1570 1705 */ 1571 rtlogLock(pLogger );1572 pLogger ->pInt->pvPrefixUserArg = pvUser;1573 pLogger ->pInt->pfnPrefix = pfnCallback;1574 rtlogUnlock(pLogger );1706 rtlogLock(pLoggerInt); 1707 pLoggerInt->pvPrefixUserArg = pvUser; 1708 pLoggerInt->pfnPrefix = pfnCallback; 1709 rtlogUnlock(pLoggerInt); 1575 1710 1576 1711 return VINF_SUCCESS; … … 1666 1801 RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue) 1667 1802 { 1803 1668 1804 /* 1669 1805 * Resolve defaults. 1670 1806 */ 1671 if (!pLogger) 1672 { 1673 pLogger = RTLogDefaultInstance(); 1674 if (!pLogger) 1807 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 1808 if (!pLoggerInt) 1809 { 1810 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 1811 if (!pLoggerInt) 1675 1812 return VINF_SUCCESS; 1676 1813 } 1814 Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC); 1677 1815 1678 1816 /* … … 1723 1861 ? RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 1724 1862 : rtlogGroupFlags(&pszStart[3]); 1725 for (i = 0; i < pLogger ->cGroups; i++)1863 for (i = 0; i < pLoggerInt->cGroups; i++) 1726 1864 { 1727 1865 if (fEnabled) 1728 pLogger ->afGroups[i] |= fFlags;1866 pLoggerInt->afGroups[i] |= fFlags; 1729 1867 else 1730 pLogger ->afGroups[i] &= ~fFlags;1868 pLoggerInt->afGroups[i] &= ~fFlags; 1731 1869 } 1732 1870 } … … 1736 1874 * Specific group(s). 1737 1875 */ 1738 for (i = 0; i < pLogger ->cGroups; i++)1876 for (i = 0; i < pLoggerInt->cGroups; i++) 1739 1877 { 1740 1878 const char *psz2 = (const char*)pszStart; 1741 if (rtlogIsGroupMatching(pLogger ->pInt->papszGroups[i], &psz2, cch))1879 if (rtlogIsGroupMatching(pLoggerInt->papszGroups[i], &psz2, cch)) 1742 1880 { 1743 1881 unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1; … … 1745 1883 fFlags = rtlogGroupFlags(psz2); 1746 1884 if (fEnabled) 1747 pLogger ->afGroups[i] |= fFlags;1885 pLoggerInt->afGroups[i] |= fFlags; 1748 1886 else 1749 pLogger ->afGroups[i] &= ~fFlags;1887 pLoggerInt->afGroups[i] &= ~fFlags; 1750 1888 } 1751 1889 } /* for each group */ … … 1920 2058 RTDECL(int) RTLogQueryGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf) 1921 2059 { 1922 bool fNotFirst = false; 1923 int rc = VINF_SUCCESS; 1924 uint32_t cGroups; 1925 uint32_t fGroup; 1926 uint32_t i; 2060 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2061 bool fNotFirst = false; 2062 int rc = VINF_SUCCESS; 2063 uint32_t cGroups; 2064 uint32_t fGroup; 2065 uint32_t i; 1927 2066 1928 2067 Assert(cchBuf); … … 1931 2070 * Resolve defaults. 1932 2071 */ 1933 if (!pLogger )1934 { 1935 pLogger =RTLogDefaultInstance();1936 if (!pLogger )2072 if (!pLoggerInt) 2073 { 2074 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2075 if (!pLoggerInt) 1937 2076 { 1938 2077 *pszBuf = '\0'; … … 1940 2079 } 1941 2080 } 1942 1943 cGroups = pLogger->cGroups; 2081 Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC); 2082 2083 cGroups = pLoggerInt->cGroups; 1944 2084 1945 2085 /* 1946 2086 * Check if all are the same. 1947 2087 */ 1948 fGroup = pLogger ->afGroups[0];2088 fGroup = pLoggerInt->afGroups[0]; 1949 2089 for (i = 1; i < cGroups; i++) 1950 if (pLogger ->afGroups[i] != fGroup)2090 if (pLoggerInt->afGroups[i] != fGroup) 1951 2091 break; 1952 2092 if (i >= cGroups) … … 1960 2100 for (i = 0; i < cGroups; i++) 1961 2101 { 1962 fGroup = pLogger ->afGroups[i];2102 fGroup = pLoggerInt->afGroups[i]; 1963 2103 if (fGroup) 1964 2104 { 1965 const char *pszName = pLogger ->pInt->papszGroups[i];2105 const char *pszName = pLoggerInt->papszGroups[i]; 1966 2106 if (pszName) 1967 2107 { … … 1992 2132 RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue) 1993 2133 { 1994 int rc = VINF_SUCCESS; 2134 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2135 int rc = VINF_SUCCESS; 1995 2136 1996 2137 /* 1997 2138 * Resolve defaults. 1998 2139 */ 1999 if (!pLogger )2000 { 2001 pLogger =RTLogDefaultInstance();2002 if (!pLogger )2140 if (!pLoggerInt) 2141 { 2142 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2143 if (!pLoggerInt) 2003 2144 return VINF_SUCCESS; 2004 2145 } … … 2046 2187 if (!strncmp(pszValue, g_aLogFlags[i].pszInstr, g_aLogFlags[i].cchInstr)) 2047 2188 { 2048 if (!(g_aLogFlags[i].fFixedDest & pLogger ->fDestFlags))2189 if (!(g_aLogFlags[i].fFixedDest & pLoggerInt->fDestFlags)) 2049 2190 { 2050 2191 if (fNo == g_aLogFlags[i].fInverted) 2051 pLogger ->fFlags |= g_aLogFlags[i].fFlag;2192 pLoggerInt->fFlags |= g_aLogFlags[i].fFlag; 2052 2193 else 2053 pLogger ->fFlags &= ~g_aLogFlags[i].fFlag;2194 pLoggerInt->fFlags &= ~g_aLogFlags[i].fFlag; 2054 2195 } 2055 2196 pszValue += g_aLogFlags[i].cchInstr; … … 2087 2228 RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered) 2088 2229 { 2089 bool fOld; 2230 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2231 bool fOld; 2090 2232 2091 2233 /* 2092 2234 * Resolve the logger instance. 2093 2235 */ 2094 if (!pLogger )2095 { 2096 pLogger =RTLogDefaultInstance();2097 if (!pLogger )2236 if (!pLoggerInt) 2237 { 2238 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2239 if (!pLoggerInt) 2098 2240 return false; 2099 2241 } 2100 2242 2101 rtlogLock(pLogger );2102 fOld = !!(pLogger ->fFlags & RTLOGFLAGS_BUFFERED);2243 rtlogLock(pLoggerInt); 2244 fOld = !!(pLoggerInt->fFlags & RTLOGFLAGS_BUFFERED); 2103 2245 if (fBuffered) 2104 pLogger ->fFlags |= RTLOGFLAGS_BUFFERED;2246 pLoggerInt->fFlags |= RTLOGFLAGS_BUFFERED; 2105 2247 else 2106 pLogger ->fFlags &= ~RTLOGFLAGS_BUFFERED;2107 rtlogUnlock(pLogger );2248 pLoggerInt->fFlags &= ~RTLOGFLAGS_BUFFERED; 2249 rtlogUnlock(pLoggerInt); 2108 2250 2109 2251 return fOld; … … 2115 2257 RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup) 2116 2258 { 2259 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2260 2117 2261 /* 2118 2262 * Resolve the logger instance. 2119 2263 */ 2120 if (!pLogger )2121 { 2122 pLogger =RTLogDefaultInstance();2123 if (!pLogger )2264 if (!pLoggerInt) 2265 { 2266 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2267 if (!pLoggerInt) 2124 2268 return UINT32_MAX; 2125 2269 } 2126 2270 2127 rtlogLock(pLogger );2128 uint32_t cOld = pLogger ->pInt->cMaxEntriesPerGroup;2129 pLogger ->pInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup;2130 rtlogUnlock(pLogger );2271 rtlogLock(pLoggerInt); 2272 uint32_t cOld = pLoggerInt->cMaxEntriesPerGroup; 2273 pLoggerInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup; 2274 rtlogUnlock(pLoggerInt); 2131 2275 2132 2276 return cOld; 2133 2277 } 2278 #endif 2279 2280 2281 #ifdef IN_RING0 2282 RTR0DECL(int) RTLogSetR0ThreadNameF(PRTLOGGER pLogger, const char *pszNameFmt, ...) 2283 { 2284 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2285 int rc; 2286 if (pLoggerInt) 2287 { 2288 va_list va; 2289 va_start(va, pszNameFmt); 2290 2291 rc = rtlogLock(pLoggerInt); 2292 if (RT_SUCCESS(rc)) 2293 { 2294 ssize_t cch = RTStrPrintf2V(pLoggerInt->szR0ThreadName, sizeof(pLoggerInt->szR0ThreadName), pszNameFmt, va); 2295 rtlogUnlock(pLoggerInt); 2296 rc = cch > 0 ? VINF_SUCCESS : VERR_BUFFER_OVERFLOW; 2297 } 2298 2299 va_end(va); 2300 } 2301 else 2302 rc = VERR_INVALID_PARAMETER; 2303 return rc; 2304 } 2305 RT_EXPORT_SYMBOL(RTLogSetR0ThreadNameF); 2134 2306 #endif 2135 2307 … … 2144 2316 RTDECL(uint64_t) RTLogGetFlags(PRTLOGGER pLogger) 2145 2317 { 2146 if (!pLogger) 2147 { 2148 pLogger = RTLogDefaultInstance(); 2149 if (!pLogger) 2318 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2319 if (!pLoggerInt) 2320 { 2321 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2322 if (!pLoggerInt) 2150 2323 return UINT64_MAX; 2151 2324 } 2152 return pLogger ->fFlags;2325 return pLoggerInt->fFlags; 2153 2326 } 2154 2327 RT_EXPORT_SYMBOL(RTLogGetFlags); 2328 2329 2330 /** 2331 * Modifies the flag settings for the given logger. 2332 * 2333 * @returns IPRT status code. Returns VINF_SUCCESS if no default logger and @a 2334 * pLogger is NULL. 2335 * @param pLogger Logger instance (NULL for default logger). 2336 * @param fSet Mask of flags to set (OR). 2337 * @param fClear Mask of flags to clear (NAND). This is allowed to 2338 * include invalid flags - e.g. UINT64_MAX is okay. 2339 */ 2340 RTDECL(int) RTLogChangeFlags(PRTLOGGER pLogger, uint64_t fSet, uint64_t fClear) 2341 { 2342 AssertReturn(!(fSet & ~RTLOG_F_VALID_MASK), VERR_INVALID_FLAGS); 2343 2344 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2345 if (!pLoggerInt) 2346 { 2347 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2348 if (!pLoggerInt) 2349 return VINF_SUCCESS; 2350 } 2351 AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 2352 AssertReturn(pLoggerInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH); 2353 2354 /* 2355 * Make the changes. 2356 */ 2357 pLoggerInt->fFlags &= ~fClear; 2358 pLoggerInt->fFlags |= fSet; 2359 2360 return VINF_SUCCESS; 2361 } 2362 RT_EXPORT_SYMBOL(RTLogChangeFlags); 2155 2363 2156 2364 … … 2166 2374 RTDECL(int) RTLogQueryFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf) 2167 2375 { 2168 bool fNotFirst = false; 2169 int rc = VINF_SUCCESS; 2170 uint32_t fFlags; 2171 unsigned i; 2376 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2377 bool fNotFirst = false; 2378 int rc = VINF_SUCCESS; 2379 uint32_t fFlags; 2380 unsigned i; 2172 2381 2173 2382 Assert(cchBuf); … … 2176 2385 * Resolve defaults. 2177 2386 */ 2178 if (!pLogger )2179 { 2180 pLogger =RTLogDefaultInstance();2181 if (!pLogger )2387 if (!pLoggerInt) 2388 { 2389 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2390 if (!pLoggerInt) 2182 2391 { 2183 2392 *pszBuf = '\0'; … … 2189 2398 * Add the flags in the list. 2190 2399 */ 2191 fFlags = pLogger ->fFlags;2400 fFlags = pLoggerInt->fFlags; 2192 2401 for (i = 0; i < RT_ELEMENTS(g_aLogFlags); i++) 2193 2402 if ( !g_aLogFlags[i].fInverted … … 2272 2481 * Resolve defaults. 2273 2482 */ 2274 if (!pLogger) 2275 { 2276 pLogger = RTLogDefaultInstance(); 2277 if (!pLogger) 2483 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2484 if (!pLoggerInt) 2485 { 2486 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2487 if (!pLoggerInt) 2278 2488 return VINF_SUCCESS; 2279 2489 } … … 2313 2523 { 2314 2524 if (!fNo) 2315 pLogger ->fDestFlags |= g_aLogDst[i].fFlag;2525 pLoggerInt->fDestFlags |= g_aLogDst[i].fFlag; 2316 2526 else 2317 pLogger ->fDestFlags &= ~g_aLogDst[i].fFlag;2527 pLoggerInt->fDestFlags &= ~g_aLogDst[i].fFlag; 2318 2528 pszValue += cchInstr; 2319 2529 … … 2328 2538 2329 2539 # ifdef IN_RING3 2330 char szTmp[sizeof(pLogger ->pInt->szFilename)];2540 char szTmp[sizeof(pLoggerInt->szFilename)]; 2331 2541 # else 2332 2542 char szTmp[32]; … … 2334 2544 if (0) 2335 2545 { /* nothing */ } 2336 # ifdef IN_RING32546 # ifdef IN_RING3 2337 2547 2338 2548 /* log file name */ 2339 2549 else if (i == 0 /* file */ && !fNo) 2340 2550 { 2341 if (!(pLogger ->fDestFlags & RTLOGDEST_FIXED_FILE))2551 if (!(pLoggerInt->fDestFlags & RTLOGDEST_FIXED_FILE)) 2342 2552 { 2343 AssertReturn(cch < sizeof(pLogger ->pInt->szFilename), VERR_OUT_OF_RANGE);2344 memcpy(pLogger ->pInt->szFilename, pszValue, cch);2345 pLogger ->pInt->szFilename[cch] = '\0';2346 /** @todo reopen log file if pLogger ->pInt->fCreated is true ... */2553 AssertReturn(cch < sizeof(pLoggerInt->szFilename), VERR_OUT_OF_RANGE); 2554 memcpy(pLoggerInt->szFilename, pszValue, cch); 2555 pLoggerInt->szFilename[cch] = '\0'; 2556 /** @todo reopen log file if pLoggerInt->fCreated is true ... */ 2347 2557 } 2348 2558 } … … 2350 2560 else if (i == 1 /* dir */ && !fNo) 2351 2561 { 2352 if (!(pLogger ->fDestFlags & RTLOGDEST_FIXED_DIR))2562 if (!(pLoggerInt->fDestFlags & RTLOGDEST_FIXED_DIR)) 2353 2563 { 2354 const char *pszFile = RTPathFilename(pLogger ->pInt->szFilename);2564 const char *pszFile = RTPathFilename(pLoggerInt->szFilename); 2355 2565 size_t cchFile = pszFile ? strlen(pszFile) : 0; 2356 AssertReturn(cchFile + cch + 1 < sizeof(pLogger ->pInt->szFilename), VERR_OUT_OF_RANGE);2566 AssertReturn(cchFile + cch + 1 < sizeof(pLoggerInt->szFilename), VERR_OUT_OF_RANGE); 2357 2567 memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1); 2358 2568 2359 memcpy(pLogger ->pInt->szFilename, pszValue, cch);2360 pLogger ->pInt->szFilename[cch] = '\0';2361 RTPathStripTrailingSlash(pLogger ->pInt->szFilename);2362 2363 cch = strlen(pLogger ->pInt->szFilename);2364 pLogger ->pInt->szFilename[cch++] = '/';2365 memcpy(&pLogger ->pInt->szFilename[cch], szTmp, cchFile);2366 pLogger ->pInt->szFilename[cch + cchFile] = '\0';2367 /** @todo reopen log file if pLogger ->pInt->fCreated is true ... */2569 memcpy(pLoggerInt->szFilename, pszValue, cch); 2570 pLoggerInt->szFilename[cch] = '\0'; 2571 RTPathStripTrailingSlash(pLoggerInt->szFilename); 2572 2573 cch = strlen(pLoggerInt->szFilename); 2574 pLoggerInt->szFilename[cch++] = '/'; 2575 memcpy(&pLoggerInt->szFilename[cch], szTmp, cchFile); 2576 pLoggerInt->szFilename[cch + cchFile] = '\0'; 2577 /** @todo reopen log file if pLoggerInt->fCreated is true ... */ 2368 2578 } 2369 2579 } … … 2377 2587 rc = RTStrToUInt32Full(szTmp, 0, &cHistory); 2378 2588 AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc); 2379 pLogger ->pInt->cHistory = cHistory;2589 pLoggerInt->cHistory = cHistory; 2380 2590 } 2381 2591 else 2382 pLogger ->pInt->cHistory = 0;2592 pLoggerInt->cHistory = 0; 2383 2593 } 2384 2594 else if (i == 3 /* histsize */) … … 2388 2598 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch); 2389 2599 if (RT_SUCCESS(rc)) 2390 rc = RTStrToUInt64Full(szTmp, 0, &pLogger ->pInt->cbHistoryFileMax);2600 rc = RTStrToUInt64Full(szTmp, 0, &pLoggerInt->cbHistoryFileMax); 2391 2601 AssertMsgRCReturn(rc, ("Invalid history file size value %s (%Rrc)!\n", szTmp, rc), rc); 2392 if (pLogger ->pInt->cbHistoryFileMax == 0)2393 pLogger ->pInt->cbHistoryFileMax = UINT64_MAX;2602 if (pLoggerInt->cbHistoryFileMax == 0) 2603 pLoggerInt->cbHistoryFileMax = UINT64_MAX; 2394 2604 } 2395 2605 else 2396 pLogger ->pInt->cbHistoryFileMax = UINT64_MAX;2606 pLoggerInt->cbHistoryFileMax = UINT64_MAX; 2397 2607 } 2398 2608 else if (i == 4 /* histtime */) … … 2402 2612 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch); 2403 2613 if (RT_SUCCESS(rc)) 2404 rc = RTStrToUInt32Full(szTmp, 0, &pLogger ->pInt->cSecsHistoryTimeSlot);2614 rc = RTStrToUInt32Full(szTmp, 0, &pLoggerInt->cSecsHistoryTimeSlot); 2405 2615 AssertMsgRCReturn(rc, ("Invalid history time slot value %s (%Rrc)!\n", szTmp, rc), rc); 2406 if (pLogger ->pInt->cSecsHistoryTimeSlot == 0)2407 pLogger ->pInt->cSecsHistoryTimeSlot = UINT32_MAX;2616 if (pLoggerInt->cSecsHistoryTimeSlot == 0) 2617 pLoggerInt->cSecsHistoryTimeSlot = UINT32_MAX; 2408 2618 } 2409 2619 else 2410 pLogger ->pInt->cSecsHistoryTimeSlot = UINT32_MAX;2620 pLoggerInt->cSecsHistoryTimeSlot = UINT32_MAX; 2411 2621 } 2412 2622 # endif /* IN_RING3 */ … … 2427 2637 else 2428 2638 cbRingBuf = RT_ALIGN_32(cbRingBuf, 64); 2429 rc = rtLogRingBufAdjust(pLogger , cbRingBuf, false /*fForce*/);2639 rc = rtLogRingBufAdjust(pLoggerInt, cbRingBuf, false /*fForce*/); 2430 2640 if (RT_FAILURE(rc)) 2431 2641 return rc; … … 2438 2648 pszValue = pszEnd + (*pszEnd != '\0'); 2439 2649 } 2440 else if (i == 5 /* ringbuf */ && !fNo && !pLogger ->pInt->pszRingBuf)2650 else if (i == 5 /* ringbuf */ && !fNo && !pLoggerInt->pszRingBuf) 2441 2651 { 2442 int rc = rtLogRingBufAdjust(pLogger , pLogger->pInt->cbRingBuf, false /*fForce*/);2652 int rc = rtLogRingBufAdjust(pLoggerInt, pLoggerInt->cbRingBuf, false /*fForce*/); 2443 2653 if (RT_FAILURE(rc)) 2444 2654 return rc; … … 2476 2686 * Resolve defaults. 2477 2687 */ 2478 if (!pLogger) 2479 { 2480 pLogger = RTLogDefaultInstance(); 2481 if (!pLogger) 2688 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2689 if (!pLoggerInt) 2690 { 2691 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2692 if (!pLoggerInt) 2482 2693 return VINF_SUCCESS; 2483 2694 } … … 2486 2697 * Do the work. 2487 2698 */ 2488 int rc = rtlogLock(pLogger );2699 int rc = rtlogLock(pLoggerInt); 2489 2700 if (RT_SUCCESS(rc)) 2490 2701 { 2491 if (pLogger ->fDestFlags & RTLOGDEST_F_DELAY_FILE)2492 { 2493 pLogger ->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE;2702 if (pLoggerInt->fDestFlags & RTLOGDEST_F_DELAY_FILE) 2703 { 2704 pLoggerInt->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE; 2494 2705 # ifdef IN_RING3 2495 if ( pLogger ->fDestFlags & RTLOGDEST_FILE2496 && pLogger ->pInt->hFile == NIL_RTFILE)2706 if ( pLoggerInt->fDestFlags & RTLOGDEST_FILE 2707 && pLoggerInt->hFile == NIL_RTFILE) 2497 2708 { 2498 rc = rtR3LogOpenFileDestination(pLogger , pErrInfo);2709 rc = rtR3LogOpenFileDestination(pLoggerInt, pErrInfo); 2499 2710 if (RT_SUCCESS(rc)) 2500 rtlogFlush(pLogger , false /*fNeedSpace*/);2711 rtlogFlush(pLoggerInt, false /*fNeedSpace*/); 2501 2712 } 2502 2713 # endif 2503 2714 RT_NOREF(pErrInfo); /** @todo fix create API to use RTErrInfo */ 2504 2715 } 2505 rtlogUnlock(pLogger );2716 rtlogUnlock(pLoggerInt); 2506 2717 } 2507 2718 return VINF_SUCCESS; 2508 2719 } 2509 2720 RT_EXPORT_SYMBOL(RTLogClearFileDelayFlag); 2721 2722 2723 /** 2724 * Modifies the log destinations settings for the given logger. 2725 * 2726 * This is only suitable for simple destination settings that doesn't take 2727 * additional arguments, like RTLOGDEST_FILE. 2728 * 2729 * @returns IPRT status code. Returns VINF_SUCCESS if no default logger and @a 2730 * pLogger is NULL. 2731 * @param pLogger Logger instance (NULL for default logger). 2732 * @param fSet Mask of destinations to set (OR). 2733 * @param fClear Mask of destinations to clear (NAND). 2734 */ 2735 RTDECL(int) RTLogChangeDestinations(PRTLOGGER pLogger, uint32_t fSet, uint32_t fClear) 2736 { 2737 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2738 AssertCompile((RTLOG_DST_VALID_MASK & RTLOG_DST_CHANGE_MASK) == RTLOG_DST_CHANGE_MASK); 2739 AssertReturn(!(fSet & ~RTLOG_DST_CHANGE_MASK), VERR_INVALID_FLAGS); 2740 AssertReturn(!(fClear & ~RTLOG_DST_CHANGE_MASK), VERR_INVALID_FLAGS); 2741 2742 /* 2743 * Resolve defaults. 2744 */ 2745 if (!pLoggerInt) 2746 { 2747 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2748 if (!pLoggerInt) 2749 return VINF_SUCCESS; 2750 } 2751 AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 2752 AssertReturn(pLoggerInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH); 2753 2754 /* 2755 * Make the changes. 2756 */ 2757 pLoggerInt->fDestFlags &= ~fClear; 2758 pLoggerInt->fDestFlags |= fSet; 2759 2760 return VINF_SUCCESS; 2761 } 2762 RT_EXPORT_SYMBOL(RTLogChangeDestinations); 2763 2764 2765 /** 2766 * Gets the current destinations flags for the given logger. 2767 * 2768 * @returns Logger destination flags, UINT32_MAX if no logger. 2769 * @param pLogger Logger instance (NULL for default logger). 2770 */ 2771 RTDECL(uint32_t) RTLogGetDestinations(PRTLOGGER pLogger) 2772 { 2773 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2774 if (!pLoggerInt) 2775 { 2776 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2777 if (!pLoggerInt) 2778 return UINT32_MAX; 2779 } 2780 return pLoggerInt->fFlags; 2781 } 2782 RT_EXPORT_SYMBOL(RTLogGetDestinations); 2510 2783 2511 2784 … … 2521 2794 RTDECL(int) RTLogQueryDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf) 2522 2795 { 2523 bool fNotFirst = false; 2524 int rc = VINF_SUCCESS; 2525 uint32_t fDestFlags; 2526 unsigned i; 2796 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2797 bool fNotFirst = false; 2798 int rc = VINF_SUCCESS; 2799 uint32_t fDestFlags; 2800 unsigned i; 2527 2801 2528 2802 AssertReturn(cchBuf, VERR_INVALID_PARAMETER); … … 2532 2806 * Resolve defaults. 2533 2807 */ 2534 if (!pLogger )2535 { 2536 pLogger =RTLogDefaultInstance();2537 if (!pLogger )2808 if (!pLoggerInt) 2809 { 2810 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 2811 if (!pLoggerInt) 2538 2812 return VINF_SUCCESS; 2539 2813 } … … 2542 2816 * Add the flags in the list. 2543 2817 */ 2544 fDestFlags = pLogger ->fDestFlags;2818 fDestFlags = pLoggerInt->fDestFlags; 2545 2819 for (i = 6; i < RT_ELEMENTS(g_aLogDst); i++) 2546 2820 if (g_aLogDst[i].fFlag & fDestFlags) … … 2569 2843 if (RT_FAILURE(rc)) 2570 2844 return rc; 2571 rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger ->pInt->szFilename);2845 rc = RTStrCopyP(&pszBuf, &cchBuf, pLoggerInt->szFilename); 2572 2846 if (RT_FAILURE(rc)) 2573 2847 return rc; 2574 2848 fNotFirst = true; 2575 2849 2576 if (pLogger ->pInt->cHistory)2577 { 2578 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " history=%u" : "history=%u", pLogger ->pInt->cHistory);2850 if (pLoggerInt->cHistory) 2851 { 2852 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " history=%u" : "history=%u", pLoggerInt->cHistory); 2579 2853 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 2580 2854 if (RT_FAILURE(rc)) … … 2582 2856 fNotFirst = true; 2583 2857 } 2584 if (pLogger ->pInt->cbHistoryFileMax != UINT64_MAX)2585 { 2586 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histsize=%llu" : "histsize=%llu", pLogger ->pInt->cbHistoryFileMax);2858 if (pLoggerInt->cbHistoryFileMax != UINT64_MAX) 2859 { 2860 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histsize=%llu" : "histsize=%llu", pLoggerInt->cbHistoryFileMax); 2587 2861 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 2588 2862 if (RT_FAILURE(rc)) … … 2590 2864 fNotFirst = true; 2591 2865 } 2592 if (pLogger ->pInt->cSecsHistoryTimeSlot != UINT32_MAX)2593 { 2594 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histtime=%llu" : "histtime=%llu", pLogger ->pInt->cSecsHistoryTimeSlot);2866 if (pLoggerInt->cSecsHistoryTimeSlot != UINT32_MAX) 2867 { 2868 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histtime=%llu" : "histtime=%llu", pLoggerInt->cSecsHistoryTimeSlot); 2595 2869 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 2596 2870 if (RT_FAILURE(rc)) … … 2606 2880 if (fDestFlags & RTLOGDEST_RINGBUF) 2607 2881 { 2608 if (pLogger ->pInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE)2882 if (pLoggerInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE) 2609 2883 rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " ringbuf" : "ringbuf"); 2610 2884 else 2611 2885 { 2612 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " ringbuf=%#x" : "ringbuf=%#x", pLogger ->pInt->cbRingBuf);2886 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " ringbuf=%#x" : "ringbuf=%#x", pLoggerInt->cbRingBuf); 2613 2887 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 2614 2888 } … … 2622 2896 RT_EXPORT_SYMBOL(RTLogQueryDestinations); 2623 2897 2898 2899 /** 2900 * Helper for calculating the CRC32 of all the group names. 2901 */ 2902 static uint32_t rtLogCalcGroupNameCrc32(PRTLOGGERINTERNAL pLoggerInt) 2903 { 2904 const char * const * const papszGroups = pLoggerInt->papszGroups; 2905 uint32_t iGroup = pLoggerInt->cGroups; 2906 uint32_t uCrc32 = RTCrc32Start(); 2907 while (iGroup-- > 0) 2908 { 2909 const char *pszGroup = papszGroups[iGroup]; 2910 uCrc32 = RTCrc32Process(uCrc32, pszGroup, strlen(pszGroup) + 1); 2911 } 2912 return RTCrc32Finish(uCrc32); 2913 } 2914 2915 2916 /** 2917 * Performs a bulk update of logger flags and group flags. 2918 * 2919 * This is for instanced used for copying settings from ring-3 to ring-0 2920 * loggers. 2921 * 2922 * @returns IPRT status code. 2923 * @param pLogger The logger instance (NULL for default logger). 2924 * @param fFlags The new logger flags. 2925 * @param uGroupCrc32 The CRC32 of the group name strings. 2926 * @param cGroups Number of groups. 2927 * @param pafGroups Array of group flags. 2928 * @sa RTLogQueryBulk 2929 */ 2930 RTDECL(int) RTLogBulkUpdate(PRTLOGGER pLogger, uint64_t fFlags, uint32_t uGroupCrc32, uint32_t cGroups, uint32_t const *pafGroups) 2931 { 2932 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2933 int rc; 2934 2935 /* 2936 * Resolve defaults. 2937 */ 2938 if (!pLoggerInt) 2939 { 2940 pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger; 2941 if (!pLoggerInt) 2942 return VINF_SUCCESS; 2943 } 2944 2945 /* 2946 * Do the updating. 2947 */ 2948 rc = rtlogLock(pLoggerInt); 2949 if (RT_SUCCESS(rc)) 2950 { 2951 pLoggerInt->fFlags = fFlags; 2952 if ( uGroupCrc32 == rtLogCalcGroupNameCrc32(pLoggerInt) 2953 && pLoggerInt->cGroups == cGroups) 2954 { 2955 memcpy(pLoggerInt->afGroups, pafGroups, sizeof(pLoggerInt->afGroups[0]) * cGroups); 2956 rc = VINF_SUCCESS; 2957 } 2958 else 2959 rc = VERR_MISMATCH; 2960 2961 rtlogUnlock(pLoggerInt); 2962 } 2963 return rc; 2964 } 2965 RT_EXPORT_SYMBOL(RTLogBulkUpdate); 2966 2967 2968 /** 2969 * Queries data for a bulk update of logger flags and group flags. 2970 * 2971 * This is for instanced used for copying settings from ring-3 to ring-0 2972 * loggers. 2973 * 2974 * @returns IPRT status code. 2975 * @retval VERR_BUFFER_OVERFLOW if pafGroups is too small, @a pcGroups will be 2976 * set to the actual number of groups. 2977 * @param pLogger The logger instance (NULL for default logger). 2978 * @param pfFlags Where to return the logger flags. 2979 * @param puGroupCrc32 Where to return the CRC32 of the group names. 2980 * @param pcGroups Input: Size of the @a pafGroups allocation. 2981 * Output: Actual number of groups returned. 2982 * @param pafGroups Where to return the flags for each group. 2983 * @sa RTLogBulkUpdate 2984 */ 2985 RTDECL(int) RTLogQueryBulk(PRTLOGGER pLogger, uint64_t *pfFlags, uint32_t *puGroupCrc32, uint32_t *pcGroups, uint32_t *pafGroups) 2986 { 2987 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 2988 uint32_t const cGroupsAlloc = *pcGroups; 2989 2990 /* 2991 * Resolve defaults. 2992 */ 2993 if (!pLoggerInt) 2994 { 2995 pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger; 2996 if (!pLoggerInt) 2997 { 2998 *pfFlags = 0; 2999 *puGroupCrc32 = 0; 3000 *pcGroups = 0; 3001 return VINF_SUCCESS; 3002 } 3003 } 3004 AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 3005 3006 /* 3007 * Get the data. 3008 */ 3009 *pfFlags = pLoggerInt->fFlags; 3010 *pcGroups = pLoggerInt->cGroups; 3011 if (cGroupsAlloc >= pLoggerInt->cGroups) 3012 { 3013 memcpy(pafGroups, pLoggerInt->afGroups, sizeof(pLoggerInt->afGroups[0]) * pLoggerInt->cGroups); 3014 *puGroupCrc32 = rtLogCalcGroupNameCrc32(pLoggerInt); 3015 return VINF_SUCCESS; 3016 } 3017 *puGroupCrc32 = 0; 3018 return VERR_BUFFER_OVERFLOW; 3019 } 3020 RT_EXPORT_SYMBOL(RTLogQueryBulk); 3021 3022 3023 /** 3024 * Write/copy bulk log data from another logger. 3025 * 3026 * This is used for transferring stuff from the ring-0 loggers and into the 3027 * ring-3 one. The text goes in as-is w/o any processing (i.e. prefixing or 3028 * newline fun). 3029 * 3030 * @returns IRPT status code. 3031 * @param pLogger The logger instance (NULL for default logger). 3032 * @param pch Pointer to the block of bulk log text to write. 3033 * @param cch Size of the block of bulk log text to write. 3034 */ 3035 RTDECL(int) RTLogBulkWrite(PRTLOGGER pLogger, const char *pch, size_t cch) 3036 { 3037 /* 3038 * Resolve defaults. 3039 */ 3040 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 3041 if (!pLoggerInt) 3042 { 3043 pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger; 3044 if (!pLoggerInt) 3045 return VINF_SUCCESS; 3046 } 3047 3048 /* 3049 * Lock and validate it. 3050 */ 3051 int rc = rtlogLock(pLoggerInt); 3052 if (RT_SUCCESS(rc)) 3053 { 3054 /* 3055 * Do the copying. 3056 */ 3057 while (cch > 0) 3058 { 3059 PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc; 3060 char * const pchBuf = pBufDesc->pchBuf; 3061 uint32_t const cbBuf = pBufDesc->cbBuf; 3062 uint32_t offBuf = pBufDesc->offBuf; 3063 if (cch + 1 < cbBuf - offBuf) 3064 { 3065 memcpy(&pchBuf[offBuf], pch, cch); 3066 offBuf += (uint32_t)cch; 3067 pchBuf[offBuf] = '\0'; 3068 pBufDesc->offBuf = offBuf; 3069 if (pBufDesc->pAux) 3070 pBufDesc->pAux->offBuf = offBuf; 3071 if (!(pLoggerInt->fDestFlags & RTLOGFLAGS_BUFFERED)) 3072 rtlogFlush(pLoggerInt, false /*fNeedSpace*/); 3073 break; 3074 } 3075 3076 /* Not enough space. */ 3077 if (offBuf + 1 < cbBuf) 3078 { 3079 uint32_t cbToCopy = cbBuf - offBuf - 1; 3080 memcpy(&pchBuf[offBuf], pch, cbToCopy); 3081 offBuf += cbToCopy; 3082 pchBuf[offBuf] = '\0'; 3083 pBufDesc->offBuf = offBuf; 3084 if (pBufDesc->pAux) 3085 pBufDesc->pAux->offBuf = offBuf; 3086 pch += cbToCopy; 3087 cch -= cbToCopy; 3088 } 3089 3090 rtlogFlush(pLoggerInt, false /*fNeedSpace*/); 3091 } 3092 3093 rtlogUnlock(pLoggerInt); 3094 } 3095 return rc; 3096 } 3097 RT_EXPORT_SYMBOL(RTLogBulkWrite); 3098 2624 3099 #endif /* !IN_RC */ 2625 3100 … … 2636 3111 * Resolve defaults. 2637 3112 */ 2638 if (!pLogger) 2639 { 2640 #ifdef IN_RC 2641 pLogger = &g_Logger; 2642 #else 2643 pLogger = g_pLogger; 2644 #endif 2645 if (!pLogger) 3113 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 3114 if (!pLoggerInt) 3115 { 3116 pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger; 3117 if (!pLoggerInt) 2646 3118 return; 2647 3119 } 3120 Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC); 3121 AssertPtr(pLoggerInt->pBufDesc); 3122 Assert(pLoggerInt->pBufDesc->u32Magic == RTLOGBUFFERDESC_MAGIC); 2648 3123 2649 3124 /* 2650 3125 * Any thing to flush? 2651 3126 */ 2652 if ( pLogger->offScratch 2653 #ifndef IN_RC 2654 || (pLogger->fDestFlags & RTLOGDEST_RINGBUF) 2655 #endif 2656 ) 2657 { 2658 #ifndef IN_RC 3127 if ( pLoggerInt->pBufDesc->offBuf > 0 3128 || (pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF)) 3129 { 2659 3130 /* 2660 3131 * Acquire logger instance sem. 2661 3132 */ 2662 int rc = rtlogLock(pLogger); 2663 if (RT_FAILURE(rc)) 2664 return; 2665 #endif 2666 /* 2667 * Call worker. 2668 */ 2669 rtlogFlush(pLogger, false /*fNeedSpace*/); 2670 2671 #ifndef IN_RC 2672 /* 2673 * Since this is an explicit flush call, the ring buffer content should 2674 * be flushed to the other destinations if active. 2675 */ 2676 if ( (pLogger->fDestFlags & RTLOGDEST_RINGBUF) 2677 && pLogger->pInt->pszRingBuf /* paranoia */) 2678 rtLogRingBufFlush(pLogger); 2679 2680 /* 2681 * Release the semaphore. 2682 */ 2683 rtlogUnlock(pLogger); 2684 #endif 3133 int rc = rtlogLock(pLoggerInt); 3134 if (RT_SUCCESS(rc)) 3135 { 3136 /* 3137 * Call worker. 3138 */ 3139 rtlogFlush(pLoggerInt, false /*fNeedSpace*/); 3140 3141 /* 3142 * Since this is an explicit flush call, the ring buffer content should 3143 * be flushed to the other destinations if active. 3144 */ 3145 if ( (pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF) 3146 && pLoggerInt->pszRingBuf /* paranoia */) 3147 rtLogRingBufFlush(pLoggerInt); 3148 3149 /* 3150 * Release the semaphore. 3151 */ 3152 rtlogUnlock(pLoggerInt); 3153 } 2685 3154 } 2686 3155 } … … 2728 3197 2729 3198 3199 /** 3200 * Worker for RTLogDefaultInstanceEx, RTLogGetDefaultInstanceEx, 3201 * RTLogRelGetDefaultInstanceEx and RTLogCheckGroupFlags. 3202 */ 3203 DECL_FORCE_INLINE(PRTLOGGERINTERNAL) rtLogCheckGroupFlagsWorker(PRTLOGGERINTERNAL pLoggerInt, uint32_t fFlagsAndGroup) 3204 { 3205 if (pLoggerInt->fFlags & RTLOGFLAGS_DISABLED) 3206 pLoggerInt = NULL; 3207 else 3208 { 3209 uint32_t const fFlags = RT_LO_U16(fFlagsAndGroup); 3210 uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup); 3211 if ( iGroup != UINT16_MAX 3212 && ( (pLoggerInt->afGroups[iGroup < pLoggerInt->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED)) 3213 != (fFlags | RTLOGGRPFLAGS_ENABLED))) 3214 pLoggerInt = NULL; 3215 } 3216 return pLoggerInt; 3217 } 3218 3219 2730 3220 RTDECL(PRTLOGGER) RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup) 2731 3221 { 2732 PRTLOGGER pLogger = rtLogDefaultInstanceCommon(); 2733 if (pLogger) 2734 { 2735 if (pLogger->fFlags & RTLOGFLAGS_DISABLED) 2736 pLogger = NULL; 2737 else 2738 { 2739 uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup); 2740 uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup); 2741 if ( iGroup != UINT16_MAX 2742 && ( (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED)) 2743 != (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED))) 2744 pLogger = NULL; 2745 } 2746 } 2747 return pLogger; 3222 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)rtLogDefaultInstanceCommon(); 3223 if (pLoggerInt) 3224 pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup); 3225 AssertCompileMemberOffset(RTLOGGERINTERNAL, Core, 0); 3226 return (PRTLOGGER)pLoggerInt; 2748 3227 } 2749 3228 RT_EXPORT_SYMBOL(RTLogDefaultInstanceEx); … … 2786 3265 RTDECL(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup) 2787 3266 { 2788 PRTLOGGER pLogger = rtLogGetDefaultInstanceCommon(); 2789 if (pLogger) 2790 { 2791 if (pLogger->fFlags & RTLOGFLAGS_DISABLED) 2792 pLogger = NULL; 2793 else 2794 { 2795 uint32_t const fFlags = RT_LO_U16(fFlagsAndGroup); 2796 uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup); 2797 if ( iGroup != UINT16_MAX 2798 && ( (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED)) 2799 != (fFlags | RTLOGGRPFLAGS_ENABLED))) 2800 pLogger = NULL; 2801 } 2802 } 2803 return pLogger; 3267 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)rtLogGetDefaultInstanceCommon(); 3268 if (pLoggerInt) 3269 pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup); 3270 AssertCompileMemberOffset(RTLOGGERINTERNAL, Core, 0); 3271 return (PRTLOGGER)pLoggerInt; 2804 3272 } 2805 3273 RT_EXPORT_SYMBOL(RTLogGetDefaultInstanceEx); … … 2908 3376 2909 3377 3378 RTDECL(PRTLOGGER) RTLogRelGetDefaultInstance(void) 3379 { 3380 #ifdef IN_RC 3381 return &g_RelLogger; 3382 #else /* !IN_RC */ 3383 return g_pRelLogger; 3384 #endif /* !IN_RC */ 3385 } 3386 RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstance); 3387 3388 3389 RTDECL(PRTLOGGER) RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup) 3390 { 3391 #ifdef IN_RC 3392 PRTLOGGERINTERNAL pLoggerInt = &g_RelLogger; 3393 #else 3394 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)g_pRelLogger; 3395 #endif 3396 if (pLoggerInt) 3397 pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup); 3398 return (PRTLOGGER)pLoggerInt; 3399 } 3400 RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstanceEx); 3401 3402 3403 #ifndef IN_RC 3404 /** 3405 * Sets the default logger instance. 3406 * 3407 * @returns iprt status code. 3408 * @param pLogger The new default release logger instance. 3409 */ 3410 RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger) 3411 { 3412 return ASMAtomicXchgPtrT(&g_pRelLogger, pLogger, PRTLOGGER); 3413 } 3414 RT_EXPORT_SYMBOL(RTLogRelSetDefaultInstance); 3415 #endif /* !IN_RC */ 3416 3417 3418 /** 3419 * 3420 * This is the 2nd half of what RTLogGetDefaultInstanceEx() and 3421 * RTLogRelGetDefaultInstanceEx() does. 3422 * 3423 * @returns If the group has the specified flags enabled @a pLogger will be 3424 * returned returned. Otherwise NULL is returned. 3425 * @param pLogger The logger. NULL is NULL. 3426 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in 3427 * the high 16 bits. 3428 */ 3429 RTDECL(PRTLOGGER) RTLogCheckGroupFlags(PRTLOGGER pLogger, uint32_t fFlagsAndGroup) 3430 { 3431 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 3432 if (pLoggerInt) 3433 pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup); 3434 return (PRTLOGGER)pLoggerInt; 3435 } 3436 RT_EXPORT_SYMBOL(RTLogCheckGroupFlags); 3437 3438 2910 3439 /** 2911 3440 * Write to a logger instance. … … 2938 3467 RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args) 2939 3468 { 2940 int rc; 3469 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger; 3470 int rc; 2941 3471 2942 3472 /* 2943 3473 * A NULL logger means default instance. 2944 3474 */ 2945 if (!pLogger )2946 { 2947 pLogger =RTLogDefaultInstance();2948 if (!pLogger )3475 if (!pLoggerInt) 3476 { 3477 pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance(); 3478 if (!pLoggerInt) 2949 3479 return; 2950 3480 } … … 2953 3483 * Validate and correct iGroup. 2954 3484 */ 2955 if (iGroup != ~0U && iGroup >= pLogger ->cGroups)3485 if (iGroup != ~0U && iGroup >= pLoggerInt->cGroups) 2956 3486 iGroup = 0; 2957 3487 … … 2959 3489 * If no output, then just skip it. 2960 3490 */ 2961 if ( (pLogger ->fFlags & RTLOGFLAGS_DISABLED)3491 if ( (pLoggerInt->fFlags & RTLOGFLAGS_DISABLED) 2962 3492 #ifndef IN_RC 2963 || !pLogger ->fDestFlags3493 || !pLoggerInt->fDestFlags 2964 3494 #endif 2965 3495 || !pszFormat || !*pszFormat) 2966 3496 return; 2967 3497 if ( iGroup != ~0U 2968 && (pLogger ->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))3498 && (pLoggerInt->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED)) 2969 3499 return; 2970 3500 … … 2972 3502 * Acquire logger instance sem. 2973 3503 */ 2974 rc = rtlogLock(pLogger );3504 rc = rtlogLock(pLoggerInt); 2975 3505 if (RT_FAILURE(rc)) 2976 3506 { 2977 3507 #ifdef IN_RING0 2978 if (pLogger ->fDestFlags & ~RTLOGDEST_FILE)2979 rtR0LogLoggerExFallback(pLogger ->fDestFlags, pLogger->fFlags, pLogger->pInt, pszFormat, args);3508 if (pLoggerInt->fDestFlags & ~RTLOGDEST_FILE) 3509 rtR0LogLoggerExFallback(pLoggerInt->fDestFlags, pLoggerInt->fFlags, pLoggerInt, pszFormat, args); 2980 3510 #endif 2981 3511 return; … … 2986 3516 */ 2987 3517 #ifndef IN_RC 2988 if (RT_UNLIKELY( (pLogger ->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)2989 && iGroup < pLogger ->cGroups2990 && (pLogger ->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT)2991 && ++pLogger ->pInt->pacEntriesPerGroup[iGroup] >= pLogger->pInt->cMaxEntriesPerGroup ))2992 { 2993 uint32_t cEntries = pLogger ->pInt->pacEntriesPerGroup[iGroup];2994 if (cEntries > pLogger ->pInt->cMaxEntriesPerGroup)2995 pLogger ->pInt->pacEntriesPerGroup[iGroup] = cEntries - 1;3518 if (RT_UNLIKELY( (pLoggerInt->fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 3519 && iGroup < pLoggerInt->cGroups 3520 && (pLoggerInt->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT) 3521 && ++pLoggerInt->pacEntriesPerGroup[iGroup] >= pLoggerInt->cMaxEntriesPerGroup )) 3522 { 3523 uint32_t cEntries = pLoggerInt->pacEntriesPerGroup[iGroup]; 3524 if (cEntries > pLoggerInt->cMaxEntriesPerGroup) 3525 pLoggerInt->pacEntriesPerGroup[iGroup] = cEntries - 1; 2996 3526 else 2997 3527 { 2998 rtlogLoggerExVLocked(pLogger , fFlags, iGroup, pszFormat, args);2999 if ( pLogger ->pInt->papszGroups3000 && pLogger ->pInt->papszGroups[iGroup])3001 rtlogLoggerExFLocked(pLogger , fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n",3002 cEntries, pLogger ->pInt->papszGroups[iGroup], iGroup);3528 rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, args); 3529 if ( pLoggerInt->papszGroups 3530 && pLoggerInt->papszGroups[iGroup]) 3531 rtlogLoggerExFLocked(pLoggerInt, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n", 3532 cEntries, pLoggerInt->papszGroups[iGroup], iGroup); 3003 3533 else 3004 rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group #%u, muting it.\n", 3005 cEntries, iGroup); 3534 rtlogLoggerExFLocked(pLoggerInt, fFlags, iGroup, "%u messages from group #%u, muting it.\n", cEntries, iGroup); 3006 3535 } 3007 3536 } 3008 3537 else 3009 3538 #endif 3010 rtlogLoggerExVLocked(pLogger , fFlags, iGroup, pszFormat, args);3539 rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, args); 3011 3540 3012 3541 /* 3013 3542 * Release the semaphore. 3014 3543 */ 3015 rtlogUnlock(pLogger );3544 rtlogUnlock(pLoggerInt); 3016 3545 } 3017 3546 RT_EXPORT_SYMBOL(RTLogLoggerExV); … … 3211 3740 * Opens/creates the log file. 3212 3741 * 3213 * @param pLogger 3742 * @param pLoggerInt The logger instance to update. NULL is not allowed! 3214 3743 * @param pErrInfo Where to return extended error information. 3215 3744 * Optional. 3216 3745 */ 3217 static int rtlogFileOpen(PRTLOGGER pLogger, PRTERRINFO pErrInfo)3746 static int rtlogFileOpen(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo) 3218 3747 { 3219 3748 uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_NONE; 3220 if (pLogger ->fFlags & RTLOGFLAGS_APPEND)3749 if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND) 3221 3750 fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND; 3222 3751 else 3223 3752 { 3224 RTFileDelete(pLogger ->pInt->szFilename);3753 RTFileDelete(pLoggerInt->szFilename); 3225 3754 fOpen |= RTFILE_O_CREATE; 3226 3755 } 3227 if (pLogger ->fFlags & RTLOGFLAGS_WRITE_THROUGH)3756 if (pLoggerInt->fFlags & RTLOGFLAGS_WRITE_THROUGH) 3228 3757 fOpen |= RTFILE_O_WRITE_THROUGH; 3229 if (pLogger ->fDestFlags & RTLOGDEST_F_NO_DENY)3758 if (pLoggerInt->fDestFlags & RTLOGDEST_F_NO_DENY) 3230 3759 fOpen = (fOpen & ~RTFILE_O_DENY_NONE) | RTFILE_O_DENY_NOT_DELETE; 3231 3760 3232 3761 unsigned cBackoff = 0; 3233 int rc = RTFileOpen(&pLogger ->pInt->hFile, pLogger->pInt->szFilename, fOpen);3762 int rc = RTFileOpen(&pLoggerInt->hFile, pLoggerInt->szFilename, fOpen); 3234 3763 while ( ( rc == VERR_SHARING_VIOLATION 3235 || (rc == VERR_ALREADY_EXISTS && !(pLogger ->fFlags & RTLOGFLAGS_APPEND)))3764 || (rc == VERR_ALREADY_EXISTS && !(pLoggerInt->fFlags & RTLOGFLAGS_APPEND))) 3236 3765 && cBackoff < RT_ELEMENTS(g_acMsLogBackoff)) 3237 3766 { 3238 3767 RTThreadSleep(g_acMsLogBackoff[cBackoff++]); 3239 if (!(pLogger ->fFlags & RTLOGFLAGS_APPEND))3240 RTFileDelete(pLogger ->pInt->szFilename);3241 rc = RTFileOpen(&pLogger ->pInt->hFile, pLogger->pInt->szFilename, fOpen);3768 if (!(pLoggerInt->fFlags & RTLOGFLAGS_APPEND)) 3769 RTFileDelete(pLoggerInt->szFilename); 3770 rc = RTFileOpen(&pLoggerInt->hFile, pLoggerInt->szFilename, fOpen); 3242 3771 } 3243 3772 if (RT_SUCCESS(rc)) 3244 3773 { 3245 rc = RTFileQuerySize(pLogger ->pInt->hFile, &pLogger->pInt->cbHistoryFileWritten);3774 rc = RTFileQuerySize(pLoggerInt->hFile, &pLoggerInt->cbHistoryFileWritten); 3246 3775 if (RT_FAILURE(rc)) 3247 3776 { 3248 3777 /* Don't complain if this fails, assume the file is empty. */ 3249 pLogger ->pInt->cbHistoryFileWritten = 0;3778 pLoggerInt->cbHistoryFileWritten = 0; 3250 3779 rc = VINF_SUCCESS; 3251 3780 } … … 3253 3782 else 3254 3783 { 3255 pLogger ->pInt->hFile = NIL_RTFILE;3256 RTErrInfoSetF(pErrInfo, rc, N_("could not open file '%s' (fOpen=%#x)"), pLogger ->pInt->szFilename, fOpen);3784 pLoggerInt->hFile = NIL_RTFILE; 3785 RTErrInfoSetF(pErrInfo, rc, N_("could not open file '%s' (fOpen=%#x)"), pLoggerInt->szFilename, fOpen); 3257 3786 } 3258 3787 return rc; … … 3265 3794 * Used by the rtlogFlush() function as well as RTLogCreateExV. 3266 3795 * 3267 * @param pLogger 3796 * @param pLoggerInt The logger instance to update. NULL is not allowed! 3268 3797 * @param uTimeSlot Current time slot (for tikme based rotation). 3269 3798 * @param fFirst Flag whether this is the beginning of logging, i.e. … … 3272 3801 * @param pErrInfo Where to return extended error information. Optional. 3273 3802 */ 3274 static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst, PRTERRINFO pErrInfo)3803 static void rtlogRotate(PRTLOGGERINTERNAL pLoggerInt, uint32_t uTimeSlot, bool fFirst, PRTERRINFO pErrInfo) 3275 3804 { 3276 3805 /* Suppress rotating empty log files simply because the time elapsed. */ 3277 if (RT_UNLIKELY(!pLogger ->pInt->cbHistoryFileWritten))3278 pLogger ->pInt->uHistoryTimeSlotStart = uTimeSlot;3806 if (RT_UNLIKELY(!pLoggerInt->cbHistoryFileWritten)) 3807 pLoggerInt->uHistoryTimeSlotStart = uTimeSlot; 3279 3808 3280 3809 /* Check rotation condition: file still small enough and not too old? */ 3281 if (RT_LIKELY( pLogger ->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax3282 && uTimeSlot == pLogger ->pInt->uHistoryTimeSlotStart))3810 if (RT_LIKELY( pLoggerInt->cbHistoryFileWritten < pLoggerInt->cbHistoryFileMax 3811 && uTimeSlot == pLoggerInt->uHistoryTimeSlotStart)) 3283 3812 return; 3284 3813 … … 3288 3817 * rotation would cause severe trouble otherwise. 3289 3818 */ 3290 uint32_t const fSavedFlags = pLogger ->fFlags;3291 pLogger ->fFlags |= RTLOGFLAGS_DISABLED;3819 uint32_t const fSavedFlags = pLoggerInt->fFlags; 3820 pLoggerInt->fFlags |= RTLOGFLAGS_DISABLED; 3292 3821 3293 3822 /* … … 3295 3824 * chatty phase logging we could run into endless rotation. 3296 3825 */ 3297 uint32_t const cSavedHistory = pLogger ->pInt->cHistory;3298 pLogger ->pInt->cHistory = 0;3826 uint32_t const cSavedHistory = pLoggerInt->cHistory; 3827 pLoggerInt->cHistory = 0; 3299 3828 3300 3829 /* 3301 3830 * Close the old log file. 3302 3831 */ 3303 if (pLogger ->pInt->hFile != NIL_RTFILE)3832 if (pLoggerInt->hFile != NIL_RTFILE) 3304 3833 { 3305 3834 /* Use the callback to generate some final log contents, but only if 3306 3835 * this is a rotation with a fully set up logger. Leave the other case 3307 3836 * to the RTLogCreateExV function. */ 3308 if (pLogger ->pInt->pfnPhase && !fFirst)3309 { 3310 uint32_t fODestFlags = pLogger ->fDestFlags;3311 pLogger ->fDestFlags &= RTLOGDEST_FILE;3312 pLogger ->pInt->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);3313 pLogger ->fDestFlags = fODestFlags;3314 } 3315 RTFileClose(pLogger ->pInt->hFile);3316 pLogger ->pInt->hFile = NIL_RTFILE;3837 if (pLoggerInt->pfnPhase && !fFirst) 3838 { 3839 uint32_t fODestFlags = pLoggerInt->fDestFlags; 3840 pLoggerInt->fDestFlags &= RTLOGDEST_FILE; 3841 pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked); 3842 pLoggerInt->fDestFlags = fODestFlags; 3843 } 3844 RTFileClose(pLoggerInt->hFile); 3845 pLoggerInt->hFile = NIL_RTFILE; 3317 3846 } 3318 3847 … … 3324 3853 for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--) 3325 3854 { 3326 char szOldName[sizeof(pLogger ->pInt->szFilename) + 32];3855 char szOldName[sizeof(pLoggerInt->szFilename) + 32]; 3327 3856 if (i > 0) 3328 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger ->pInt->szFilename, i);3857 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLoggerInt->szFilename, i); 3329 3858 else 3330 RTStrCopy(szOldName, sizeof(szOldName), pLogger ->pInt->szFilename);3331 3332 char szNewName[sizeof(pLogger ->pInt->szFilename) + 32];3333 RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger ->pInt->szFilename, i + 1);3859 RTStrCopy(szOldName, sizeof(szOldName), pLoggerInt->szFilename); 3860 3861 char szNewName[sizeof(pLoggerInt->szFilename) + 32]; 3862 RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLoggerInt->szFilename, i + 1); 3334 3863 3335 3864 unsigned cBackoff = 0; … … 3351 3880 for (uint32_t i = cSavedHistory + 1; ; i++) 3352 3881 { 3353 char szExcessName[sizeof(pLogger ->pInt->szFilename) + 32];3354 RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger ->pInt->szFilename, i);3882 char szExcessName[sizeof(pLoggerInt->szFilename) + 32]; 3883 RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLoggerInt->szFilename, i); 3355 3884 int rc = RTFileDelete(szExcessName); 3356 3885 if (RT_FAILURE(rc)) … … 3362 3891 * Update logger state and create new log file. 3363 3892 */ 3364 pLogger ->pInt->cbHistoryFileWritten = 0;3365 pLogger ->pInt->uHistoryTimeSlotStart = uTimeSlot;3366 rtlogFileOpen(pLogger , pErrInfo);3893 pLoggerInt->cbHistoryFileWritten = 0; 3894 pLoggerInt->uHistoryTimeSlotStart = uTimeSlot; 3895 rtlogFileOpen(pLoggerInt, pErrInfo); 3367 3896 3368 3897 /* … … 3371 3900 * RTLogCreateExV function. 3372 3901 */ 3373 if (pLogger ->pInt->pfnPhase && !fFirst)3374 { 3375 uint32_t const fSavedDestFlags = pLogger ->fDestFlags;3376 pLogger ->fDestFlags &= RTLOGDEST_FILE;3377 pLogger ->pInt->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);3378 pLogger ->fDestFlags = fSavedDestFlags;3902 if (pLoggerInt->pfnPhase && !fFirst) 3903 { 3904 uint32_t const fSavedDestFlags = pLoggerInt->fDestFlags; 3905 pLoggerInt->fDestFlags &= RTLOGDEST_FILE; 3906 pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked); 3907 pLoggerInt->fDestFlags = fSavedDestFlags; 3379 3908 } 3380 3909 3381 3910 /* Restore saved values. */ 3382 pLogger ->pInt->cHistory = cSavedHistory;3383 pLogger ->fFlags= fSavedFlags;3911 pLoggerInt->cHistory = cSavedHistory; 3912 pLoggerInt->fFlags = fSavedFlags; 3384 3913 } 3385 3914 … … 3391 3920 * 3392 3921 * @returns IPRT status code. 3393 * @param pLogger 3922 * @param pLoggerInt The logger. 3394 3923 * @param pErrInfo Where to return extended error information. 3395 3924 * Optional. 3396 3925 */ 3397 static int rtR3LogOpenFileDestination(PRTLOGGER pLogger, PRTERRINFO pErrInfo)3926 static int rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo) 3398 3927 { 3399 3928 int rc; 3400 if (pLogger ->fFlags & RTLOGFLAGS_APPEND)3401 { 3402 rc = rtlogFileOpen(pLogger , pErrInfo);3929 if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND) 3930 { 3931 rc = rtlogFileOpen(pLoggerInt, pErrInfo); 3403 3932 3404 3933 /* Rotate in case of appending to a too big log file, 3405 3934 otherwise this simply doesn't do anything. */ 3406 rtlogRotate(pLogger , 0, true /* fFirst */, pErrInfo);3935 rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo); 3407 3936 } 3408 3937 else 3409 3938 { 3410 3939 /* Force rotation if it is configured. */ 3411 pLogger ->pInt->cbHistoryFileWritten = UINT64_MAX;3412 rtlogRotate(pLogger , 0, true /* fFirst */, pErrInfo);3940 pLoggerInt->cbHistoryFileWritten = UINT64_MAX; 3941 rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo); 3413 3942 3414 3943 /* If the file is not open then rotation is not set up. */ 3415 if (pLogger ->pInt->hFile == NIL_RTFILE)3416 { 3417 pLogger ->pInt->cbHistoryFileWritten = 0;3418 rc = rtlogFileOpen(pLogger , pErrInfo);3944 if (pLoggerInt->hFile == NIL_RTFILE) 3945 { 3946 pLoggerInt->cbHistoryFileWritten = 0; 3947 rc = rtlogFileOpen(pLoggerInt, pErrInfo); 3419 3948 } 3420 3949 else … … 3433 3962 * Used by the RTLogFlush() function. 3434 3963 * 3435 * @param pLogger 3964 * @param pLoggerInt The logger instance to write to. NULL is not allowed! 3436 3965 * @param fNeedSpace Set if the caller assumes space will be made available. 3437 3966 */ 3438 static void rtlogFlush(PRTLOGGER pLogger, bool fNeedSpace) 3439 { 3440 uint32_t const cchScratch = pLogger->offScratch; 3441 if (cchScratch == 0) 3967 static void rtlogFlush(PRTLOGGERINTERNAL pLoggerInt, bool fNeedSpace) 3968 { 3969 PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc; 3970 uint32_t cchToFlush = pBufDesc->offBuf; 3971 char * const pchToFlush = pBufDesc->pchBuf; 3972 uint32_t const cbBuf = pBufDesc->cbBuf; 3973 Assert(pBufDesc->u32Magic == RTLOGBUFFERDESC_MAGIC); 3974 3975 NOREF(fNeedSpace); 3976 if (cchToFlush == 0) 3442 3977 return; /* nothing to flush. */ 3443 NOREF(fNeedSpace); 3444 3445 #ifndef IN_RC 3978 3979 AssertPtrReturnVoid(pchToFlush); 3980 AssertReturnVoid(cbBuf > 0); 3981 AssertMsgStmt(cchToFlush < cbBuf, ("%#x vs %#x\n", cchToFlush, cbBuf), cchToFlush = cbBuf - 1); 3982 3446 3983 /* 3447 3984 * If the ring buffer is active, the other destinations are only written 3448 3985 * to when the ring buffer is flushed by RTLogFlush(). 3449 3986 */ 3450 if ( (pLogger->fDestFlags & RTLOGDEST_RINGBUF) 3451 && pLogger->pInt 3452 && pLogger->pInt->pszRingBuf /* paraoia */) 3453 { 3454 rtLogRingBufWrite(pLogger->pInt, pLogger->achScratch, pLogger->offScratch); 3455 pLogger->offScratch = 0; /* empty the buffer. */ 3987 if ( (pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF) 3988 && pLoggerInt->pszRingBuf /* paranoia */) 3989 { 3990 rtLogRingBufWrite(pLoggerInt, pchToFlush, cchToFlush); 3991 3992 /* empty the buffer. */ 3993 pBufDesc->offBuf = 0; 3994 *pchToFlush = '\0'; 3456 3995 } 3457 3996 /* … … 3460 3999 */ 3461 4000 else 3462 # ifdef IN_RING3 3463 if (!(pLogger->fDestFlags & RTLOGDEST_F_DELAY_FILE)) 3464 # endif 4001 #ifdef IN_RING3 4002 if (!(pLoggerInt->fDestFlags & RTLOGDEST_F_DELAY_FILE)) 3465 4003 #endif 3466 4004 { 3467 4005 /* Make sure the string is terminated. On Windows, RTLogWriteDebugger 3468 4006 will get upset if it isn't. */ 3469 if (RT_LIKELY(cchScratch < sizeof(pLogger->achScratch))) 3470 pLogger->achScratch[cchScratch] = '\0'; 3471 else 3472 AssertFailed(); 3473 3474 #ifndef IN_RC 3475 if (pLogger->fDestFlags & RTLOGDEST_USER) 3476 RTLogWriteUser(pLogger->achScratch, cchScratch); 3477 3478 if (pLogger->fDestFlags & RTLOGDEST_DEBUGGER) 3479 RTLogWriteDebugger(pLogger->achScratch, cchScratch); 3480 3481 # ifdef IN_RING3 3482 if ((pLogger->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_RINGBUF)) == RTLOGDEST_FILE) 3483 { 3484 if (pLogger->pInt->hFile != NIL_RTFILE) 4007 pchToFlush[cchToFlush] = '\0'; 4008 4009 if (pLoggerInt->fDestFlags & RTLOGDEST_USER) 4010 RTLogWriteUser(pchToFlush, cchToFlush); 4011 4012 if (pLoggerInt->fDestFlags & RTLOGDEST_DEBUGGER) 4013 RTLogWriteDebugger(pchToFlush, cchToFlush); 4014 4015 #ifdef IN_RING3 4016 if ((pLoggerInt->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_RINGBUF)) == RTLOGDEST_FILE) 4017 { 4018 if (pLoggerInt->hFile != NIL_RTFILE) 3485 4019 { 3486 RTFileWrite(pLogger ->pInt->hFile, pLogger->achScratch, cchScratch, NULL);3487 if (pLogger ->fFlags & RTLOGFLAGS_FLUSH)3488 RTFileFlush(pLogger ->pInt->hFile);4020 RTFileWrite(pLoggerInt->hFile, pchToFlush, cchToFlush, NULL); 4021 if (pLoggerInt->fFlags & RTLOGFLAGS_FLUSH) 4022 RTFileFlush(pLoggerInt->hFile); 3489 4023 } 3490 if (pLogger->pInt->cHistory) 3491 pLogger->pInt->cbHistoryFileWritten += cchScratch; 3492 } 3493 # endif 3494 3495 if (pLogger->fDestFlags & RTLOGDEST_STDOUT) 3496 RTLogWriteStdOut(pLogger->achScratch, cchScratch); 3497 3498 if (pLogger->fDestFlags & RTLOGDEST_STDERR) 3499 RTLogWriteStdErr(pLogger->achScratch, cchScratch); 3500 3501 # if (defined(IN_RING0) || defined(IN_RC)) && !defined(LOG_NO_COM) 3502 if (pLogger->fDestFlags & RTLOGDEST_COM) 3503 RTLogWriteCom(pLogger->achScratch, cchScratch); 3504 # endif 3505 #endif /* !IN_RC */ 3506 3507 #ifdef IN_RC 3508 if (pLogger->pfnFlush) 3509 pLogger->pfnFlush(pLogger); 3510 #else 3511 if (pLogger->pInt->pfnFlush) 3512 pLogger->pInt->pfnFlush(pLogger); 4024 if (pLoggerInt->cHistory) 4025 pLoggerInt->cbHistoryFileWritten += cchToFlush; 4026 } 3513 4027 #endif 3514 4028 4029 if (pLoggerInt->fDestFlags & RTLOGDEST_STDOUT) 4030 RTLogWriteStdOut(pchToFlush, cchToFlush); 4031 4032 if (pLoggerInt->fDestFlags & RTLOGDEST_STDERR) 4033 RTLogWriteStdErr(pchToFlush, cchToFlush); 4034 4035 #if (defined(IN_RING0) || defined(IN_RC)) && !defined(LOG_NO_COM) 4036 if (pLoggerInt->fDestFlags & RTLOGDEST_COM) 4037 RTLogWriteCom(pchToFlush, cchToFlush); 4038 #endif 4039 4040 if (pLoggerInt->pfnFlush) 4041 { 4042 /** @todo implement asynchronous buffer switching protocol. */ 4043 bool fDone; 4044 if (pBufDesc->pAux) 4045 pBufDesc->pAux->offBuf = cchToFlush; 4046 fDone = pLoggerInt->pfnFlush(&pLoggerInt->Core, pBufDesc); 4047 Assert(fDone == true); RT_NOREF(fDone); 4048 } 4049 3515 4050 /* empty the buffer. */ 3516 pLogger->offScratch = 0; 4051 pBufDesc->offBuf = 0; 4052 if (pBufDesc->pAux) 4053 pBufDesc->pAux->offBuf = 0; 4054 *pchToFlush = '\0'; 3517 4055 3518 4056 #ifdef IN_RING3 … … 3522 4060 * and footer messages. 3523 4061 */ 3524 if ( (pLogger->fDestFlags & RTLOGDEST_FILE)3525 && pLogger->pInt->cHistory)3526 rtlogRotate(pLogger , RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /*fFirst*/, NULL /*pErrInfo*/);4062 if ( pLoggerInt->cHistory > 0 4063 && (pLoggerInt->fDestFlags & RTLOGDEST_FILE)) 4064 rtlogRotate(pLoggerInt, RTTimeProgramSecTS() / pLoggerInt->cSecsHistoryTimeSlot, false /*fFirst*/, NULL /*pErrInfo*/); 3527 4065 #endif 3528 4066 } … … 3534 4072 * buffer and insert a message indicating that we've dropped output. 3535 4073 */ 3536 uint32_t offHalf = sizeof(pLogger->achScratch) / 2; 3537 if (cchScratch > offHalf) 3538 { 3539 if (pLogger->fFlags & RTLOGFLAGS_USECRLF) 3540 pLogger->achScratch[offHalf++] = '\r'; 3541 static const char s_szDropMsg[] = "\n[DROP DROP DROP]"; 3542 memcpy(&pLogger->achScratch[offHalf], RT_STR_TUPLE(s_szDropMsg)); 3543 offHalf += sizeof(s_szDropMsg) - 1; 3544 if (pLogger->fFlags & RTLOGFLAGS_USECRLF) 3545 pLogger->achScratch[offHalf++] = '\r'; 3546 pLogger->achScratch[offHalf++] = '\n'; 3547 3548 pLogger->offScratch = offHalf; 4074 uint32_t offHalf = cbBuf / 2; 4075 if (cchToFlush > offHalf) 4076 { 4077 static const char s_szDropMsgLf[] = "\n[DROP DROP DROP]\n"; 4078 static const char s_szDropMsgCrLf[] = "\r\n[DROP DROP DROP]\r\n"; 4079 if (!(pLoggerInt->fFlags & RTLOGFLAGS_USECRLF)) 4080 { 4081 memcpy(&pchToFlush[offHalf], RT_STR_TUPLE(s_szDropMsgLf)); 4082 offHalf += sizeof(s_szDropMsgLf) - 1; 4083 } 4084 else 4085 { 4086 memcpy(&pchToFlush[offHalf], RT_STR_TUPLE(s_szDropMsgCrLf)); 4087 offHalf += sizeof(s_szDropMsgCrLf) - 1; 4088 } 4089 pBufDesc->offBuf = offHalf; 3549 4090 } 3550 4091 } … … 3559 4100 static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars) 3560 4101 { 3561 PRTLOGGER pLogger = (PRTLOGGER)pv;4102 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pv; 3562 4103 if (cbChars) 3563 4104 { … … 3565 4106 for (;;) 3566 4107 { 3567 #if defined(DEBUG) && defined(IN_RING3) 3568 /* sanity */ 3569 if (pLogger->offScratch >= sizeof(pLogger->achScratch)) 4108 PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc; 4109 if (pBufDesc->offBuf < pBufDesc->cbBuf) 3570 4110 { 3571 fprintf(stderr, "pLogger->offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n", 3572 pLogger->offScratch, (unsigned)sizeof(pLogger->achScratch)); 4111 /* how much */ 4112 char *pchBuf = pBufDesc->pchBuf; 4113 uint32_t offBuf = pBufDesc->offBuf; 4114 size_t cb = pBufDesc->cbBuf - offBuf - 1; 4115 if (cb > cbChars) 4116 cb = cbChars; 4117 4118 switch (cb) 4119 { 4120 default: 4121 memcpy(&pchBuf[offBuf], pachChars, cb); 4122 pBufDesc->offBuf = offBuf + (uint32_t)cb; 4123 cbRet += cb; 4124 cbChars -= cb; 4125 if (cbChars <= 0) 4126 return cbRet; 4127 pachChars += cb; 4128 break; 4129 4130 case 1: 4131 pchBuf[offBuf] = pachChars[0]; 4132 pBufDesc->offBuf = offBuf + 1; 4133 if (cbChars == 1) 4134 return cbRet + 1; 4135 cbChars -= 1; 4136 pachChars += 1; 4137 break; 4138 4139 case 2: 4140 pchBuf[offBuf] = pachChars[0]; 4141 pchBuf[offBuf + 1] = pachChars[1]; 4142 pBufDesc->offBuf = offBuf + 2; 4143 if (cbChars == 2) 4144 return cbRet + 2; 4145 cbChars -= 2; 4146 pachChars += 2; 4147 break; 4148 4149 case 3: 4150 pchBuf[offBuf] = pachChars[0]; 4151 pchBuf[offBuf + 1] = pachChars[1]; 4152 pchBuf[offBuf + 2] = pachChars[2]; 4153 pBufDesc->offBuf = offBuf + 3; 4154 if (cbChars == 3) 4155 return cbRet + 3; 4156 cbChars -= 3; 4157 pachChars += 3; 4158 break; 4159 } 4160 4161 } 4162 #if defined(RT_STRICT) && defined(IN_RING3) 4163 else 4164 { 4165 fprintf(stderr, "pBufDesc->offBuf >= pBufDesc->cbBuf (%#x >= %#x)\n", pBufDesc->offBuf, pBufDesc->cbBuf); 3573 4166 AssertBreakpoint(); AssertBreakpoint(); 3574 4167 } 3575 4168 #endif 3576 4169 3577 /* how much */3578 size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;3579 if (cb > cbChars)3580 cb = cbChars;3581 3582 /* copy */3583 memcpy(&pLogger->achScratch[pLogger->offScratch], pachChars, cb);3584 3585 /* advance */3586 pLogger->offScratch += (uint32_t)cb;3587 cbRet += cb;3588 cbChars -= cb;3589 3590 /* done? */3591 if (cbChars <= 0)3592 return cbRet;3593 3594 pachChars += cb;3595 3596 4170 /* flush */ 3597 rtlogFlush(pLogger , true /*fNeedSpace*/);4171 rtlogFlush(pLoggerInt, true /*fNeedSpace*/); 3598 4172 } 3599 4173 … … 3606 4180 * There's always space for a terminator, and it's not counted. 3607 4181 */ 3608 pLogger->achScratch[pLogger->offScratch] = '\0'; 4182 PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc; 4183 pBufDesc->pchBuf[RT_MIN(pBufDesc->offBuf, pBufDesc->cbBuf - 1)] = '\0'; 3609 4184 return 0; 3610 4185 } … … 3678 4253 static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars) 3679 4254 { 3680 PRTLOGOUTPUTPREFIXEDARGS pArgs = (PRTLOGOUTPUTPREFIXEDARGS)pv;3681 PRTLOGGER pLogger = pArgs->pLogger;4255 PRTLOGOUTPUTPREFIXEDARGS pArgs = (PRTLOGOUTPUTPREFIXEDARGS)pv; 4256 PRTLOGGERINTERNAL pLoggerInt = pArgs->pLoggerInt; 3682 4257 if (cbChars) 3683 4258 { … … 3685 4260 for (;;) 3686 4261 { 3687 uint32_t offScratch = pLogger->offScratch; 3688 size_t cb = sizeof(pLogger->achScratch) - offScratch - 1; 3689 const char *pszNewLine; 3690 char *psz; 3691 #ifdef IN_RC 3692 bool *pfPendingPrefix = &pLogger->fPendingPrefix; 3693 #else 3694 bool *pfPendingPrefix = &pLogger->pInt->fPendingPrefix; 4262 PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc; 4263 char * const pchBuf = pBufDesc->pchBuf; 4264 uint32_t const cbBuf = pBufDesc->cbBuf; 4265 uint32_t offBuf = pBufDesc->offBuf; 4266 size_t cb = cbBuf - offBuf - 1; 4267 const char *pszNewLine; 4268 char *psz; 4269 4270 #if defined(RT_STRICT) && defined(IN_RING3) 4271 /* sanity */ 4272 if (offBuf < cbBuf) 4273 { /* likely */ } 4274 else 4275 { 4276 fprintf(stderr, "offBuf >= cbBuf (%#x >= %#x)\n", offBuf, cbBuf); 4277 AssertBreakpoint(); AssertBreakpoint(); 4278 } 3695 4279 #endif 3696 4280 … … 3698 4282 * Pending prefix? 3699 4283 */ 3700 if ( *pfPendingPrefix)4284 if (pLoggerInt->fPendingPrefix) 3701 4285 { 3702 *pfPendingPrefix = false;3703 3704 #if defined(DEBUG) && defined(IN_RING3)3705 /* sanity */3706 if (offScratch >= sizeof(pLogger->achScratch))3707 {3708 fprintf(stderr, "offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",3709 offScratch, (unsigned)sizeof(pLogger->achScratch));3710 AssertBreakpoint(); AssertBreakpoint();3711 }3712 #endif3713 3714 4286 /* 3715 4287 * Flush the buffer if there isn't enough room for the maximum prefix config. 3716 4288 * Max is 256, add a couple of extra bytes. See CCH_PREFIX check way below. 3717 4289 */ 3718 if (cb < 256 + 16) 4290 if (cb >= 256 + 16) 4291 pLoggerInt->fPendingPrefix = false; 4292 else 3719 4293 { 3720 rtlogFlush(pLogger, true /*fNeedSpace*/); 3721 offScratch = pLogger->offScratch; 3722 cb = sizeof(pLogger->achScratch) - offScratch - 1; 4294 rtlogFlush(pLoggerInt, true /*fNeedSpace*/); 4295 continue; 3723 4296 } 3724 4297 … … 3727 4300 * psz is pointing to the current position. 3728 4301 */ 3729 psz = &p Logger->achScratch[offScratch];3730 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_TS)4302 psz = &pchBuf[offBuf]; 4303 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TS) 3731 4304 { 3732 4305 uint64_t u64 = RTTimeNanoTS(); 3733 4306 int iBase = 16; 3734 4307 unsigned int fFlags = RTSTR_F_ZEROPAD; 3735 if (pLogger ->fFlags & RTLOGFLAGS_DECIMAL_TS)4308 if (pLoggerInt->fFlags & RTLOGFLAGS_DECIMAL_TS) 3736 4309 { 3737 4310 iBase = 10; 3738 4311 fFlags = 0; 3739 4312 } 3740 if (pLogger ->fFlags & RTLOGFLAGS_REL_TS)4313 if (pLoggerInt->fFlags & RTLOGFLAGS_REL_TS) 3741 4314 { 3742 4315 static volatile uint64_t s_u64LastTs; … … 3754 4327 #define CCH_PREFIX_01 0 + 17 3755 4328 3756 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_TSC)4329 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TSC) 3757 4330 { 3758 4331 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) … … 3763 4336 int iBase = 16; 3764 4337 unsigned int fFlags = RTSTR_F_ZEROPAD; 3765 if (pLogger ->fFlags & RTLOGFLAGS_DECIMAL_TS)4338 if (pLoggerInt->fFlags & RTLOGFLAGS_DECIMAL_TS) 3766 4339 { 3767 4340 iBase = 10; 3768 4341 fFlags = 0; 3769 4342 } 3770 if (pLogger ->fFlags & RTLOGFLAGS_REL_TS)4343 if (pLoggerInt->fFlags & RTLOGFLAGS_REL_TS) 3771 4344 { 3772 4345 static volatile uint64_t s_u64LastTsc; … … 3784 4357 #define CCH_PREFIX_02 CCH_PREFIX_01 + 17 3785 4358 3786 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_MS_PROG)4359 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_MS_PROG) 3787 4360 { 3788 4361 #if defined(IN_RING3) || defined(IN_RC) 3789 4362 uint64_t u64 = RTTimeProgramMilliTS(); 3790 4363 #else 3791 uint64_t u64 = (RTTimeNanoTS() - pLogger ->pInt->nsR0ProgramStart) / RT_NS_1MS;4364 uint64_t u64 = (RTTimeNanoTS() - pLoggerInt->nsR0ProgramStart) / RT_NS_1MS; 3792 4365 #endif 3793 4366 /* 1E8 milliseconds = 27 hours */ … … 3797 4370 #define CCH_PREFIX_03 CCH_PREFIX_02 + 21 3798 4371 3799 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_TIME)4372 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TIME) 3800 4373 { 3801 4374 #if defined(IN_RING3) || defined(IN_RING0) … … 3818 4391 #define CCH_PREFIX_04 CCH_PREFIX_03 + (3+1+3+1+3+1+7+1) 3819 4392 3820 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG)4393 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG) 3821 4394 { 3822 4395 … … 3824 4397 uint64_t u64 = RTTimeProgramMicroTS(); 3825 4398 #else 3826 uint64_t u64 = (RTTimeNanoTS() - pLogger ->pInt->nsR0ProgramStart) / RT_NS_1US;4399 uint64_t u64 = (RTTimeNanoTS() - pLoggerInt->nsR0ProgramStart) / RT_NS_1US; 3827 4400 3828 4401 #endif … … 3842 4415 3843 4416 # if 0 3844 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_DATETIME)4417 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_DATETIME) 3845 4418 { 3846 4419 char szDate[32]; … … 3857 4430 # endif 3858 4431 3859 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_PID)4432 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_PID) 3860 4433 { 3861 4434 #ifndef IN_RC … … 3869 4442 #define CCH_PREFIX_07 CCH_PREFIX_06 + 9 3870 4443 3871 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_TID)4444 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TID) 3872 4445 { 3873 4446 #ifndef IN_RC … … 3881 4454 #define CCH_PREFIX_08 CCH_PREFIX_07 + 17 3882 4455 3883 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_THREAD)4456 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_THREAD) 3884 4457 { 3885 4458 #ifdef IN_RING3 … … 3888 4461 const char *pszName = "EMT-RC"; 3889 4462 #else 3890 const char *pszName = pLogger ->pInt->szR0ThreadName[0] ? pLogger->pInt->szR0ThreadName : "R0";4463 const char *pszName = pLoggerInt->szR0ThreadName[0] ? pLoggerInt->szR0ThreadName : "R0"; 3891 4464 #endif 3892 4465 psz = rtLogStPNCpyPad(psz, pszName, 16, 8); … … 3894 4467 #define CCH_PREFIX_09 CCH_PREFIX_08 + 17 3895 4468 3896 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_CPUID)4469 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_CPUID) 3897 4470 { 3898 4471 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) … … 3907 4480 3908 4481 #ifndef IN_RC 3909 if ( (pLogger ->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)3910 && pLogger ->pInt->pfnPrefix)4482 if ( (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_CUSTOM) 4483 && pLoggerInt->pfnPrefix) 3911 4484 { 3912 psz += pLogger ->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg);4485 psz += pLoggerInt->pfnPrefix(&pLoggerInt->Core, psz, 31, pLoggerInt->pvPrefixUserArg); 3913 4486 *psz++ = ' '; /* +32 */ 3914 4487 } … … 3916 4489 #define CCH_PREFIX_11 CCH_PREFIX_10 + 32 3917 4490 3918 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS)4491 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS) 3919 4492 { 3920 4493 #ifdef IN_RING3 /** @todo implement these counters in ring-0 too? */ … … 3941 4514 #define CCH_PREFIX_12 CCH_PREFIX_11 + 8 3942 4515 3943 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO)4516 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO) 3944 4517 { 3945 4518 psz += RTStrFormatNumber(psz, pArgs->fFlags, 16, 8, 0, RTSTR_F_ZEROPAD); … … 3948 4521 #define CCH_PREFIX_13 CCH_PREFIX_12 + 9 3949 4522 3950 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_FLAG)4523 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_FLAG) 3951 4524 { 3952 4525 #ifdef IN_RING3 3953 const char *pszGroup = pArgs->iGroup != ~0U ? pLogger ->pInt->papszGroups[pArgs->iGroup] : NULL;4526 const char *pszGroup = pArgs->iGroup != ~0U ? pLoggerInt->papszGroups[pArgs->iGroup] : NULL; 3954 4527 #else 3955 4528 const char *pszGroup = NULL; … … 3959 4532 #define CCH_PREFIX_14 CCH_PREFIX_13 + 17 3960 4533 3961 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO)4534 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO) 3962 4535 { 3963 4536 if (pArgs->iGroup != ~0U) … … 3974 4547 #define CCH_PREFIX_15 CCH_PREFIX_14 + 9 3975 4548 3976 if (pLogger ->fFlags & RTLOGFLAGS_PREFIX_GROUP)4549 if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_GROUP) 3977 4550 { 3978 const unsigned fGrp = pLogger ->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0];4551 const unsigned fGrp = pLoggerInt->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0]; 3979 4552 const char *pszGroup; 3980 4553 size_t cchGroup; … … 4009 4582 * Done, figure what we've used and advance the buffer and free size. 4010 4583 */ 4011 cb = psz - &pLogger->achScratch[offScratch];4012 AssertMsg(cb <= 223, ("%#zx (%zd) - fFlags=%#x\n", cb, cb, pLogger->fFlags));4013 p Logger->offScratch = offScratch += (uint32_t)cb;4014 cb = sizeof(pLogger->achScratch) - offScratch- 1;4584 AssertMsg(psz - &pchBuf[offBuf] <= 223, 4585 ("%#zx (%zd) - fFlags=%#x\n", psz - &pchBuf[offBuf], psz - &pchBuf[offBuf], pLoggerInt->fFlags)); 4586 pBufDesc->offBuf = offBuf = (uint32_t)(psz - pchBuf); 4587 cb = cbBuf - offBuf - 1; 4015 4588 } 4016 4589 else if (cb <= 0) 4017 4590 { 4018 rtlogFlush(pLogger, true /*fNeedSpace*/); 4019 offScratch = pLogger->offScratch; 4020 cb = sizeof(pLogger->achScratch) - offScratch - 1; 4591 rtlogFlush(pLoggerInt, true /*fNeedSpace*/); 4592 continue; 4021 4593 } 4022 4023 #if defined(DEBUG) && defined(IN_RING3)4024 /* sanity */4025 if (offScratch >= sizeof(pLogger->achScratch))4026 {4027 fprintf(stderr, "offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",4028 offScratch, (unsigned)sizeof(pLogger->achScratch));4029 AssertBreakpoint(); AssertBreakpoint();4030 }4031 #endif4032 4594 4033 4595 /* how much */ … … 4039 4601 if (pszNewLine) 4040 4602 { 4041 if (pLogger->fFlags & RTLOGFLAGS_USECRLF) 4603 if (!(pLoggerInt->fFlags & RTLOGFLAGS_USECRLF)) 4604 { 4605 cb = pszNewLine - pachChars + 1; 4606 memcpy(&pchBuf[offBuf], pachChars, cb); 4607 pLoggerInt->fPendingPrefix = true; 4608 } 4609 else if (cbBuf - offBuf < (uintptr_t)(pszNewLine - pachChars + 2)) 4610 { 4042 4611 cb = pszNewLine - pachChars; 4612 memcpy(&pchBuf[offBuf], pachChars, cb); 4613 pchBuf[offBuf + cb++] = '\r'; 4614 pchBuf[offBuf + cb++] = '\n'; 4615 pachChars--; /* Discount the extra '\r'. */ 4616 cbChars++; /* Discount the extra '\r'. */ 4617 cbRet--; /* Ditto. */ 4618 pLoggerInt->fPendingPrefix = true; 4619 } 4043 4620 else 4044 4621 { 4045 cb = pszNewLine - pachChars + 1; 4046 *pfPendingPrefix = true; 4622 /* Insufficient buffer space, leave the '\n' for the next iteration. */ 4623 cb = pszNewLine - pachChars; 4624 memcpy(&pchBuf[offBuf], pachChars, cb); 4047 4625 } 4048 4626 } 4049 4050 /* copy */ 4051 memcpy(&pLogger->achScratch[offScratch], pachChars, cb); 4627 else 4628 memcpy(&pchBuf[offBuf], pachChars, cb); 4052 4629 4053 4630 /* advance */ 4054 p Logger->offScratch = offScratch+= (uint32_t)cb;4055 cbRet += cb;4631 pBufDesc->offBuf = offBuf += (uint32_t)cb; 4632 cbRet += cb; 4056 4633 cbChars -= cb; 4057 4058 if ( pszNewLine4059 && (pLogger->fFlags & RTLOGFLAGS_USECRLF)4060 && offScratch + 2 < sizeof(pLogger->achScratch))4061 {4062 memcpy(&pLogger->achScratch[offScratch], "\r\n", 2);4063 pLogger->offScratch = offScratch += 2;4064 cbRet++;4065 cbChars--;4066 cb++;4067 *pfPendingPrefix = true;4068 }4069 4634 4070 4635 /* done? */ … … 4082 4647 * There's always space for a terminator, and it's not counted. 4083 4648 */ 4084 pLogger->achScratch[pLogger->offScratch] = '\0'; 4649 PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc; 4650 pBufDesc->pchBuf[RT_MIN(pBufDesc->offBuf, pBufDesc->cbBuf - 1)] = '\0'; 4085 4651 return 0; 4086 4652 } … … 4094 4660 * logging kind which is currently enabled before writing anything to the log. 4095 4661 * 4096 * @param pLogger 4662 * @param pLoggerInt Pointer to logger instance. Must be non-NULL. 4097 4663 * @param fFlags The logging flags. 4098 4664 * @param iGroup The group. … … 4102 4668 * @param args Format arguments. 4103 4669 */ 4104 static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args) 4105 { 4106 /* 4107 * Format the message and perhaps flush it. 4108 */ 4109 if (pLogger->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF)) 4670 static void rtlogLoggerExVLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, 4671 const char *pszFormat, va_list args) 4672 { 4673 /* 4674 * If we've got an auxilary descriptor, check if the buffer was flushed. 4675 */ 4676 PRTLOGBUFFERDESC pBufDesc = pLoggerInt->pBufDesc; 4677 PRTLOGBUFFERAUXDESC pAuxDesc = pBufDesc->pAux; 4678 if (!pAuxDesc || !pAuxDesc->fFlushedIndicator) 4679 { /* likely, except maybe for ring-0 */ } 4680 else 4681 { 4682 pAuxDesc->fFlushedIndicator = false; 4683 pBufDesc->offBuf = 0; 4684 } 4685 4686 /* 4687 * Format the message. 4688 */ 4689 if (pLoggerInt->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF)) 4110 4690 { 4111 4691 RTLOGOUTPUTPREFIXEDARGS OutputArgs; 4112 OutputArgs.pLogger = pLogger;4113 OutputArgs.iGroup = iGroup;4114 OutputArgs.fFlags = fFlags;4692 OutputArgs.pLoggerInt = pLoggerInt; 4693 OutputArgs.iGroup = iGroup; 4694 OutputArgs.fFlags = fFlags; 4115 4695 RTLogFormatV(rtLogOutputPrefixed, &OutputArgs, pszFormat, args); 4116 4696 } 4117 4697 else 4118 RTLogFormatV(rtLogOutput, pLogger, pszFormat, args); 4119 if ( !(pLogger->fFlags & RTLOGFLAGS_BUFFERED) 4120 && pLogger->offScratch) 4121 rtlogFlush(pLogger, false /*fNeedSpace*/); 4698 RTLogFormatV(rtLogOutput, pLoggerInt, pszFormat, args); 4699 4700 /* 4701 * Maybe flush the buffer and update the auxiliary descriptor if there is one. 4702 */ 4703 pBufDesc = pLoggerInt->pBufDesc; /* (the descriptor may have changed) */ 4704 if ( !(pLoggerInt->fFlags & RTLOGFLAGS_BUFFERED) 4705 && pBufDesc->offBuf) 4706 rtlogFlush(pLoggerInt, false /*fNeedSpace*/); 4707 else 4708 { 4709 pAuxDesc = pBufDesc->pAux; 4710 if (pAuxDesc) 4711 pAuxDesc->offBuf = pBufDesc->offBuf; 4712 } 4122 4713 } 4123 4714 … … 4127 4718 * For calling rtlogLoggerExVLocked. 4128 4719 * 4129 * @param pLogger 4720 * @param pLoggerInt The logger. 4130 4721 * @param fFlags The logging flags. 4131 4722 * @param iGroup The group. … … 4135 4726 * @param ... Format arguments. 4136 4727 */ 4137 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)4728 static void rtlogLoggerExFLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...) 4138 4729 { 4139 4730 va_list va; 4140 4731 va_start(va, pszFormat); 4141 rtlogLoggerExVLocked(pLogger , fFlags, iGroup, pszFormat, va);4732 rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, va); 4142 4733 va_end(va); 4143 4734 } -
trunk/src/VBox/Runtime/common/log/logrel.cpp
r82968 r90829 56 56 # include <stdio.h> 57 57 #endif 58 59 60 /*********************************************************************************************************************************61 * Global Variables *62 *********************************************************************************************************************************/63 #ifdef IN_RC64 /** Default release logger instance. */65 extern "C" DECLIMPORT(RTLOGGERRC) g_RelLogger;66 #else /* !IN_RC */67 /** Default release logger instance. */68 static PRTLOGGER g_pRelLogger;69 #endif /* !IN_RC */70 71 72 RTDECL(PRTLOGGER) RTLogRelGetDefaultInstance(void)73 {74 #ifdef IN_RC75 return &g_RelLogger;76 #else /* !IN_RC */77 return g_pRelLogger;78 #endif /* !IN_RC */79 }80 RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstance);81 82 83 RTDECL(PRTLOGGER) RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup)84 {85 #ifdef IN_RC86 PRTLOGGER pLogger = &g_RelLogger;87 #else /* !IN_RC */88 PRTLOGGER pLogger = g_pRelLogger;89 #endif /* !IN_RC */90 if (pLogger)91 {92 if (pLogger->fFlags & RTLOGFLAGS_DISABLED)93 pLogger = NULL;94 else95 {96 uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);97 uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);98 if ( iGroup != UINT16_MAX99 && ( (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED))100 != (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED)))101 pLogger = NULL;102 }103 }104 return pLogger;105 }106 RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstanceEx);107 108 109 #ifndef IN_RC110 /**111 * Sets the default logger instance.112 *113 * @returns iprt status code.114 * @param pLogger The new default release logger instance.115 */116 RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger)117 {118 return ASMAtomicXchgPtrT(&g_pRelLogger, pLogger, PRTLOGGER);119 }120 RT_EXPORT_SYMBOL(RTLogRelSetDefaultInstance);121 #endif /* !IN_RC */122 58 123 59
Note:
See TracChangeset
for help on using the changeset viewer.