Changeset 37591 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jun 22, 2011 3:58:22 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 72437
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/log/log.cpp
r36679 r37591 72 72 { 73 73 /** The logger instance. */ 74 PRTLOGGER pLogger;74 PRTLOGGER pLogger; 75 75 /** The flags. (used for prefixing.) */ 76 unsigned fFlags;76 unsigned fFlags; 77 77 /** The group. (used for prefixing.) */ 78 unsigned iGroup;78 unsigned iGroup; 79 79 } RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS; 80 80 81 #ifdef IN_RING3 82 /** 83 * File logging bits for the logger. 84 */ 85 typedef struct RTLOGGERFILE 86 { 81 /** 82 * Internal logger data. 83 * 84 * @remarks Don't make casual changes to this structure. 85 */ 86 typedef struct RTLOGGERINTERNAL 87 { 88 /** The structure revision (RTLOGGERINTERNAL_REV). */ 89 uint32_t uRevision; 90 /** The size of the internal logger structure. */ 91 uint32_t cbSelf; 92 93 /** Spinning mutex semaphore. Can be NIL. */ 94 RTSEMSPINMUTEX hSpinMtx; 95 /** Pointer to the flush function. */ 96 PFNRTLOGFLUSH pfnFlush; 97 98 /** Custom prefix callback. */ 99 PFNRTLOGPREFIX pfnPrefix; 100 /** Prefix callback argument. */ 101 void *pvPrefixUserArg; 102 /** This is set if a prefix is pending. */ 103 bool fPendingPrefix; 104 /** Alignment padding. */ 105 bool afPadding1[3]; 106 107 /** The max number of groups that there is room for in afGroups and papszGroups. 108 * Used by RTLogCopyGroupAndFlags(). */ 109 uint32_t cMaxGroups; 110 /** Pointer to the group name array. 111 * (The data is readonly and provided by the user.) */ 112 const char * const *papszGroups; 113 114 /** The number of log entries per group. NULL if 115 * RTLOGFLAGS_RESTRICT_GROUPS is not specified. */ 116 uint32_t *pacEntriesPerGroup; 117 /** The max number of entries per group. */ 118 uint32_t cMaxEntriesPerGroup; 119 /** Padding. */ 120 uint32_t u32Padding2; 121 122 #ifdef IN_RING3 /* Note! Must be at the end! */ 123 /** @name File logging bits for the logger. 124 * @{ */ 87 125 /** Pointer to the function called when starting logging, and when 88 126 * ending or starting a new log file as part of history rotation. 89 127 * This can be NULL. */ 90 128 PFNRTLOGPHASE pfnPhase; 129 91 130 /** Handle to log file (if open). */ 92 RTFILE File; 93 /** Pointer to filename. 94 * (The memory is allocated in the same block as RTLOGGER.) */ 95 char *pszFilename; 96 /** Log file history settings: number of older files to keep. 97 * 0 means no history. */ 98 uint32_t cHistory; 131 union 132 { 133 RTFILE hFile; 134 RTHCUINTPTR uPaddingForNewRTFILE; 135 } u; 136 # if ARCH_BITS == 32 137 /** Alignment padding. */ 138 uint32_t u32Padding; 139 # endif 99 140 /** Log file history settings: maximum amount of data to put in a file. */ 100 141 uint64_t cbHistoryFileMax; … … 105 146 /** Log file history settings: in what time slot was the file created. */ 106 147 uint32_t uHistoryTimeSlotStart; 107 } RTLOGGERFILE; 148 /** Log file history settings: number of older files to keep. 149 * 0 means no history. */ 150 uint32_t cHistory; 151 /** Pointer to filename. */ 152 char szFilename[RTPATH_MAX]; 153 /** @} */ 108 154 #endif /* IN_RING3 */ 109 155 } RTLOGGERINTERNAL; 156 157 /** The revision of the internal logger structure. */ 158 #define RTLOGGERINTERNAL_REV UINT32_C(9) 159 160 #ifdef IN_RING3 161 /** The size of the RTLOGGERINTERNAL structure in ring-0. */ 162 # define RTLOGGERINTERNAL_R0_SIZE RT_OFFSETOF(RTLOGGERINTERNAL, pfnPhase) 163 AssertCompileMemberAlignment(RTLOGGERINTERNAL, u.hFile, sizeof(void *)); 164 AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbHistoryFileMax, sizeof(uint64_t)); 165 #endif 110 166 111 167 /******************************************************************************* … … 126 182 static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars); 127 183 static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args); 184 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...); 128 185 129 186 … … 142 199 static uint32_t volatile g_cLoggerLockCount; 143 200 #endif 201 144 202 #ifdef IN_RING0 145 203 /** Number of per-thread loggers. */ … … 210 268 { "tsc", sizeof("tsc" ) - 1, RTLOGFLAGS_PREFIX_TSC, false }, /* before ts! */ 211 269 { "ts", sizeof("ts" ) - 1, RTLOGFLAGS_PREFIX_TS, false }, 270 /* We intentionally omit RTLOGFLAGS_RESTRICT_GROUPS. */ 212 271 }; 213 272 … … 244 303 { 245 304 #ifndef IN_RC 246 if (pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX) 247 { 248 int rc = RTSemSpinMutexRequest(pLogger->hSpinMtx); 305 PRTLOGGERINTERNAL pInt = pLogger->pInt; 306 AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV), 307 VERR_LOG_REVISION_MISMATCH); 308 AssertMsgReturn(pInt->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)), 309 VERR_LOG_REVISION_MISMATCH); 310 if (pInt->hSpinMtx != NIL_RTSEMSPINMUTEX) 311 { 312 int rc = RTSemSpinMutexRequest(pInt->hSpinMtx); 249 313 if (RT_FAILURE(rc)) 250 314 return rc; … … 262 326 { 263 327 #ifndef IN_RC 264 if (pLogger-> hSpinMtx != NIL_RTSEMSPINMUTEX)265 RTSemSpinMutexRelease(pLogger-> hSpinMtx);328 if (pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX) 329 RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx); 266 330 #endif 267 331 return; … … 281 345 { 282 346 PRTLOGGER pLogger = (PRTLOGGER)pvArg; 283 RTFileWrite(pLogger->p File->File, pachChars, cbChars, NULL);347 RTFileWrite(pLogger->pInt->u.hFile, pachChars, cbChars, NULL); 284 348 return cbChars; 285 349 } … … 325 389 va_list args; 326 390 AssertPtrReturnVoid(pLogger); 327 AssertPtrReturnVoid(pLogger->p File);328 Assert(pLogger-> hSpinMtx != NIL_RTSEMSPINMUTEX);391 AssertPtrReturnVoid(pLogger->pInt); 392 Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX); 329 393 330 394 va_start(args, pszFormat); … … 345 409 va_list args; 346 410 AssertPtrReturnVoid(pLogger); 347 AssertPtrReturnVoid(pLogger->p File);348 Assert(pLogger-> hSpinMtx != NIL_RTSEMSPINMUTEX);411 AssertPtrReturnVoid(pLogger->pInt); 412 Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX); 349 413 350 414 va_start(args, pszFormat); … … 356 420 357 421 RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, 358 const char *pszEnvVarBase, unsigned cGroups, const char * const * 422 const char *pszEnvVarBase, unsigned cGroups, const char * const *papszGroups, 359 423 uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory, 360 424 uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot, 361 425 char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args) 362 426 { 363 int rc; 364 size_t cb; 365 PRTLOGGER pLogger; 427 int rc; 428 size_t offInternal; 429 size_t cbLogger; 430 PRTLOGGER pLogger; 366 431 367 432 /* … … 384 449 * Allocate a logger instance. 385 450 */ 386 cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups + 1]) + RTPATH_MAX; 387 #ifdef IN_RING3 388 cb += sizeof(RTLOGGERFILE); 389 #endif 390 pLogger = (PRTLOGGER)RTMemAllocZVar(cb); 451 offInternal = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]); 452 offInternal = RT_ALIGN_Z(offInternal, sizeof(uint64_t)); 453 cbLogger = offInternal; 454 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 455 cbLogger += cGroups * sizeof(uint32_t); 456 pLogger = (PRTLOGGER)RTMemAllocZVar(offInternal + sizeof(RTLOGGERINTERNAL)); 391 457 if (pLogger) 392 458 { 393 # if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))459 # if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC)) 394 460 uint8_t *pu8Code; 395 #endif 396 397 pLogger->u32Magic = RTLOGGER_MAGIC; 398 pLogger->papszGroups = papszGroups; 399 pLogger->cMaxGroups = cGroups; 400 pLogger->cGroups = cGroups; 401 #ifdef IN_RING3 402 pLogger->pFile = (PRTLOGGERFILE)((char *)&pLogger->afGroups[cGroups + 1] + RTPATH_MAX); 403 pLogger->pFile->File = NIL_RTFILE; 404 pLogger->pFile->pszFilename = (char *)&pLogger->afGroups[cGroups + 1]; 405 pLogger->pFile->pfnPhase = pfnPhase; 406 pLogger->pFile->cHistory = cHistory; 461 # endif 462 pLogger->u32Magic = RTLOGGER_MAGIC; 463 pLogger->cGroups = cGroups; 464 pLogger->fFlags = fFlags; 465 pLogger->fDestFlags = fDestFlags; 466 pLogger->pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger + offInternal); 467 pLogger->pInt->uRevision = RTLOGGERINTERNAL_REV; 468 pLogger->pInt->cbSelf = sizeof(RTLOGGERINTERNAL); 469 pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX; 470 pLogger->pInt->pfnFlush = NULL; 471 pLogger->pInt->pfnPrefix = NULL; 472 pLogger->pInt->pvPrefixUserArg = NULL; 473 pLogger->pInt->afPadding1[0] = false; 474 pLogger->pInt->afPadding1[1] = false; 475 pLogger->pInt->afPadding1[2] = false; 476 pLogger->pInt->cMaxGroups = cGroups; 477 pLogger->pInt->papszGroups = papszGroups; 478 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 479 pLogger->pInt->pacEntriesPerGroup = (uint32_t *)(pLogger->pInt + 1); 480 else 481 pLogger->pInt->pacEntriesPerGroup = NULL; 482 pLogger->pInt->cMaxEntriesPerGroup = UINT32_MAX; 483 # ifdef IN_RING3 484 pLogger->pInt->pfnPhase = pfnPhase; 485 pLogger->pInt->u.hFile = NIL_RTFILE; 486 pLogger->pInt->cHistory = cHistory; 407 487 if (cbHistoryFileMax == 0) 408 pLogger->p File->cbHistoryFileMax= UINT64_MAX;488 pLogger->pInt->cbHistoryFileMax = UINT64_MAX; 409 489 else 410 pLogger->p File->cbHistoryFileMax= cbHistoryFileMax;490 pLogger->pInt->cbHistoryFileMax = cbHistoryFileMax; 411 491 if (cSecsHistoryTimeSlot == 0) 412 pLogger->p File->cSecsHistoryTimeSlot = UINT32_MAX;492 pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX; 413 493 else 414 pLogger->pFile->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot; 415 #else /* !IN_RING3 */ 416 pLogger->pFile = NULL; 417 #endif /* !IN_RING3 */ 418 pLogger->fFlags = fFlags; 419 pLogger->fDestFlags = fDestFlags; 420 pLogger->fPendingPrefix = true; 494 pLogger->pInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot; 495 # endif /* IN_RING3 */ 421 496 if (pszGroupSettings) 422 497 RTLogGroupSettings(pLogger, pszGroupSettings); 423 498 424 # if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))499 # if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC)) 425 500 /* 426 501 * Emit wrapper code. … … 447 522 else 448 523 { 449 # ifdef RT_OS_LINUX524 # ifdef RT_OS_LINUX 450 525 if (pszErrorMsg) /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */ 451 526 RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?")); 452 # endif527 # endif 453 528 rc = VERR_NO_MEMORY; 454 529 } 455 530 if (RT_SUCCESS(rc)) 456 # endif /* X86 wrapper code*/457 { 458 # ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */531 # endif /* X86 wrapper code*/ 532 { 533 # ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */ 459 534 /* 460 535 * Format the filename. … … 463 538 { 464 539 /** @todo validate the length, fail on overflow. */ 465 RTStrPrintfV(pLogger->p File->pszFilename, RTPATH_MAX, pszFilenameFmt, args);540 RTStrPrintfV(pLogger->pInt->szFilename, sizeof(pLogger->pInt->szFilename), pszFilenameFmt, args); 466 541 pLogger->fDestFlags |= RTLOGDEST_FILE; 467 542 } … … 501 576 RTLogGroupSettings(pLogger, pszVar); 502 577 } 503 # endif /* IN_RING3 */578 # endif /* IN_RING3 */ 504 579 505 580 /* … … 507 582 */ 508 583 rc = VINF_SUCCESS; 509 # ifdef IN_RING3584 # ifdef IN_RING3 510 585 if (pLogger->fDestFlags & RTLOGDEST_FILE) 511 586 { … … 521 596 { 522 597 /* Force rotation if it is configured. */ 523 pLogger->p File->cbHistoryFileWritten = UINT64_MAX;598 pLogger->pInt->cbHistoryFileWritten = UINT64_MAX; 524 599 rtlogRotate(pLogger, 0, true /* fFirst */); 525 600 526 601 /* If the file is not open then rotation is not set up. */ 527 if (pLogger->p File->File == NIL_RTFILE)602 if (pLogger->pInt->u.hFile == NIL_RTFILE) 528 603 { 529 pLogger->p File->cbHistoryFileWritten = 0;604 pLogger->pInt->cbHistoryFileWritten = 0; 530 605 rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg); 531 606 } 532 607 } 533 608 } 534 # endif /* IN_RING3 */609 # endif /* IN_RING3 */ 535 610 536 611 /* … … 540 615 if (RT_SUCCESS(rc)) 541 616 { 542 rc = RTSemSpinMutexCreate(&pLogger-> hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);617 rc = RTSemSpinMutexCreate(&pLogger->pInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE); 543 618 if (RT_SUCCESS(rc)) 544 619 { 545 # ifdef IN_RING3 /** @todo do counters in ring-0 too? */620 # ifdef IN_RING3 /** @todo do counters in ring-0 too? */ 546 621 RTTHREAD Thread = RTThreadSelf(); 547 622 if (Thread != NIL_RTTHREAD) 548 623 { 549 624 int32_t c = RTLockValidatorWriteLockGetCount(Thread); 550 RTSemSpinMutexRequest(pLogger-> hSpinMtx);625 RTSemSpinMutexRequest(pLogger->pInt->hSpinMtx); 551 626 c = RTLockValidatorWriteLockGetCount(Thread) - c; 552 RTSemSpinMutexRelease(pLogger-> hSpinMtx);627 RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx); 553 628 ASMAtomicWriteU32(&g_cLoggerLockCount, c); 554 629 } 555 630 556 631 /* Use the callback to generate some initial log contents. */ 557 Assert(VALID_PTR(pLogger->p File->pfnPhase) || pLogger->pFile->pfnPhase == NULL);558 if (pLogger->p File->pfnPhase)559 pLogger->p File->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);560 # endif632 Assert(VALID_PTR(pLogger->pInt->pfnPhase) || pLogger->pInt->pfnPhase == NULL); 633 if (pLogger->pInt->pfnPhase) 634 pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal); 635 # endif 561 636 *ppLogger = pLogger; 562 637 return VINF_SUCCESS; … … 566 641 RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("failed to create semaphore")); 567 642 } 568 # ifdef IN_RING3569 RTFileClose(pLogger->p File->File);570 # endif571 # if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)643 # ifdef IN_RING3 644 RTFileClose(pLogger->pInt->u.hFile); 645 # endif 646 # if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC) 572 647 RTMemFree(*(void **)&pLogger->pfnLogger); 573 # else648 # else 574 649 RTMemExecFree(*(void **)&pLogger->pfnLogger, 64); 575 # endif650 # endif 576 651 } 577 652 RTMemFree(pLogger); … … 640 715 if (!pLogger) 641 716 return VINF_SUCCESS; 642 Assert Return(VALID_PTR(pLogger), VERR_INVALID_POINTER);717 AssertPtrReturn(pLogger, VERR_INVALID_POINTER); 643 718 AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 719 AssertPtrReturn(pLogger->pInt, VERR_INVALID_POINTER); 644 720 645 721 /* … … 659 735 rtlogFlush(pLogger); 660 736 661 # ifdef IN_RING3737 # ifdef IN_RING3 662 738 /* 663 739 * Add end of logging message. 664 740 */ 665 741 if ( (pLogger->fDestFlags & RTLOGDEST_FILE) 666 && pLogger->p File->File != NIL_RTFILE)667 pLogger->p File->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);742 && pLogger->pInt->u.hFile != NIL_RTFILE) 743 pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked); 668 744 669 745 /* 670 746 * Close output stuffs. 671 747 */ 672 if (pLogger->p File->File != NIL_RTFILE)673 { 674 int rc2 = RTFileClose(pLogger->p File->File);748 if (pLogger->pInt->u.hFile != NIL_RTFILE) 749 { 750 int rc2 = RTFileClose(pLogger->pInt->u.hFile); 675 751 AssertRC(rc2); 676 752 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 677 753 rc = rc2; 678 pLogger->p File->File = NIL_RTFILE;679 } 680 # endif754 pLogger->pInt->u.hFile = NIL_RTFILE; 755 } 756 # endif 681 757 682 758 /* 683 759 * Free the mutex, the wrapper and the instance memory. 684 760 */ 685 hSpinMtx = pLogger-> hSpinMtx;686 pLogger-> hSpinMtx = NIL_RTSEMSPINMUTEX;761 hSpinMtx = pLogger->pInt->hSpinMtx; 762 pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX; 687 763 if (hSpinMtx != NIL_RTSEMSPINMUTEX) 688 764 { … … 697 773 if (pLogger->pfnLogger) 698 774 { 699 # if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)775 # if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC) 700 776 RTMemFree(*(void **)&pLogger->pfnLogger); 701 # else777 # else 702 778 RTMemExecFree(*(void **)&pLogger->pfnLogger, 64); 703 # endif779 # endif 704 780 pLogger->pfnLogger = NULL; 705 781 } … … 772 848 { 773 849 AssertMsgFailed(("%d req=%d cGroups=%d\n", cbLoggerRC, RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]), pLogger->cGroups)); 774 return VERR_ INVALID_PARAMETER;850 return VERR_BUFFER_OVERFLOW; 775 851 } 776 852 memcpy(&pLoggerRC->afGroups[0], &pLogger->afGroups[0], pLogger->cGroups * sizeof(pLoggerRC->afGroups[0])); … … 780 856 * Copy bits from the HC instance. 781 857 */ 782 pLoggerRC->fPendingPrefix = pLogger-> fPendingPrefix;858 pLoggerRC->fPendingPrefix = pLogger->pInt->fPendingPrefix; 783 859 pLoggerRC->fFlags |= pLogger->fFlags; 784 860 … … 851 927 RT_EXPORT_SYMBOL(RTLogFlushRC); 852 928 853 854 #ifdef IN_RING3 855 /** 856 * Create a logger instance for singled threaded ring-0 usage. 857 * 858 * @returns iprt status code. 859 * 860 * @param pLogger Where to create the logger instance. 861 * @param cbLogger The amount of memory available for the logger instance. 862 * @param pfnLogger Pointer to logger wrapper function for the clone. 863 * @param pfnFlush Pointer to flush function for the clone. 864 * @param fFlags Logger instance flags for the clone, a combination of the RTLOGFLAGS_* values. 865 * @param fDestFlags The destination flags. 866 */ 867 RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, PFNRTLOGGER pfnLogger, PFNRTLOGFLUSH pfnFlush, 929 # ifdef IN_RING3 930 931 RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, 932 RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr, 868 933 uint32_t fFlags, uint32_t fDestFlags) 869 934 { … … 872 937 */ 873 938 AssertPtrReturn(pLogger, VERR_INVALID_PARAMETER); 874 AssertReturn(cbLogger >= sizeof(*pLogger), VERR_INVALID_PARAMETER); 875 AssertReturn(pfnLogger, VERR_INVALID_PARAMETER); 876 AssertReturn(pfnFlush, VERR_INVALID_PARAMETER); 939 size_t const cbRequired = sizeof(*pLogger) + RTLOGGERINTERNAL_R0_SIZE; 940 AssertReturn(cbLogger >= cbRequired, VERR_BUFFER_OVERFLOW); 941 AssertReturn(pLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER); 942 AssertReturn(pfnLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER); 877 943 878 944 /* 879 945 * Initialize the ring-0 instance. 880 946 */ 881 pLogger->offScratch = 0; 882 pLogger->fPendingPrefix = false; 883 pLogger->pfnLogger = pfnLogger; 884 pLogger->pfnFlush = pfnFlush; 885 pLogger->hSpinMtx = NIL_RTSEMSPINMUTEX; /* Not serialized. */ 886 pLogger->u32Magic = RTLOGGER_MAGIC; 887 pLogger->fFlags = fFlags; 888 pLogger->fDestFlags = fDestFlags & ~RTLOGDEST_FILE; 889 pLogger->pFile = NULL; 890 pLogger->papszGroups = NULL; 891 pLogger->cMaxGroups = (uint32_t)((cbLogger - RT_OFFSETOF(RTLOGGER, afGroups[0])) / sizeof(pLogger->afGroups[0])); 892 pLogger->cGroups = 1; 893 pLogger->afGroups[0] = 0; 947 pLogger->achScratch[0] = 0; 948 pLogger->offScratch = 0; 949 pLogger->pfnLogger = (PFNRTLOGGER)pfnLoggerR0Ptr; 950 pLogger->fFlags = fFlags; 951 pLogger->fDestFlags = fDestFlags & ~RTLOGDEST_FILE; 952 pLogger->pInt = NULL; 953 pLogger->cGroups = 1; 954 pLogger->afGroups[0] = 0; 955 956 uint32_t cMaxGroups = (uint32_t)((cbLogger - cbRequired) / sizeof(pLogger->afGroups[0])); 957 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 958 cMaxGroups /= 2; 959 PRTLOGGERINTERNAL pInt; 960 for (;;) 961 { 962 AssertReturn(cMaxGroups > 0, VERR_BUFFER_OVERFLOW); 963 pInt = (PRTLOGGERINTERNAL)&pLogger->afGroups[cMaxGroups]; 964 if (!((uintptr_t)pInt & (sizeof(uint64_t) - 1))) 965 break; 966 cMaxGroups--; 967 } 968 pLogger->pInt = (PRTLOGGERINTERNAL)(pLoggerR0Ptr + (uintptr_t)pInt - (uintptr_t)pLogger); 969 pInt->uRevision = RTLOGGERINTERNAL_REV; 970 pInt->cbSelf = RTLOGGERINTERNAL_R0_SIZE; 971 pInt->hSpinMtx = NIL_RTSEMSPINMUTEX; /* Not serialized. */ 972 pInt->pfnFlush = (PFNRTLOGFLUSH)pfnFlushR0Ptr; 973 pInt->pfnPrefix = NULL; 974 pInt->pvPrefixUserArg = NULL; 975 pInt->fPendingPrefix = false; 976 pInt->cMaxGroups = cMaxGroups; 977 pInt->papszGroups = NULL; 978 pInt->cMaxEntriesPerGroup = UINT32_MAX; 979 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 980 { 981 memset(pInt + 1, 0, sizeof(uint32_t) * cMaxGroups); 982 pInt->pacEntriesPerGroup= (uint32_t *)(pLogger->pInt + 1); 983 } 984 else 985 pInt->pacEntriesPerGroup= NULL; 986 987 pLogger->u32Magic = RTLOGGER_MAGIC; 894 988 return VINF_SUCCESS; 895 989 } 896 990 RT_EXPORT_SYMBOL(RTLogCreateForR0); 897 #endif /* IN_RING3 */ 898 899 900 /** 901 * Copies the group settings and flags from logger instance to another.902 *903 * @returns IPRT status code.904 * @param pDstLogger The destination logger instance.905 * @param pSrcLogger The source logger instance. If NULL the default one is used.906 * @param fFlagsOr OR mask for the flags.907 * @param fFlagsAnd AND mask for the flags. 908 */ 909 RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger, unsigned fFlagsOr, unsigned fFlagsAnd) 910 { 911 int rc; 912 unsigned cGroups;913 991 992 993 RTDECL(size_t) RTLogCalcSizeForR0(uint32_t cGroups, uint32_t fFlags) 994 { 995 size_t cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]); 996 cb = RT_ALIGN_Z(cb, sizeof(uint64_t)); 997 cb += sizeof(RTLOGGERINTERNAL); 998 if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 999 cb += sizeof(uint32_t) * cGroups; 1000 return cb; 1001 } 1002 RT_EXPORT_SYMBOL(RTLogCalcSizeForR0); 1003 1004 1005 RTDECL(int) RTLogCopyGroupsAndFlagsForR0(PRTLOGGER pDstLogger, RTR0PTR pDstLoggerR0Ptr, 1006 PCRTLOGGER pSrcLogger, uint32_t fFlagsOr, uint32_t fFlagsAnd) 1007 { 914 1008 /* 915 1009 * Validate input. … … 926 1020 if (!pSrcLogger) 927 1021 { 928 pDstLogger->fFlags |= RTLOGFLAGS_DISABLED ;1022 pDstLogger->fFlags |= RTLOGFLAGS_DISABLED | fFlagsOr; 929 1023 pDstLogger->cGroups = 1; 930 1024 pDstLogger->afGroups[0] = 0; … … 936 1030 * Copy flags and group settings. 937 1031 */ 938 pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd) | fFlagsOr; 939 940 rc = VINF_SUCCESS; 941 cGroups = pSrcLogger->cGroups; 942 if (cGroups < pDstLogger->cMaxGroups) 943 { 944 AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstLogger->cMaxGroups, 945 pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups]))); 1032 pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd & ~RTLOGFLAGS_RESTRICT_GROUPS) | fFlagsOr; 1033 1034 PRTLOGGERINTERNAL pDstInt = (PRTLOGGERINTERNAL)((uintptr_t)pDstLogger->pInt - pDstLoggerR0Ptr + (uintptr_t)pDstLogger); 1035 int rc = VINF_SUCCESS; 1036 uint32_t cGroups = pSrcLogger->cGroups; 1037 if (cGroups > pDstInt->cMaxGroups) 1038 { 1039 AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstInt->cMaxGroups, 1040 pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups]) + RTLOGGERINTERNAL_R0_SIZE)); 946 1041 rc = VERR_INVALID_PARAMETER; 947 cGroups = pDst Logger->cMaxGroups;1042 cGroups = pDstInt->cMaxGroups; 948 1043 } 949 1044 memcpy(&pDstLogger->afGroups[0], &pSrcLogger->afGroups[0], cGroups * sizeof(pDstLogger->afGroups[0])); … … 952 1047 return rc; 953 1048 } 954 RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlags); 1049 RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlagsForR0); 1050 1051 1052 RTDECL(int) RTLogSetCustomPrefixCallbackForR0(PRTLOGGER pLogger, RTR0PTR pLoggerR0Ptr, 1053 RTR0PTR pfnCallbackR0Ptr, RTR0PTR pvUserR0Ptr) 1054 { 1055 AssertPtrReturn(pLogger, VERR_INVALID_POINTER); 1056 AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC); 1057 1058 /* 1059 * Do the work. 1060 */ 1061 PRTLOGGERINTERNAL pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger->pInt - pLoggerR0Ptr + (uintptr_t)pLogger); 1062 AssertReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH); 1063 pInt->pvPrefixUserArg = (void *)pvUserR0Ptr; 1064 pInt->pfnPrefix = (PFNRTLOGPREFIX)pfnCallbackR0Ptr; 1065 1066 return VINF_SUCCESS; 1067 } 1068 RT_EXPORT_SYMBOL(RTLogSetCustomPrefixCallbackForR0); 1069 1070 # endif /* IN_RING3 */ 955 1071 956 1072 … … 1050 1166 */ 1051 1167 rtlogLock(pLogger); 1052 pLogger->p vPrefixUserArg = pvUser;1053 pLogger->p fnPrefix = pfnCallback;1168 pLogger->pInt->pvPrefixUserArg = pvUser; 1169 pLogger->pInt->pfnPrefix = pfnCallback; 1054 1170 rtlogUnlock(pLogger); 1055 1171 … … 1219 1335 { 1220 1336 const char *psz2 = (const char*)pszStart; 1221 if (rtlogIsGroupMatching(pLogger->p apszGroups[i], &psz2, cch))1337 if (rtlogIsGroupMatching(pLogger->pInt->papszGroups[i], &psz2, cch)) 1222 1338 { 1223 1339 unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1; … … 1279 1395 { "f", RTLOGGRPFLAGS_FLOW }, 1280 1396 { "flow", RTLOGGRPFLAGS_FLOW }, 1397 { "restrict", RTLOGGRPFLAGS_RESTRICT }, 1281 1398 1282 1399 { "lelik", RTLOGGRPFLAGS_LELIK }, 1283 1400 { "michael", RTLOGGRPFLAGS_MICHAEL }, 1284 { "dmik", RTLOGGRPFLAGS_DMIK },1285 1401 { "sunlover", RTLOGGRPFLAGS_SUNLOVER }, 1286 1402 { "achim", RTLOGGRPFLAGS_ACHIM }, … … 1344 1460 static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst) 1345 1461 { 1346 # define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)1347 # define APPEND_SZ(sz) APPEND_PSZ(sz, sizeof(sz) - 1)1348 # define APPEND_CH(ch) do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)1462 # define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0) 1463 # define APPEND_SZ(sz) APPEND_PSZ(sz, sizeof(sz) - 1) 1464 # define APPEND_CH(ch) do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0) 1349 1465 1350 1466 /* … … 1382 1498 return VERR_BUFFER_OVERFLOW; 1383 1499 1384 # undef APPEND_PSZ1385 # undef APPEND_SZ1386 # undef APPEND_CH1500 # undef APPEND_PSZ 1501 # undef APPEND_SZ 1502 # undef APPEND_CH 1387 1503 return VINF_SUCCESS; 1388 1504 } … … 1443 1559 if (fGroup) 1444 1560 { 1445 const char *pszName = pLogger->p apszGroups[i];1561 const char *pszName = pLogger->pInt->papszGroups[i]; 1446 1562 if (pszName) 1447 1563 { … … 1458 1574 } 1459 1575 RT_EXPORT_SYMBOL(RTLogGetGroupSettings); 1576 1460 1577 #endif /* !IN_RC */ 1461 1462 1578 1463 1579 /** … … 1588 1704 RT_EXPORT_SYMBOL(RTLogSetBuffering); 1589 1705 1706 1707 #ifdef IN_RING3 1708 RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup) 1709 { 1710 /* 1711 * Resolve the logger instance. 1712 */ 1713 if (!pLogger) 1714 { 1715 pLogger = RTLogDefaultInstance(); 1716 if (!pLogger) 1717 return UINT32_MAX; 1718 } 1719 1720 rtlogLock(pLogger); 1721 uint32_t cOld = pLogger->pInt->cMaxEntriesPerGroup; 1722 pLogger->pInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup; 1723 rtlogUnlock(pLogger); 1724 1725 return cOld; 1726 } 1727 #endif 1728 1590 1729 #ifndef IN_RC 1591 1730 … … 1722 1861 if (i == 0 /* file */ && !fNo) 1723 1862 { 1724 AssertReturn(cch < RTPATH_MAX, VERR_OUT_OF_RANGE);1725 memcpy(pLogger->p File->pszFilename, pszVar, cch);1726 pLogger->p File->pszFilename[cch] = '\0';1863 AssertReturn(cch < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE); 1864 memcpy(pLogger->pInt->szFilename, pszVar, cch); 1865 pLogger->pInt->szFilename[cch] = '\0'; 1727 1866 } 1728 1867 /* log directory */ 1729 1868 else if (i == 1 /* dir */ && !fNo) 1730 1869 { 1731 char szTmp[ RTPATH_MAX];1732 const char *pszFile = RTPathFilename(pLogger->p File->pszFilename);1870 char szTmp[sizeof(pLogger->pInt->szFilename)]; 1871 const char *pszFile = RTPathFilename(pLogger->pInt->szFilename); 1733 1872 size_t cchFile = pszFile ? strlen(pszFile) : 0; 1734 AssertReturn(cchFile + cch + 1 < RTPATH_MAX, VERR_OUT_OF_RANGE);1873 AssertReturn(cchFile + cch + 1 < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE); 1735 1874 memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1); 1736 1875 1737 memcpy(pLogger->p File->pszFilename, pszVar, cch);1738 pLogger->p File->pszFilename[cch] = '\0';1739 RTPathStripTrailingSlash(pLogger->p File->pszFilename);1740 1741 cch = strlen(pLogger->p File->pszFilename);1742 pLogger->p File->pszFilename[cch++] = '/';1743 memcpy(&pLogger->p File->pszFilename[cch], szTmp, cchFile);1744 pLogger->p File->pszFilename[cch+cchFile] = '\0';1876 memcpy(pLogger->pInt->szFilename, pszVar, cch); 1877 pLogger->pInt->szFilename[cch] = '\0'; 1878 RTPathStripTrailingSlash(pLogger->pInt->szFilename); 1879 1880 cch = strlen(pLogger->pInt->szFilename); 1881 pLogger->pInt->szFilename[cch++] = '/'; 1882 memcpy(&pLogger->pInt->szFilename[cch], szTmp, cchFile); 1883 pLogger->pInt->szFilename[cch + cchFile] = '\0'; 1745 1884 } 1746 1885 else if (i == 2 /* history */) … … 1754 1893 rc = RTStrToUInt32Full(szTmp, 0, &cHistory); 1755 1894 AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc); 1756 pLogger->p File->cHistory = cHistory;1895 pLogger->pInt->cHistory = cHistory; 1757 1896 } 1758 1897 else 1759 pLogger->p File->cHistory = 0;1898 pLogger->pInt->cHistory = 0; 1760 1899 } 1761 1900 else if (i == 3 /* histsize */) … … 1766 1905 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch); 1767 1906 if (RT_SUCCESS(rc)) 1768 rc = RTStrToUInt64Full(szTmp, 0, &pLogger->p File->cbHistoryFileMax);1907 rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pInt->cbHistoryFileMax); 1769 1908 AssertMsgRCReturn(rc, ("Invalid history file size value %s (%Rrc)!\n", szTmp, rc), rc); 1770 if (pLogger->p File->cbHistoryFileMax == 0)1771 pLogger->p File->cbHistoryFileMax = UINT64_MAX;1909 if (pLogger->pInt->cbHistoryFileMax == 0) 1910 pLogger->pInt->cbHistoryFileMax = UINT64_MAX; 1772 1911 } 1773 1912 else 1774 pLogger->p File->cbHistoryFileMax = UINT64_MAX;1913 pLogger->pInt->cbHistoryFileMax = UINT64_MAX; 1775 1914 } 1776 1915 else if (i == 4 /* histtime */) … … 1781 1920 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch); 1782 1921 if (RT_SUCCESS(rc)) 1783 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->p File->cSecsHistoryTimeSlot);1922 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pInt->cSecsHistoryTimeSlot); 1784 1923 AssertMsgRCReturn(rc, ("Invalid history time slot value %s (%Rrc)!\n", szTmp, rc), rc); 1785 if (pLogger->p File->cSecsHistoryTimeSlot == 0)1786 pLogger->p File->cSecsHistoryTimeSlot = UINT32_MAX;1924 if (pLogger->pInt->cSecsHistoryTimeSlot == 0) 1925 pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX; 1787 1926 } 1788 1927 else 1789 pLogger->p File->cSecsHistoryTimeSlot = UINT32_MAX;1928 pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX; 1790 1929 } 1791 1930 else … … 1863 2002 } 1864 2003 1865 # ifdef IN_RING32004 # ifdef IN_RING3 1866 2005 /* 1867 2006 * Add the filename. 1868 2007 */ 1869 if ( (fDestFlags & RTLOGDEST_FILE) 1870 && VALID_PTR(pLogger->pFile->pszFilename)) 2008 if (fDestFlags & RTLOGDEST_FILE) 1871 2009 { 1872 2010 rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " file=" : "file="); 1873 2011 if (RT_FAILURE(rc)) 1874 2012 return rc; 1875 rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->p File->pszFilename);2013 rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pInt->szFilename); 1876 2014 if (RT_FAILURE(rc)) 1877 2015 return rc; … … 1882 2020 { 1883 2021 char szNum[32]; 1884 if (pLogger->p File->cHistory)1885 { 1886 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "history=%u" : " history=%u", pLogger->p File->cHistory);2022 if (pLogger->pInt->cHistory) 2023 { 2024 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "history=%u" : " history=%u", pLogger->pInt->cHistory); 1887 2025 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 1888 2026 if (RT_FAILURE(rc)) 1889 2027 return rc; 1890 2028 } 1891 if (pLogger->p File->cbHistoryFileMax != UINT64_MAX)1892 { 1893 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histsize=%llu" : " histsize=%llu", pLogger->p File->cbHistoryFileMax);2029 if (pLogger->pInt->cbHistoryFileMax != UINT64_MAX) 2030 { 2031 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histsize=%llu" : " histsize=%llu", pLogger->pInt->cbHistoryFileMax); 1894 2032 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 1895 2033 if (RT_FAILURE(rc)) 1896 2034 return rc; 1897 2035 } 1898 if (pLogger->p File->cSecsHistoryTimeSlot != UINT32_MAX)1899 { 1900 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histtime=%llu" : " histtime=%llu", pLogger->p File->cSecsHistoryTimeSlot);2036 if (pLogger->pInt->cSecsHistoryTimeSlot != UINT32_MAX) 2037 { 2038 RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histtime=%llu" : " histtime=%llu", pLogger->pInt->cSecsHistoryTimeSlot); 1901 2039 rc = RTStrCopyP(&pszBuf, &cchBuf, szNum); 1902 2040 if (RT_FAILURE(rc)) … … 1904 2042 } 1905 2043 } 1906 # endif /* IN_RING3 */2044 # endif /* IN_RING3 */ 1907 2045 1908 2046 return VINF_SUCCESS; … … 2131 2269 } 2132 2270 RT_EXPORT_SYMBOL(RTLogSetDefaultInstanceThread); 2133 #endif 2271 #endif /* IN_RING0 */ 2134 2272 2135 2273 … … 2209 2347 2210 2348 /* 2211 * Call worker. 2212 */ 2213 rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args); 2349 * Check restrictions and call worker. 2350 */ 2351 #ifndef IN_RC 2352 if (RT_UNLIKELY( (pLogger->fFlags & RTLOGFLAGS_RESTRICT_GROUPS) 2353 && iGroup < pLogger->cGroups 2354 && (pLogger->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT) 2355 && ++pLogger->pInt->pacEntriesPerGroup[iGroup] >= pLogger->pInt->cMaxEntriesPerGroup )) 2356 { 2357 uint32_t cEntries = pLogger->pInt->pacEntriesPerGroup[iGroup]; 2358 if (cEntries > pLogger->pInt->cMaxEntriesPerGroup) 2359 pLogger->pInt->pacEntriesPerGroup[iGroup] = cEntries - 1; 2360 else 2361 { 2362 rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args); 2363 if ( pLogger->pInt->papszGroups 2364 && pLogger->pInt->papszGroups[iGroup]) 2365 rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n", 2366 cEntries, pLogger->pInt->papszGroups[iGroup], iGroup); 2367 else 2368 rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group #%u, muting it.\n", 2369 cEntries, iGroup); 2370 } 2371 } 2372 else 2373 #endif 2374 rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args); 2214 2375 2215 2376 /* … … 2261 2422 RTLogWriteStdErr(pThis->achScratch, pThis->offScratch); 2262 2423 2263 # ifndef LOG_NO_COM2424 # ifndef LOG_NO_COM 2264 2425 if (pThis->fDestFlags & RTLOGDEST_COM) 2265 2426 RTLogWriteCom(pThis->achScratch, pThis->offScratch); 2266 # endif2427 # endif 2267 2428 2268 2429 /* empty the buffer. */ … … 2401 2562 fOpen |= RTFILE_O_WRITE_THROUGH; 2402 2563 2403 int rc = RTFileOpen(&pLogger->p File->File, pLogger->pFile->pszFilename, fOpen);2564 int rc = RTFileOpen(&pLogger->pInt->u.hFile, pLogger->pInt->szFilename, fOpen); 2404 2565 if (RT_FAILURE(rc)) 2405 2566 { 2406 pLogger->p File->File = NIL_RTFILE;2567 pLogger->pInt->u.hFile = NIL_RTFILE; 2407 2568 if (pszErrorMsg) 2408 RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->p File->pszFilename, fOpen);2569 RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pInt->szFilename, fOpen); 2409 2570 } 2410 2571 else 2411 2572 { 2412 rc = RTFileGetSize(pLogger->p File->File, &pLogger->pFile->cbHistoryFileWritten);2573 rc = RTFileGetSize(pLogger->pInt->u.hFile, &pLogger->pInt->cbHistoryFileWritten); 2413 2574 if (RT_FAILURE(rc)) 2414 2575 { 2415 2576 /* Don't complain if this fails, assume the file is empty. */ 2416 pLogger->p File->cbHistoryFileWritten = 0;2577 pLogger->pInt->cbHistoryFileWritten = 0; 2417 2578 rc = VINF_SUCCESS; 2418 2579 } … … 2436 2597 { 2437 2598 /* Suppress rotating empty log files simply because the time elapsed. */ 2438 if (RT_UNLIKELY(!pLogger->p File->cbHistoryFileWritten))2439 pLogger->p File->uHistoryTimeSlotStart = uTimeSlot;2599 if (RT_UNLIKELY(!pLogger->pInt->cbHistoryFileWritten)) 2600 pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot; 2440 2601 2441 2602 /* Check rotation condition: file still small enough and not too old? */ 2442 if (RT_LIKELY( pLogger->p File->cbHistoryFileWritten < pLogger->pFile->cbHistoryFileMax2443 && uTimeSlot == pLogger->p File->uHistoryTimeSlotStart))2603 if (RT_LIKELY( pLogger->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax 2604 && uTimeSlot == pLogger->pInt->uHistoryTimeSlotStart)) 2444 2605 return; 2445 2606 … … 2456 2617 * chatty phase logging we could run into endless rotation. 2457 2618 */ 2458 uint32_t const cSavedHistory = pLogger->p File->cHistory;2459 pLogger->p File->cHistory = 0;2619 uint32_t const cSavedHistory = pLogger->pInt->cHistory; 2620 pLogger->pInt->cHistory = 0; 2460 2621 2461 2622 /* 2462 2623 * Close the old log file. 2463 2624 */ 2464 if (pLogger->p File->File != NIL_RTFILE)2625 if (pLogger->pInt->u.hFile != NIL_RTFILE) 2465 2626 { 2466 2627 /* Use the callback to generate some final log contents, but only if 2467 2628 * this is a rotation with a fully set up logger. Leave the other case 2468 2629 * to the RTLogCreateExV function. */ 2469 if (pLogger->p File->pfnPhase && !fFirst)2630 if (pLogger->pInt->pfnPhase && !fFirst) 2470 2631 { 2471 2632 uint32_t fODestFlags = pLogger->fDestFlags; 2472 2633 pLogger->fDestFlags &= RTLOGDEST_FILE; 2473 pLogger->p File->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);2634 pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked); 2474 2635 pLogger->fDestFlags = fODestFlags; 2475 2636 } 2476 RTFileClose(pLogger->p File->File);2477 pLogger->p File->File = NIL_RTFILE;2637 RTFileClose(pLogger->pInt->u.hFile); 2638 pLogger->pInt->u.hFile = NIL_RTFILE; 2478 2639 } 2479 2640 … … 2485 2646 for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--) 2486 2647 { 2487 char szOldName[ RTPATH_MAX];2648 char szOldName[sizeof(pLogger->pInt->szFilename) + 32]; 2488 2649 if (i > 0) 2489 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->p File->pszFilename, i);2650 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pInt->szFilename, i); 2490 2651 else 2491 RTStrCopy(szOldName, sizeof(szOldName), pLogger->pFile->pszFilename); 2492 char szNewName[RTPATH_MAX]; 2493 RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pFile->pszFilename, i + 1); 2494 if (RTFileRename(szOldName, szNewName, 2495 RTFILEMOVE_FLAGS_REPLACE) == VERR_FILE_NOT_FOUND) 2652 RTStrCopy(szOldName, sizeof(szOldName), pLogger->pInt->szFilename); 2653 2654 char szNewName[sizeof(pLogger->pInt->szFilename) + 32]; 2655 RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pInt->szFilename, i + 1); 2656 if ( RTFileRename(szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE) 2657 == VERR_FILE_NOT_FOUND) 2496 2658 RTFileDelete(szNewName); 2497 2659 } … … 2502 2664 for (uint32_t i = cSavedHistory + 1; ; i++) 2503 2665 { 2504 char szExcessName[ RTPATH_MAX];2505 RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->p File->pszFilename, i);2666 char szExcessName[sizeof(pLogger->pInt->szFilename) + 32]; 2667 RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pInt->szFilename, i); 2506 2668 int rc = RTFileDelete(szExcessName); 2507 2669 if (RT_FAILURE(rc)) … … 2513 2675 * Update logger state and create new log file. 2514 2676 */ 2515 pLogger->p File->cbHistoryFileWritten = 0;2516 pLogger->p File->uHistoryTimeSlotStart = uTimeSlot;2677 pLogger->pInt->cbHistoryFileWritten = 0; 2678 pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot; 2517 2679 rtlogFileOpen(pLogger, NULL, 0); 2518 2680 … … 2522 2684 * RTLogCreateExV function. 2523 2685 */ 2524 if (pLogger->p File->pfnPhase && !fFirst)2686 if (pLogger->pInt->pfnPhase && !fFirst) 2525 2687 { 2526 2688 uint32_t const fSavedDestFlags = pLogger->fDestFlags; 2527 2689 pLogger->fDestFlags &= RTLOGDEST_FILE; 2528 pLogger->p File->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);2690 pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked); 2529 2691 pLogger->fDestFlags = fSavedDestFlags; 2530 2692 } 2531 2693 2532 2694 /* Restore saved values. */ 2533 pLogger->p File->cHistory = cSavedHistory;2695 pLogger->pInt->cHistory = cSavedHistory; 2534 2696 pLogger->fFlags = fSavedFlags; 2535 2697 } … … 2559 2721 if (pLogger->fDestFlags & RTLOGDEST_FILE) 2560 2722 { 2561 if (pLogger->p File->File != NIL_RTFILE)2562 { 2563 RTFileWrite(pLogger->p File->File, pLogger->achScratch, pLogger->offScratch, NULL);2723 if (pLogger->pInt->u.hFile != NIL_RTFILE) 2724 { 2725 RTFileWrite(pLogger->pInt->u.hFile, pLogger->achScratch, pLogger->offScratch, NULL); 2564 2726 if (pLogger->fFlags & RTLOGFLAGS_FLUSH) 2565 RTFileFlush(pLogger->p File->File);2566 } 2567 if (pLogger->p File->cHistory)2568 pLogger->p File->cbHistoryFileWritten += pLogger->offScratch;2727 RTFileFlush(pLogger->pInt->u.hFile); 2728 } 2729 if (pLogger->pInt->cHistory) 2730 pLogger->pInt->cbHistoryFileWritten += pLogger->offScratch; 2569 2731 } 2570 2732 # endif … … 2582 2744 #endif /* !IN_RC */ 2583 2745 2746 #ifdef IN_RC 2584 2747 if (pLogger->pfnFlush) 2585 2748 pLogger->pfnFlush(pLogger); 2749 #else 2750 if (pLogger->pInt->pfnFlush) 2751 pLogger->pInt->pfnFlush(pLogger); 2752 #endif 2586 2753 2587 2754 /* empty the buffer. */ … … 2595 2762 */ 2596 2763 if ( (pLogger->fDestFlags & RTLOGDEST_FILE) 2597 && pLogger->pFile->cHistory) 2598 rtlogRotate(pLogger, 2599 RTTimeProgramSecTS() / pLogger->pFile->cSecsHistoryTimeSlot, 2600 false /* fFirst */); 2764 && pLogger->pInt->cHistory) 2765 rtlogRotate(pLogger, RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /* fFirst */); 2601 2766 #endif 2602 2767 } … … 2678 2843 for (;;) 2679 2844 { 2680 size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1; 2681 char *psz; 2845 size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1; 2682 2846 const char *pszNewLine; 2847 char *psz; 2848 #ifdef IN_RC 2849 bool *pfPendingPrefix = &pLogger->fPendingPrefix; 2850 #else 2851 bool *pfPendingPrefix = &pLogger->pInt->fPendingPrefix; 2852 #endif 2683 2853 2684 2854 /* 2685 2855 * Pending prefix? 2686 2856 */ 2687 if ( pLogger->fPendingPrefix)2857 if (*pfPendingPrefix) 2688 2858 { 2689 pLogger->fPendingPrefix = false;2859 *pfPendingPrefix = false; 2690 2860 2691 2861 #if defined(DEBUG) && defined(IN_RING3) … … 2880 3050 #ifndef IN_RC 2881 3051 if ( (pLogger->fFlags & RTLOGFLAGS_PREFIX_CUSTOM) 2882 && pLogger->p fnPrefix)3052 && pLogger->pInt->pfnPrefix) 2883 3053 { 2884 psz += pLogger->p fnPrefix(pLogger, psz, 31, pLogger->pvPrefixUserArg);3054 psz += pLogger->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg); 2885 3055 *psz++ = ' '; /* +32 */ 2886 3056 } … … 2917 3087 { 2918 3088 #ifdef IN_RING3 2919 const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->p apszGroups[pArgs->iGroup] : NULL;3089 const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->pInt->papszGroups[pArgs->iGroup] : NULL; 2920 3090 #else 2921 3091 const char *pszGroup = NULL; … … 2966 3136 case RTLOGGRPFLAGS_LELIK: pszGroup = "lelik" ; cch = sizeof("lelik" ) - 1; break; 2967 3137 case RTLOGGRPFLAGS_MICHAEL: pszGroup = "Michael" ; cch = sizeof("Michael" ) - 1; break; 2968 case RTLOGGRPFLAGS_DMIK: pszGroup = "dmik" ; cch = sizeof("dmik" ) - 1; break;2969 3138 case RTLOGGRPFLAGS_SUNLOVER: pszGroup = "sunlover"; cch = sizeof("sunlover") - 1; break; 2970 3139 case RTLOGGRPFLAGS_ACHIM: pszGroup = "Achim" ; cch = sizeof("Achim" ) - 1; break; … … 3024 3193 { 3025 3194 cb = pszNewLine - pachChars + 1; 3026 pLogger->fPendingPrefix = true;3195 *pfPendingPrefix = true; 3027 3196 } 3028 3197 } … … 3045 3214 cbChars--; 3046 3215 cb++; 3047 pLogger->fPendingPrefix = true;3216 *pfPendingPrefix = true; 3048 3217 } 3049 3218 … … 3102 3271 } 3103 3272 3273 3274 /** 3275 * For calling rtlogLoggerExVLocked. 3276 * 3277 * @param pLogger The logger. 3278 * @param fFlags The logging flags. 3279 * @param iGroup The group. 3280 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is 3281 * only for internal usage! 3282 * @param pszFormat Format string. 3283 * @param ... Format arguments. 3284 */ 3285 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...) 3286 { 3287 va_list va; 3288 va_start(va, pszFormat); 3289 rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, va); 3290 va_end(va); 3291 } 3292
Note:
See TracChangeset
for help on using the changeset viewer.