VirtualBox

Changeset 90829 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Aug 24, 2021 10:26:07 AM (3 years ago)
Author:
vboxsync
Message:

IPRT,VMM,SUPDrv,++: Reworked the IPRT logger structure and how the VMM ring-0 uses it. bugref:10086

Location:
trunk/src/VBox/Runtime/common/log
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/log/log.cpp

    r90803 r90829  
    3434#ifndef IN_RC
    3535# include <iprt/alloc.h>
     36# include <iprt/crc.h>
    3637# include <iprt/process.h>
    3738# include <iprt/semaphore.h>
     
    8990AssertCompile(sizeof(RTLOG_RINGBUF_EYE_CATCHER_END) == 16);
    9091
     92/** The default buffer size. */
     93#define RTLOG_BUFFER_DEFAULT_SIZE       _64K
     94/** Buffer alignment used RTLogCreateExV.   */
     95#define RTLOG_BUFFER_ALIGN              64
     96
    9197
    9298/*********************************************************************************************************************************
     
    94100*********************************************************************************************************************************/
    95101/**
    96  * Arguments passed to the output function.
    97  */
    98 typedef struct RTLOGOUTPUTPREFIXEDARGS
    99 {
    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_RC
    109 
    110 /**
    111102 * Internal logger data.
    112103 *
     
    115106typedef struct RTLOGGERINTERNAL
    116107{
     108    /** The public logger core. */
     109    RTLOGGER                Core;
     110
    117111    /** The structure revision (RTLOGGERINTERNAL_REV). */
    118112    uint32_t                uRevision;
    119113    /** The size of the internal logger structure. */
    120114    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;
    121129
    122130    /** Spinning mutex semaphore.  Can be NIL. */
     
    181189    char                    szR0ThreadName[16];
    182190
    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... */
    184192    /** @name File logging bits for the logger.
    185193     * @{ */
     
    205213    char                    szFilename[RTPATH_MAX];
    206214    /** @} */
    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];
    208224} RTLOGGERINTERNAL;
    209225
    210226/** 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
     229AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t));
     230#ifdef IN_RING3
    214231/** The size of the RTLOGGERINTERNAL structure in ring-0.  */
    215 #  define RTLOGGERINTERNAL_R0_SIZE       RT_UOFFSETOF(RTLOGGERINTERNAL, pfnPhase)
     232# define RTLOGGERINTERNAL_R0_SIZE       RT_UOFFSETOF(RTLOGGERINTERNAL, pfnPhase)
    216233AssertCompileMemberAlignment(RTLOGGERINTERNAL, hFile, sizeof(void *));
    217234AssertCompileMemberAlignment(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. */
     239typedef struct RTLOGGERINTERNAL *PRTLOGGERINTERNAL;
     240/**
     241 * Arguments passed to the output function.
     242 */
     243typedef 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;
    222252
    223253
     
    233263#endif
    234264#ifdef IN_RING3
    235 static int  rtR3LogOpenFileDestination(PRTLOGGER pLogger, PRTERRINFO pErrInfo);
     265static int  rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo);
    236266#endif
    237267#ifndef IN_RC
    238 static void rtLogRingBufFlush(PRTLOGGER pLogger);
     268static void rtLogRingBufFlush(PRTLOGGERINTERNAL pLoggerInt);
    239269#endif
    240 static void rtlogFlush(PRTLOGGER pLogger, bool fNeedSpace);
     270static void rtlogFlush(PRTLOGGERINTERNAL pLoggerInt, bool fNeedSpace);
    241271static 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);
     272static void rtlogLoggerExVLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup,
     273                                const char *pszFormat, va_list args);
    244274#ifndef IN_RC
    245 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
     275static void rtlogLoggerExFLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
    246276#endif
    247277
     
    250280*   Global Variables                                                                                                             *
    251281*********************************************************************************************************************************/
    252 #ifdef IN_RC
     282#ifndef IN_RC
     283/** Default logger instance. */
     284static PRTLOGGER                    g_pLogger;
     285/** Default release logger instance. */
     286static PRTLOGGER                    g_pRelLogger;
     287#else
    253288/** Default logger instance. Make it weak because our RC module loader does not
    254289 *  necessarily resolve this symbol and the compiler _must_ check if this is
     
    256291 *  .weak_reference (must specify "-dynamic" to be used'') */
    257292# ifdef RT_OS_DARWIN
    258 extern "C" DECLIMPORT(RTLOGGERRC) g_Logger;
     293extern "C" DECLIMPORT(RTLOGGERRC)   g_Logger;
     294/** Default release logger instance. */
     295extern "C" DECLIMPORT(RTLOGGERRC)   g_RelLogger;
    259296# else
    260297extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_Logger;
     298/** Default release logger instance. */
     299extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_RelLogger;
    261300# endif
    262 #else /* !IN_RC */
    263 /** Default logger instance. */
    264 static PRTLOGGER                    g_pLogger;
    265 #endif /* !IN_RC */
     301#endif /* IN_RC */
    266302#ifdef IN_RING3
    267303/** The RTThreadGetWriteLockCount() change caused by the logger mutex semaphore. */
     
    303339    const char *pszInstr;               /**< The name  */
    304340    size_t      cchInstr;               /**< The size of the name. */
    305     uint32_t    fFlag;                  /**< The flag value. */
     341    uint64_t    fFlag;                  /**< The flag value. */
    306342    bool        fInverted;              /**< Inverse meaning? */
    307343    uint32_t    fFixedDest;             /**< RTLOGDEST_FIXED_XXX flags blocking this. */
     
    381417 *
    382418 * @returns See RTSemSpinMutexRequest().
    383  * @param   pLogger     The logger instance.
    384  */
    385 DECLINLINE(int) rtlogLock(PRTLOGGER pLogger)
     419 * @param   pLoggerInt  The logger instance.
     420 */
     421DECLINLINE(int) rtlogLock(PRTLOGGERINTERNAL pLoggerInt)
    386422{
    387423#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),
    390427                    VERR_LOG_REVISION_MISMATCH);
    391     AssertMsgReturn(pInt->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)),
     428    AssertMsgReturn(pLoggerInt->cbSelf == sizeof(*pLoggerInt), ("%#x != %#x\n", pLoggerInt->cbSelf, sizeof(*pLoggerInt)),
    392429                    VERR_LOG_REVISION_MISMATCH);
    393     if (pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
    394     {
    395         int rc = RTSemSpinMutexRequest(pInt->hSpinMtx);
     430    if (pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
     431    {
     432        int rc = RTSemSpinMutexRequest(pLoggerInt->hSpinMtx);
    396433        if (RT_FAILURE(rc))
    397434            return rc;
    398435    }
    399436#else
    400     NOREF(pLogger);
     437    NOREF(pLoggerInt);
    401438#endif
    402439    return VINF_SUCCESS;
     
    406443/**
    407444 * Unlocks the logger instance.
    408  * @param   pLogger     The logger instance.
    409  */
    410 DECLINLINE(void) rtlogUnlock(PRTLOGGER pLogger)
     445 * @param   pLoggerInt  The logger instance.
     446 */
     447DECLINLINE(void) rtlogUnlock(PRTLOGGERINTERNAL pLoggerInt)
    411448{
    412449#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);
    415452#else
    416     NOREF(pLogger);
     453    NOREF(pLoggerInt);
    417454#endif
    418455    return;
     
    432469static DECLCALLBACK(size_t) rtlogPhaseWrite(void *pvArg, const char *pachChars, size_t cbChars)
    433470{
    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);
    436473    return cbChars;
    437474}
     
    477514static DECLCALLBACK(void) rtlogPhaseMsgLocked(PRTLOGGER pLogger, const char *pszFormat, ...)
    478515{
     516    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     517    AssertPtrReturnVoid(pLoggerInt);
     518    Assert(pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
     519
    479520    va_list args;
    480     AssertPtrReturnVoid(pLogger);
    481     AssertPtrReturnVoid(pLogger->pInt);
    482     Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
    483 
    484521    va_start(args, pszFormat);
    485     rtlogLoggerExVLocked(pLogger, 0, ~0U, pszFormat, args);
     522    rtlogLoggerExVLocked(pLoggerInt, 0, ~0U, pszFormat, args);
    486523    va_end(args);
    487524}
     
    497534static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *pszFormat, ...)
    498535{
     536    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     537    AssertPtrReturnVoid(pLoggerInt);
     538    Assert(pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
     539
    499540    va_list args;
    500     AssertPtrReturnVoid(pLogger);
    501     AssertPtrReturnVoid(pLogger->pInt);
    502     Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
    503 
    504541    va_start(args, pszFormat);
    505     RTLogLoggerExV(pLogger, 0, ~0U, pszFormat, args);
     542    RTLogLoggerExV(&pLoggerInt->Core, 0, ~0U, pszFormat, args);
    506543    va_end(args);
    507544}
     
    513550 *
    514551 * @returns IPRT status code.
    515  * @param   pLogger     The logger instance.
     552 * @param   pLoggerInt  The logger instance.
    516553 * @param   cbNewSize   The new ring buffer size (0 == default).
    517554 * @param   fForce      Whether to do this even if the logger instance hasn't
    518555 *                      really been fully created yet (i.e. during RTLogCreate).
    519556 */
    520 static int rtLogRingBufAdjust(PRTLOGGER pLogger, uint32_t cbNewSize, bool fForce)
     557static int rtLogRingBufAdjust(PRTLOGGERINTERNAL pLoggerInt, uint32_t cbNewSize, bool fForce)
    521558{
    522559    /*
    523560     * If this is early logger init, don't do anything.
    524561     */
    525     if (!pLogger->pInt->fCreated && !fForce)
     562    if (!pLoggerInt->fCreated && !fForce)
    526563        return VINF_SUCCESS;
    527564
     
    529566     * Lock the logger and make the necessary changes.
    530567     */
    531     int rc = rtlogLock(pLogger);
     568    int rc = rtlogLock(pLoggerInt);
    532569    if (RT_SUCCESS(rc))
    533570    {
    534571        if (cbNewSize == 0)
    535572            cbNewSize = RTLOG_RINGBUF_DEFAULT_SIZE;
    536         if (   pLogger->pInt->cbRingBuf != cbNewSize
    537             || !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;
    540577            if (offOld < sizeof(RTLOG_RINGBUF_EYE_CATCHER))
    541578                offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER);
    542579            else if (offOld >= cbNewSize)
    543580            {
    544                 memmove(pLogger->pInt->pszRingBuf, &pLogger->pInt->pszRingBuf[offOld - cbNewSize], cbNewSize);
     581                memmove(pLoggerInt->pszRingBuf, &pLoggerInt->pszRingBuf[offOld - cbNewSize], cbNewSize);
    545582                offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER);
    546583            }
    547584
    548             void *pvNew = RTMemRealloc(pLogger->pInt->pchRingBufCur, cbNewSize);
     585            void *pvNew = RTMemRealloc(pLoggerInt->pchRingBufCur, cbNewSize);
    549586            if (pvNew)
    550587            {
    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;
    554591                memcpy(pvNew, RTLOG_RINGBUF_EYE_CATCHER, sizeof(RTLOG_RINGBUF_EYE_CATCHER));
    555592                memcpy((char *)pvNew + cbNewSize - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END),
     
    560597                rc = VERR_NO_MEMORY;
    561598        }
    562         rtlogUnlock(pLogger);
     599        rtlogUnlock(pLoggerInt);
    563600    }
    564601
     
    642679 * Flushes the ring buffer to all the other log destinations.
    643680 *
    644  * @param   pLogger     The logger instance which ring buffer should be flushed.
    645  */
    646 static void rtLogRingBufFlush(PRTLOGGER pLogger)
     681 * @param   pLoggerInt  The logger instance which ring buffer should be flushed.
     682 */
     683static void rtLogRingBufFlush(PRTLOGGERINTERNAL pLoggerInt)
    647684{
    648685    const char  *pszPreamble;
     
    657694     * part of the buffer.
    658695     */
    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;
    663700    size_t       cchAfter;
    664701    if (RT_LIKELY(offCur < cchBuf))
     
    670707    }
    671708
    672     pLogger->pInt->cbRingBufUnflushed = 0;
     709    pLoggerInt->cbRingBufUnflushed = 0;
    673710
    674711    /*
     
    711748     * Write the ring buffer to all other destiations.
    712749     */
    713     if (pLogger->fDestFlags & RTLOGDEST_USER)
     750    if (pLoggerInt->fDestFlags & RTLOGDEST_USER)
    714751    {
    715752        if (cchPreamble)
     
    721758    }
    722759
    723     if (pLogger->fDestFlags & RTLOGDEST_DEBUGGER)
     760    if (pLoggerInt->fDestFlags & RTLOGDEST_DEBUGGER)
    724761    {
    725762        if (cchPreamble)
     
    732769
    733770# 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)
    737774        {
    738775            if (cchPreamble)
    739                 RTFileWrite(pLogger->pInt->hFile, pszPreamble, cchPreamble, NULL);
     776                RTFileWrite(pLoggerInt->hFile, pszPreamble, cchPreamble, NULL);
    740777            if (cchFirst)
    741                 RTFileWrite(pLogger->pInt->hFile, pszFirst, cchFirst, NULL);
     778                RTFileWrite(pLoggerInt->hFile, pszFirst, cchFirst, NULL);
    742779            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;
    749786    }
    750787# endif
    751788
    752     if (pLogger->fDestFlags & RTLOGDEST_STDOUT)
     789    if (pLoggerInt->fDestFlags & RTLOGDEST_STDOUT)
    753790    {
    754791        if (cchPreamble)
     
    760797    }
    761798
    762     if (pLogger->fDestFlags & RTLOGDEST_STDERR)
     799    if (pLoggerInt->fDestFlags & RTLOGDEST_STDERR)
    763800    {
    764801        if (cchPreamble)
     
    771808
    772809# if defined(IN_RING0) && !defined(LOG_NO_COM)
    773     if (pLogger->fDestFlags & RTLOGDEST_COM)
     810    if (pLoggerInt->fDestFlags & RTLOGDEST_COM)
    774811    {
    775812        if (cchPreamble)
     
    784821
    785822
    786 RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, const char *pszEnvVarBase,
    787                            unsigned cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
    788                            uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
    789                            uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
     823RTDECL(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,
    790827                           PRTERRINFO pErrInfo, const char *pszFilenameFmt, va_list args)
    791828{
    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;
    796834
    797835    /*
    798836     * Validate input.
    799837     */
    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);
    806839    *ppLogger = NULL;
    807 
     840    if (cGroups)
     841    {
     842        AssertPtrReturn(papszGroups, VERR_INVALID_POINTER);
     843        AssertReturn(cGroups < _8K, VERR_OUT_OF_RANGE);
     844    }
    808845    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]);
    816853    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
    817854        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)
    820900    {
    821901# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
    822902        uint8_t *pu8Code;
    823903# 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;
    841920        if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
    842             pLogger->pInt->pacEntriesPerGroup   = (uint32_t *)(pLogger->pInt + 1);
     921            pLoggerInt->pacEntriesPerGroup      = (uint32_t *)(pLoggerInt + 1);
    843922        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;
    846925# 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;
    850929        if (cbHistoryFileMax == 0)
    851             pLogger->pInt->cbHistoryFileMax     = UINT64_MAX;
     930            pLoggerInt->cbHistoryFileMax        = UINT64_MAX;
    852931        else
    853             pLogger->pInt->cbHistoryFileMax     = cbHistoryFileMax;
     932            pLoggerInt->cbHistoryFileMax        = cbHistoryFileMax;
    854933        if (cSecsHistoryTimeSlot == 0)
    855             pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
     934            pLoggerInt->cSecsHistoryTimeSlot    = UINT32_MAX;
    856935        else
    857             pLogger->pInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
     936            pLoggerInt->cSecsHistoryTimeSlot    = cSecsHistoryTimeSlot;
    858937# else   /* !IN_RING3 */
    859938        RT_NOREF_PV(pfnPhase); RT_NOREF_PV(cHistory); RT_NOREF_PV(cbHistoryFileMax); RT_NOREF_PV(cSecsHistoryTimeSlot);
    860939# endif  /* !IN_RING3 */
    861940        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;
    863984
    864985# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
     
    869990        if (pu8Code)
    870991        {
    871             pLogger->pfnLogger = *(PFNRTLOGGER*)&pu8Code;
     992            pLoggerInt->Core.pfnLogger = *(PFNRTLOGGER *)&pu8Code;
    872993            *pu8Code++ = 0x68;          /* push imm32 */
    873             *(void **)pu8Code = pLogger;
     994            *(void **)pu8Code = &pLoggerInt->Core;
    874995            pu8Code += sizeof(void *);
    875996            *pu8Code++ = 0xe8;          /* call rel32 */
     
    8811002            *pu8Code++ = 0x04;
    8821003            *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));
    8851006            rc = VINF_SUCCESS;
    8861007        }
     
    8891010            rc = VERR_NO_MEMORY;
    8901011#  ifdef RT_OS_LINUX
    891                 /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
     1012            /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
    8921013            RTErrInfoSet(pErrInfo, rc, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?"));
    8931014#  endif
     
    9031024            {
    9041025                /** @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;
    9081029            }
    9091030
     
    9241045                const char *pszValue = RTEnvGet(pszEnvVar);
    9251046                if (pszValue)
    926                     RTLogDestinations(pLogger, pszValue);
     1047                    RTLogDestinations(&pLoggerInt->Core, pszValue);
    9271048
    9281049                /*
     
    9321053                pszValue = RTEnvGet(pszEnvVar);
    9331054                if (pszValue)
    934                     RTLogFlags(pLogger, pszValue);
     1055                    RTLogFlags(&pLoggerInt->Core, pszValue);
    9351056
    9361057                /*
     
    9401061                pszValue = RTEnvGet(pszEnvVar);
    9411062                if (pszValue)
    942                     RTLogGroupSettings(pLogger, pszValue);
     1063                    RTLogGroupSettings(&pLoggerInt->Core, pszValue);
    9431064
    9441065                /*
     
    9521073                    rc = RTStrToUInt32Full(pszValue, 0, &cMax);
    9531074                    if (RT_SUCCESS(rc))
    954                         pLogger->pInt->cMaxEntriesPerGroup = cMax ? cMax : UINT32_MAX;
     1075                        pLoggerInt->cMaxEntriesPerGroup = cMax ? cMax : UINT32_MAX;
    9551076                    else
    9561077                        AssertMsgFailed(("Invalid group limit! %s=%s\n", pszEnvVar, pszValue));
     
    9661087             */
    9671088            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;
    9701091# 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);
    9731094# endif
    9741095
    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*/);
    9771098
    9781099            /*
     
    9821103            if (RT_SUCCESS(rc))
    9831104            {
    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);
    9851107                if (RT_SUCCESS(rc))
    9861108                {
     
    9901112                    {
    9911113                        int32_t c = RTLockValidatorWriteLockGetCount(Thread);
    992                         RTSemSpinMutexRequest(pLogger->pInt->hSpinMtx);
     1114                        RTSemSpinMutexRequest(pLoggerInt->hSpinMtx);
    9931115                        c = RTLockValidatorWriteLockGetCount(Thread) - c;
    994                         RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
     1116                        RTSemSpinMutexRelease(pLoggerInt->hSpinMtx);
    9951117                        ASMAtomicWriteU32(&g_cLoggerLockCount, c);
    9961118                    }
    9971119
    9981120                    /* 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);
    10021124# endif
    1003                     pLogger->pInt->fCreated = true;
    1004                     *ppLogger = pLogger;
     1125                    pLoggerInt->fCreated = true;
     1126                    *ppLogger = &pLoggerInt->Core;
    10051127                    return VINF_SUCCESS;
    10061128                }
     
    10091131            }
    10101132# ifdef IN_RING3
    1011             RTFileClose(pLogger->pInt->hFile);
     1133            RTFileClose(pLoggerInt->hFile);
    10121134# endif
    10131135# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
    1014             RTMemFree(*(void **)&pLogger->pfnLogger);
     1136            RTMemFree(*(void **)&pLoggerInt->Core.pfnLogger);
    10151137# else
    1016             RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
     1138            RTMemExecFree(*(void **)&pLoggerInt->Core.pfnLogger, 64);
    10171139# endif
    10181140        }
    1019         RTMemFree(pLogger);
     1141        RTMemFree(pLoggerInt);
    10201142    }
    10211143    else
     
    10271149
    10281150
    1029 RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
     1151RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint64_t fFlags, const char *pszGroupSettings,
    10301152                        const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
    10311153                        uint32_t fDestFlags, const char *pszFilenameFmt, ...)
    10321154{
    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,
    10391162                        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);
    10421165    return rc;
    10431166}
     
    10451168
    10461169
    1047 RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, const char *pszEnvVarBase,
     1170RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
    10481171                          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,
    10511174                          PRTERRINFO pErrInfo, const char *pszFilenameFmt, ...)
    10521175{
    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);
    10611185    return rc;
    10621186}
     
    10741198RTDECL(int) RTLogDestroy(PRTLOGGER pLogger)
    10751199{
    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;
    10791204
    10801205    /*
    10811206     * Validate input.
    10821207     */
    1083     if (!pLogger)
     1208    if (!pLoggerInt)
    10841209        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);
    10881212
    10891213    /*
    10901214     * Acquire logger instance sem and disable all logging. (paranoia)
    10911215     */
    1092     rc = rtlogLock(pLogger);
     1216    rc = rtlogLock(pLoggerInt);
    10931217    AssertMsgRCReturn(rc, ("%Rrc\n", rc), rc);
    10941218
    1095     pLogger->fFlags |= RTLOGFLAGS_DISABLED;
    1096     iGroup = pLogger->cGroups;
     1219    pLoggerInt->fFlags |= RTLOGFLAGS_DISABLED;
     1220    iGroup = pLoggerInt->cGroups;
    10971221    while (iGroup-- > 0)
    1098         pLogger->afGroups[iGroup] = 0;
     1222        pLoggerInt->afGroups[iGroup] = 0;
    10991223
    11001224    /*
    11011225     * Flush it.
    11021226     */
    1103     rtlogFlush(pLogger, false /*fNeedSpace*/);
     1227    rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
    11041228
    11051229# ifdef IN_RING3
     
    11071231     * Add end of logging message.
    11081232     */
    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);
    11121236
    11131237    /*
    11141238     * Close output stuffs.
    11151239     */
    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);
    11191243        AssertRC(rc2);
    11201244        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
    11211245            rc = rc2;
    1122         pLogger->pInt->hFile = NIL_RTFILE;
     1246        pLoggerInt->hFile = NIL_RTFILE;
    11231247    }
    11241248# endif
     
    11271251     * Free the mutex, the wrapper and the instance memory.
    11281252     */
    1129     hSpinMtx = pLogger->pInt->hSpinMtx;
    1130     pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
     1253    hSpinMtx = pLoggerInt->hSpinMtx;
     1254    pLoggerInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
    11311255    if (hSpinMtx != NIL_RTSEMSPINMUTEX)
    11321256    {
     
    11391263    }
    11401264
    1141     if (pLogger->pfnLogger)
     1265    if (pLoggerInt->Core.pfnLogger)
    11421266    {
    11431267# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
    1144         RTMemFree(*(void **)&pLogger->pfnLogger);
     1268        RTMemFree(*(void **)&pLoggerInt->Core.pfnLogger);
    11451269# else
    1146         RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
     1270        RTMemExecFree(*(void **)&pLoggerInt->Core.pfnLogger, 64);
    11471271# endif
    1148         pLogger->pfnLogger = NULL;
    1149     }
    1150     RTMemFree(pLogger);
     1272        pLoggerInt->Core.pfnLogger = NULL;
     1273    }
     1274    RTMemFree(pLoggerInt);
    11511275
    11521276    return rc;
     
    11551279
    11561280
     1281# if 0 /* obsolete */
    11571282/**
    11581283 * Create a logger instance clone for RC usage.
     
    12371362}
    12381363RT_EXPORT_SYMBOL(RTLogCloneRC);
    1239 
    1240 
     1364# endif
     1365
     1366
     1367# if 0 /* obsolete */
    12411368/**
    12421369 * Flushes a RC logger instance to a R3 logger.
     
    12941421}
    12951422RT_EXPORT_SYMBOL(RTLogFlushRC);
     1423# endif
    12961424
    12971425# ifdef IN_RING3
    1298 
     1426#  if 0 /* obsolete */
    12991427RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
    13001428                             RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
     
    14721600RT_EXPORT_SYMBOL(RTLogFlushR0);
    14731601
     1602#  endif /* obsolete */
    14741603# endif /* IN_RING3 */
    14751604
    14761605
     1606#if 0
    14771607/**
    14781608 * Flushes the buffer in one logger instance onto another logger.
     
    14861616RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger)
    14871617{
     1618    PRTLOGGERINTERNAL pSrcLoggerInt = (PRTLOGGERINTERNAL)pSrcLogger;
     1619    PRTLOGGERINTERNAL pDstLoggerInt = (PRTLOGGERINTERNAL)pDstLogger;
     1620
    14881621    /*
    14891622     * Resolve defaults.
    14901623     */
    1491     if (!pDstLogger)
    1492     {
    1493         pDstLogger = RTLogDefaultInstance();
    1494         if (!pDstLogger)
     1624    if (!pDstLoggerInt)
     1625    {
     1626        pDstLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     1627        if (!pDstLoggerInt)
    14951628        {
    14961629            /* flushing to "/dev/null". */
    1497             if (pSrcLogger->offScratch)
     1630            if (pSrcLoggerInt->offScratch)
    14981631            {
    1499                 int rc = rtlogLock(pSrcLogger);
     1632                int rc = rtlogLock(pSrcLoggerInt);
    15001633                if (RT_SUCCESS(rc))
    15011634                {
    1502                     pSrcLogger->offScratch = 0;
    1503                     rtlogUnlock(pSrcLogger);
     1635                    pSrcLoggerInt->offScratch = 0;
     1636                    rtlogUnlock(pSrcLoggerInt);
    15041637                }
    15051638            }
     
    15111644     * Any thing to flush?
    15121645     */
    1513     if (    pSrcLogger->offScratch
    1514         ||  pDstLogger->offScratch)
     1646    if (    pSrcLoggerInt->offScratch
     1647        ||  pDstLoggerInt->offScratch)
    15151648    {
    15161649        /*
    15171650         * Acquire logger semaphores.
    15181651         */
    1519         int rc = rtlogLock(pDstLogger);
     1652        int rc = rtlogLock(pDstLoggerInt);
    15201653        if (RT_FAILURE(rc))
    15211654            return;
    1522         rc = rtlogLock(pSrcLogger);
     1655        rc = rtlogLock(pSrcLoggerInt);
    15231656        if (RT_SUCCESS(rc))
    15241657        {
     
    15271660             * flush the HC instance.
    15281661             */
    1529             if (pSrcLogger->offScratch)
     1662            if (pSrcLoggerInt->offScratch)
    15301663            {
    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;
    15341667            }
    15351668
     
    15371670             * Release the semaphores.
    15381671             */
    1539             rtlogUnlock(pSrcLogger);
    1540         }
    1541         rtlogUnlock(pDstLogger);
     1672            rtlogUnlock(pSrcLoggerInt);
     1673        }
     1674        rtlogUnlock(pDstLoggerInt);
    15421675    }
    15431676}
    15441677RT_EXPORT_SYMBOL(RTLogFlushToLogger);
     1678#endif
    15451679
    15461680
     
    15581692     * Resolve defaults.
    15591693     */
    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)
    15641699            return VINF_SUCCESS;
    15651700    }
    1566     AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     1701    AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
    15671702
    15681703    /*
    15691704     * Do the work.
    15701705     */
    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);
    15751710
    15761711    return VINF_SUCCESS;
     
    16661801RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue)
    16671802{
     1803
    16681804    /*
    16691805     * Resolve defaults.
    16701806     */
    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)
    16751812            return VINF_SUCCESS;
    16761813    }
     1814    Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC);
    16771815
    16781816    /*
     
    17231861                            ? RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1
    17241862                            : rtlogGroupFlags(&pszStart[3]);
    1725             for (i = 0; i < pLogger->cGroups; i++)
     1863            for (i = 0; i < pLoggerInt->cGroups; i++)
    17261864            {
    17271865                if (fEnabled)
    1728                     pLogger->afGroups[i] |= fFlags;
     1866                    pLoggerInt->afGroups[i] |= fFlags;
    17291867                else
    1730                     pLogger->afGroups[i] &= ~fFlags;
     1868                    pLoggerInt->afGroups[i] &= ~fFlags;
    17311869            }
    17321870        }
     
    17361874             * Specific group(s).
    17371875             */
    1738             for (i = 0; i < pLogger->cGroups; i++)
     1876            for (i = 0; i < pLoggerInt->cGroups; i++)
    17391877            {
    17401878                const char *psz2 = (const char*)pszStart;
    1741                 if (rtlogIsGroupMatching(pLogger->pInt->papszGroups[i], &psz2, cch))
     1879                if (rtlogIsGroupMatching(pLoggerInt->papszGroups[i], &psz2, cch))
    17421880                {
    17431881                    unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1;
     
    17451883                        fFlags = rtlogGroupFlags(psz2);
    17461884                    if (fEnabled)
    1747                         pLogger->afGroups[i] |= fFlags;
     1885                        pLoggerInt->afGroups[i] |= fFlags;
    17481886                    else
    1749                         pLogger->afGroups[i] &= ~fFlags;
     1887                        pLoggerInt->afGroups[i] &= ~fFlags;
    17501888                }
    17511889            } /* for each group */
     
    19202058RTDECL(int) RTLogQueryGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
    19212059{
    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;
    19272066
    19282067    Assert(cchBuf);
     
    19312070     * Resolve defaults.
    19322071     */
    1933     if (!pLogger)
    1934     {
    1935         pLogger = RTLogDefaultInstance();
    1936         if (!pLogger)
     2072    if (!pLoggerInt)
     2073    {
     2074        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2075        if (!pLoggerInt)
    19372076        {
    19382077            *pszBuf = '\0';
     
    19402079        }
    19412080    }
    1942 
    1943     cGroups = pLogger->cGroups;
     2081    Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC);
     2082
     2083    cGroups = pLoggerInt->cGroups;
    19442084
    19452085    /*
    19462086     * Check if all are the same.
    19472087     */
    1948     fGroup = pLogger->afGroups[0];
     2088    fGroup = pLoggerInt->afGroups[0];
    19492089    for (i = 1; i < cGroups; i++)
    1950         if (pLogger->afGroups[i] != fGroup)
     2090        if (pLoggerInt->afGroups[i] != fGroup)
    19512091            break;
    19522092    if (i >= cGroups)
     
    19602100        for (i = 0; i < cGroups; i++)
    19612101        {
    1962             fGroup = pLogger->afGroups[i];
     2102            fGroup = pLoggerInt->afGroups[i];
    19632103            if (fGroup)
    19642104            {
    1965                 const char *pszName = pLogger->pInt->papszGroups[i];
     2105                const char *pszName = pLoggerInt->papszGroups[i];
    19662106                if (pszName)
    19672107                {
     
    19922132RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue)
    19932133{
    1994     int rc = VINF_SUCCESS;
     2134    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2135    int               rc         = VINF_SUCCESS;
    19952136
    19962137    /*
    19972138     * Resolve defaults.
    19982139     */
    1999     if (!pLogger)
    2000     {
    2001         pLogger = RTLogDefaultInstance();
    2002         if (!pLogger)
     2140    if (!pLoggerInt)
     2141    {
     2142        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2143        if (!pLoggerInt)
    20032144            return VINF_SUCCESS;
    20042145    }
     
    20462187            if (!strncmp(pszValue, g_aLogFlags[i].pszInstr, g_aLogFlags[i].cchInstr))
    20472188            {
    2048                 if (!(g_aLogFlags[i].fFixedDest & pLogger->fDestFlags))
     2189                if (!(g_aLogFlags[i].fFixedDest & pLoggerInt->fDestFlags))
    20492190                {
    20502191                    if (fNo == g_aLogFlags[i].fInverted)
    2051                         pLogger->fFlags |= g_aLogFlags[i].fFlag;
     2192                        pLoggerInt->fFlags |= g_aLogFlags[i].fFlag;
    20522193                    else
    2053                         pLogger->fFlags &= ~g_aLogFlags[i].fFlag;
     2194                        pLoggerInt->fFlags &= ~g_aLogFlags[i].fFlag;
    20542195                }
    20552196                pszValue += g_aLogFlags[i].cchInstr;
     
    20872228RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered)
    20882229{
    2089     bool fOld;
     2230    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2231    bool              fOld;
    20902232
    20912233    /*
    20922234     * Resolve the logger instance.
    20932235     */
    2094     if (!pLogger)
    2095     {
    2096         pLogger = RTLogDefaultInstance();
    2097         if (!pLogger)
     2236    if (!pLoggerInt)
     2237    {
     2238        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2239        if (!pLoggerInt)
    20982240            return false;
    20992241    }
    21002242
    2101     rtlogLock(pLogger);
    2102     fOld  = !!(pLogger->fFlags & RTLOGFLAGS_BUFFERED);
     2243    rtlogLock(pLoggerInt);
     2244    fOld  = !!(pLoggerInt->fFlags & RTLOGFLAGS_BUFFERED);
    21032245    if (fBuffered)
    2104         pLogger->fFlags |= RTLOGFLAGS_BUFFERED;
     2246        pLoggerInt->fFlags |= RTLOGFLAGS_BUFFERED;
    21052247    else
    2106         pLogger->fFlags &= ~RTLOGFLAGS_BUFFERED;
    2107     rtlogUnlock(pLogger);
     2248        pLoggerInt->fFlags &= ~RTLOGFLAGS_BUFFERED;
     2249    rtlogUnlock(pLoggerInt);
    21082250
    21092251    return fOld;
     
    21152257RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup)
    21162258{
     2259    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2260
    21172261    /*
    21182262     * Resolve the logger instance.
    21192263     */
    2120     if (!pLogger)
    2121     {
    2122         pLogger = RTLogDefaultInstance();
    2123         if (!pLogger)
     2264    if (!pLoggerInt)
     2265    {
     2266        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2267        if (!pLoggerInt)
    21242268            return UINT32_MAX;
    21252269    }
    21262270
    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);
    21312275
    21322276    return cOld;
    21332277}
     2278#endif
     2279
     2280
     2281#ifdef IN_RING0
     2282RTR0DECL(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}
     2305RT_EXPORT_SYMBOL(RTLogSetR0ThreadNameF);
    21342306#endif
    21352307
     
    21442316RTDECL(uint64_t) RTLogGetFlags(PRTLOGGER pLogger)
    21452317{
    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)
    21502323            return UINT64_MAX;
    21512324    }
    2152     return pLogger->fFlags;
     2325    return pLoggerInt->fFlags;
    21532326}
    21542327RT_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 */
     2340RTDECL(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}
     2362RT_EXPORT_SYMBOL(RTLogChangeFlags);
    21552363
    21562364
     
    21662374RTDECL(int) RTLogQueryFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
    21672375{
    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;
    21722381
    21732382    Assert(cchBuf);
     
    21762385     * Resolve defaults.
    21772386     */
    2178     if (!pLogger)
    2179     {
    2180         pLogger = RTLogDefaultInstance();
    2181         if (!pLogger)
     2387    if (!pLoggerInt)
     2388    {
     2389        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2390        if (!pLoggerInt)
    21822391        {
    21832392            *pszBuf = '\0';
     
    21892398     * Add the flags in the list.
    21902399     */
    2191     fFlags = pLogger->fFlags;
     2400    fFlags = pLoggerInt->fFlags;
    21922401    for (i = 0; i < RT_ELEMENTS(g_aLogFlags); i++)
    21932402        if (    !g_aLogFlags[i].fInverted
     
    22722481     * Resolve defaults.
    22732482     */
    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)
    22782488            return VINF_SUCCESS;
    22792489    }
     
    23132523            {
    23142524                if (!fNo)
    2315                     pLogger->fDestFlags |= g_aLogDst[i].fFlag;
     2525                    pLoggerInt->fDestFlags |= g_aLogDst[i].fFlag;
    23162526                else
    2317                     pLogger->fDestFlags &= ~g_aLogDst[i].fFlag;
     2527                    pLoggerInt->fDestFlags &= ~g_aLogDst[i].fFlag;
    23182528                pszValue += cchInstr;
    23192529
     
    23282538
    23292539# ifdef IN_RING3
    2330                     char szTmp[sizeof(pLogger->pInt->szFilename)];
     2540                    char szTmp[sizeof(pLoggerInt->szFilename)];
    23312541# else
    23322542                    char szTmp[32];
     
    23342544                    if (0)
    23352545                    { /* nothing */ }
    2336 #ifdef IN_RING3
     2546# ifdef IN_RING3
    23372547
    23382548                    /* log file name */
    23392549                    else if (i == 0 /* file */ && !fNo)
    23402550                    {
    2341                         if (!(pLogger->fDestFlags & RTLOGDEST_FIXED_FILE))
     2551                        if (!(pLoggerInt->fDestFlags & RTLOGDEST_FIXED_FILE))
    23422552                        {
    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 ... */
    23472557                        }
    23482558                    }
     
    23502560                    else if (i == 1 /* dir */ && !fNo)
    23512561                    {
    2352                         if (!(pLogger->fDestFlags & RTLOGDEST_FIXED_DIR))
     2562                        if (!(pLoggerInt->fDestFlags & RTLOGDEST_FIXED_DIR))
    23532563                        {
    2354                             const char *pszFile = RTPathFilename(pLogger->pInt->szFilename);
     2564                            const char *pszFile = RTPathFilename(pLoggerInt->szFilename);
    23552565                            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);
    23572567                            memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1);
    23582568
    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 ... */
    23682578                        }
    23692579                    }
     
    23772587                                rc = RTStrToUInt32Full(szTmp, 0, &cHistory);
    23782588                            AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc);
    2379                             pLogger->pInt->cHistory = cHistory;
     2589                            pLoggerInt->cHistory = cHistory;
    23802590                        }
    23812591                        else
    2382                             pLogger->pInt->cHistory = 0;
     2592                            pLoggerInt->cHistory = 0;
    23832593                    }
    23842594                    else if (i == 3 /* histsize */)
     
    23882598                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
    23892599                            if (RT_SUCCESS(rc))
    2390                                 rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pInt->cbHistoryFileMax);
     2600                                rc = RTStrToUInt64Full(szTmp, 0, &pLoggerInt->cbHistoryFileMax);
    23912601                            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;
    23942604                        }
    23952605                        else
    2396                             pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
     2606                            pLoggerInt->cbHistoryFileMax = UINT64_MAX;
    23972607                    }
    23982608                    else if (i == 4 /* histtime */)
     
    24022612                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
    24032613                            if (RT_SUCCESS(rc))
    2404                                 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pInt->cSecsHistoryTimeSlot);
     2614                                rc = RTStrToUInt32Full(szTmp, 0, &pLoggerInt->cSecsHistoryTimeSlot);
    24052615                            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;
    24082618                        }
    24092619                        else
    2410                             pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
     2620                            pLoggerInt->cSecsHistoryTimeSlot = UINT32_MAX;
    24112621                    }
    24122622# endif /* IN_RING3 */
     
    24272637                        else
    24282638                            cbRingBuf = RT_ALIGN_32(cbRingBuf, 64);
    2429                         rc = rtLogRingBufAdjust(pLogger, cbRingBuf, false /*fForce*/);
     2639                        rc = rtLogRingBufAdjust(pLoggerInt, cbRingBuf, false /*fForce*/);
    24302640                        if (RT_FAILURE(rc))
    24312641                            return rc;
     
    24382648                    pszValue = pszEnd + (*pszEnd != '\0');
    24392649                }
    2440                 else if (i == 5 /* ringbuf */ && !fNo && !pLogger->pInt->pszRingBuf)
     2650                else if (i == 5 /* ringbuf */ && !fNo && !pLoggerInt->pszRingBuf)
    24412651                {
    2442                     int rc = rtLogRingBufAdjust(pLogger, pLogger->pInt->cbRingBuf, false /*fForce*/);
     2652                    int rc = rtLogRingBufAdjust(pLoggerInt, pLoggerInt->cbRingBuf, false /*fForce*/);
    24432653                    if (RT_FAILURE(rc))
    24442654                        return rc;
     
    24762686     * Resolve defaults.
    24772687     */
    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)
    24822693            return VINF_SUCCESS;
    24832694    }
     
    24862697     * Do the work.
    24872698     */
    2488     int rc = rtlogLock(pLogger);
     2699    int rc = rtlogLock(pLoggerInt);
    24892700    if (RT_SUCCESS(rc))
    24902701    {
    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;
    24942705# ifdef IN_RING3
    2495             if (   pLogger->fDestFlags & RTLOGDEST_FILE
    2496                 && pLogger->pInt->hFile == NIL_RTFILE)
     2706            if (   pLoggerInt->fDestFlags & RTLOGDEST_FILE
     2707                && pLoggerInt->hFile == NIL_RTFILE)
    24972708            {
    2498                 rc = rtR3LogOpenFileDestination(pLogger, pErrInfo);
     2709                rc = rtR3LogOpenFileDestination(pLoggerInt, pErrInfo);
    24992710                if (RT_SUCCESS(rc))
    2500                     rtlogFlush(pLogger, false /*fNeedSpace*/);
     2711                    rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
    25012712            }
    25022713# endif
    25032714            RT_NOREF(pErrInfo); /** @todo fix create API to use RTErrInfo */
    25042715        }
    2505         rtlogUnlock(pLogger);
     2716        rtlogUnlock(pLoggerInt);
    25062717    }
    25072718    return VINF_SUCCESS;
    25082719}
    25092720RT_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 */
     2735RTDECL(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}
     2762RT_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 */
     2771RTDECL(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}
     2782RT_EXPORT_SYMBOL(RTLogGetDestinations);
    25102783
    25112784
     
    25212794RTDECL(int) RTLogQueryDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
    25222795{
    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;
    25272801
    25282802    AssertReturn(cchBuf, VERR_INVALID_PARAMETER);
     
    25322806     * Resolve defaults.
    25332807     */
    2534     if (!pLogger)
    2535     {
    2536         pLogger = RTLogDefaultInstance();
    2537         if (!pLogger)
     2808    if (!pLoggerInt)
     2809    {
     2810        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2811        if (!pLoggerInt)
    25382812            return VINF_SUCCESS;
    25392813    }
     
    25422816     * Add the flags in the list.
    25432817     */
    2544     fDestFlags = pLogger->fDestFlags;
     2818    fDestFlags = pLoggerInt->fDestFlags;
    25452819    for (i = 6; i < RT_ELEMENTS(g_aLogDst); i++)
    25462820        if (g_aLogDst[i].fFlag & fDestFlags)
     
    25692843        if (RT_FAILURE(rc))
    25702844            return rc;
    2571         rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pInt->szFilename);
     2845        rc = RTStrCopyP(&pszBuf, &cchBuf, pLoggerInt->szFilename);
    25722846        if (RT_FAILURE(rc))
    25732847            return rc;
    25742848        fNotFirst = true;
    25752849
    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);
    25792853            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    25802854            if (RT_FAILURE(rc))
     
    25822856            fNotFirst = true;
    25832857        }
    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);
    25872861            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    25882862            if (RT_FAILURE(rc))
     
    25902864            fNotFirst = true;
    25912865        }
    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);
    25952869            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    25962870            if (RT_FAILURE(rc))
     
    26062880    if (fDestFlags & RTLOGDEST_RINGBUF)
    26072881    {
    2608         if (pLogger->pInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE)
     2882        if (pLoggerInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE)
    26092883            rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " ringbuf" : "ringbuf");
    26102884        else
    26112885        {
    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);
    26132887            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    26142888        }
     
    26222896RT_EXPORT_SYMBOL(RTLogQueryDestinations);
    26232897
     2898
     2899/**
     2900 * Helper for calculating the CRC32 of all the group names.
     2901 */
     2902static 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 */
     2930RTDECL(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}
     2965RT_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 */
     2985RTDECL(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}
     3020RT_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 */
     3035RTDECL(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}
     3097RT_EXPORT_SYMBOL(RTLogBulkWrite);
     3098
    26243099#endif /* !IN_RC */
    26253100
     
    26363111     * Resolve defaults.
    26373112     */
    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)
    26463118            return;
    26473119    }
     3120    Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC);
     3121    AssertPtr(pLoggerInt->pBufDesc);
     3122    Assert(pLoggerInt->pBufDesc->u32Magic == RTLOGBUFFERDESC_MAGIC);
    26483123
    26493124    /*
    26503125     * Any thing to flush?
    26513126     */
    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    {
    26593130        /*
    26603131         * Acquire logger instance sem.
    26613132         */
    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        }
    26853154    }
    26863155}
     
    27283197
    27293198
     3199/**
     3200 * Worker for RTLogDefaultInstanceEx, RTLogGetDefaultInstanceEx,
     3201 * RTLogRelGetDefaultInstanceEx and RTLogCheckGroupFlags.
     3202 */
     3203DECL_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
    27303220RTDECL(PRTLOGGER)   RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup)
    27313221{
    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;
    27483227}
    27493228RT_EXPORT_SYMBOL(RTLogDefaultInstanceEx);
     
    27863265RTDECL(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
    27873266{
    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;
    28043272}
    28053273RT_EXPORT_SYMBOL(RTLogGetDefaultInstanceEx);
     
    29083376
    29093377
     3378RTDECL(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}
     3386RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstance);
     3387
     3388
     3389RTDECL(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}
     3400RT_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 */
     3410RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger)
     3411{
     3412    return ASMAtomicXchgPtrT(&g_pRelLogger, pLogger, PRTLOGGER);
     3413}
     3414RT_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 */
     3429RTDECL(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}
     3436RT_EXPORT_SYMBOL(RTLogCheckGroupFlags);
     3437
     3438
    29103439/**
    29113440 * Write to a logger instance.
     
    29383467RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
    29393468{
    2940     int rc;
     3469    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     3470    int               rc;
    29413471
    29423472    /*
    29433473     * A NULL logger means default instance.
    29443474     */
    2945     if (!pLogger)
    2946     {
    2947         pLogger = RTLogDefaultInstance();
    2948         if (!pLogger)
     3475    if (!pLoggerInt)
     3476    {
     3477        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     3478        if (!pLoggerInt)
    29493479            return;
    29503480    }
     
    29533483     * Validate and correct iGroup.
    29543484     */
    2955     if (iGroup != ~0U && iGroup >= pLogger->cGroups)
     3485    if (iGroup != ~0U && iGroup >= pLoggerInt->cGroups)
    29563486        iGroup = 0;
    29573487
     
    29593489     * If no output, then just skip it.
    29603490     */
    2961     if (    (pLogger->fFlags & RTLOGFLAGS_DISABLED)
     3491    if (    (pLoggerInt->fFlags & RTLOGFLAGS_DISABLED)
    29623492#ifndef IN_RC
    2963         || !pLogger->fDestFlags
     3493        || !pLoggerInt->fDestFlags
    29643494#endif
    29653495        || !pszFormat || !*pszFormat)
    29663496        return;
    29673497    if (    iGroup != ~0U
    2968         &&  (pLogger->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
     3498        &&  (pLoggerInt->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
    29693499        return;
    29703500
     
    29723502     * Acquire logger instance sem.
    29733503     */
    2974     rc = rtlogLock(pLogger);
     3504    rc = rtlogLock(pLoggerInt);
    29753505    if (RT_FAILURE(rc))
    29763506    {
    29773507#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);
    29803510#endif
    29813511        return;
     
    29863516     */
    29873517#ifndef IN_RC
    2988     if (RT_UNLIKELY(   (pLogger->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
    2989                     && iGroup < pLogger->cGroups
    2990                     && (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;
    29963526        else
    29973527        {
    2998             rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
    2999             if (   pLogger->pInt->papszGroups
    3000                 && 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);
    30033533            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);
    30063535        }
    30073536    }
    30083537    else
    30093538#endif
    3010         rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
     3539        rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, args);
    30113540
    30123541    /*
    30133542     * Release the semaphore.
    30143543     */
    3015     rtlogUnlock(pLogger);
     3544    rtlogUnlock(pLoggerInt);
    30163545}
    30173546RT_EXPORT_SYMBOL(RTLogLoggerExV);
     
    32113740 * Opens/creates the log file.
    32123741 *
    3213  * @param   pLogger         The logger instance to update. NULL is not allowed!
     3742 * @param   pLoggerInt      The logger instance to update. NULL is not allowed!
    32143743 * @param   pErrInfo        Where to return extended error information.
    32153744 *                          Optional.
    32163745 */
    3217 static int rtlogFileOpen(PRTLOGGER pLogger, PRTERRINFO pErrInfo)
     3746static int rtlogFileOpen(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo)
    32183747{
    32193748    uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_NONE;
    3220     if (pLogger->fFlags & RTLOGFLAGS_APPEND)
     3749    if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND)
    32213750        fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND;
    32223751    else
    32233752    {
    3224         RTFileDelete(pLogger->pInt->szFilename);
     3753        RTFileDelete(pLoggerInt->szFilename);
    32253754        fOpen |= RTFILE_O_CREATE;
    32263755    }
    3227     if (pLogger->fFlags & RTLOGFLAGS_WRITE_THROUGH)
     3756    if (pLoggerInt->fFlags & RTLOGFLAGS_WRITE_THROUGH)
    32283757        fOpen |= RTFILE_O_WRITE_THROUGH;
    3229     if (pLogger->fDestFlags & RTLOGDEST_F_NO_DENY)
     3758    if (pLoggerInt->fDestFlags & RTLOGDEST_F_NO_DENY)
    32303759        fOpen = (fOpen & ~RTFILE_O_DENY_NONE) | RTFILE_O_DENY_NOT_DELETE;
    32313760
    32323761    unsigned cBackoff = 0;
    3233     int rc = RTFileOpen(&pLogger->pInt->hFile, pLogger->pInt->szFilename, fOpen);
     3762    int rc = RTFileOpen(&pLoggerInt->hFile, pLoggerInt->szFilename, fOpen);
    32343763    while (   (   rc == VERR_SHARING_VIOLATION
    3235                || (rc == VERR_ALREADY_EXISTS && !(pLogger->fFlags & RTLOGFLAGS_APPEND)))
     3764               || (rc == VERR_ALREADY_EXISTS && !(pLoggerInt->fFlags & RTLOGFLAGS_APPEND)))
    32363765           && cBackoff < RT_ELEMENTS(g_acMsLogBackoff))
    32373766    {
    32383767        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);
    32423771    }
    32433772    if (RT_SUCCESS(rc))
    32443773    {
    3245         rc = RTFileQuerySize(pLogger->pInt->hFile, &pLogger->pInt->cbHistoryFileWritten);
     3774        rc = RTFileQuerySize(pLoggerInt->hFile, &pLoggerInt->cbHistoryFileWritten);
    32463775        if (RT_FAILURE(rc))
    32473776        {
    32483777            /* Don't complain if this fails, assume the file is empty. */
    3249             pLogger->pInt->cbHistoryFileWritten = 0;
     3778            pLoggerInt->cbHistoryFileWritten = 0;
    32503779            rc = VINF_SUCCESS;
    32513780        }
     
    32533782    else
    32543783    {
    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);
    32573786    }
    32583787    return rc;
     
    32653794 * Used by the rtlogFlush() function as well as RTLogCreateExV.
    32663795 *
    3267  * @param   pLogger     The logger instance to update. NULL is not allowed!
     3796 * @param   pLoggerInt  The logger instance to update. NULL is not allowed!
    32683797 * @param   uTimeSlot   Current time slot (for tikme based rotation).
    32693798 * @param   fFirst      Flag whether this is the beginning of logging, i.e.
     
    32723801 * @param   pErrInfo    Where to return extended error information. Optional.
    32733802 */
    3274 static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst, PRTERRINFO pErrInfo)
     3803static void rtlogRotate(PRTLOGGERINTERNAL pLoggerInt, uint32_t uTimeSlot, bool fFirst, PRTERRINFO pErrInfo)
    32753804{
    32763805    /* 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;
    32793808
    32803809    /* Check rotation condition: file still small enough and not too old? */
    3281     if (RT_LIKELY(   pLogger->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax
    3282                   && uTimeSlot == pLogger->pInt->uHistoryTimeSlotStart))
     3810    if (RT_LIKELY(   pLoggerInt->cbHistoryFileWritten < pLoggerInt->cbHistoryFileMax
     3811                  && uTimeSlot == pLoggerInt->uHistoryTimeSlotStart))
    32833812        return;
    32843813
     
    32883817     * rotation would cause severe trouble otherwise.
    32893818     */
    3290     uint32_t const fSavedFlags = pLogger->fFlags;
    3291     pLogger->fFlags |= RTLOGFLAGS_DISABLED;
     3819    uint32_t const fSavedFlags = pLoggerInt->fFlags;
     3820    pLoggerInt->fFlags |= RTLOGFLAGS_DISABLED;
    32923821
    32933822    /*
     
    32953824     * chatty phase logging we could run into endless rotation.
    32963825     */
    3297     uint32_t const cSavedHistory = pLogger->pInt->cHistory;
    3298     pLogger->pInt->cHistory = 0;
     3826    uint32_t const cSavedHistory = pLoggerInt->cHistory;
     3827    pLoggerInt->cHistory = 0;
    32993828
    33003829    /*
    33013830     * Close the old log file.
    33023831     */
    3303     if (pLogger->pInt->hFile != NIL_RTFILE)
     3832    if (pLoggerInt->hFile != NIL_RTFILE)
    33043833    {
    33053834        /* Use the callback to generate some final log contents, but only if
    33063835         * this is a rotation with a fully set up logger. Leave the other case
    33073836         * 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;
    33173846    }
    33183847
     
    33243853        for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--)
    33253854        {
    3326             char szOldName[sizeof(pLogger->pInt->szFilename) + 32];
     3855            char szOldName[sizeof(pLoggerInt->szFilename) + 32];
    33273856            if (i > 0)
    3328                 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pInt->szFilename, i);
     3857                RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLoggerInt->szFilename, i);
    33293858            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);
    33343863
    33353864            unsigned cBackoff = 0;
     
    33513880        for (uint32_t i = cSavedHistory + 1; ; i++)
    33523881        {
    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);
    33553884            int rc = RTFileDelete(szExcessName);
    33563885            if (RT_FAILURE(rc))
     
    33623891     * Update logger state and create new log file.
    33633892     */
    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);
    33673896
    33683897    /*
     
    33713900     * RTLogCreateExV function.
    33723901     */
    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;
    33793908    }
    33803909
    33813910    /* Restore saved values. */
    3382     pLogger->pInt->cHistory = cSavedHistory;
    3383     pLogger->fFlags         = fSavedFlags;
     3911    pLoggerInt->cHistory = cSavedHistory;
     3912    pLoggerInt->fFlags   = fSavedFlags;
    33843913}
    33853914
     
    33913920 *
    33923921 * @returns IPRT status code.
    3393  * @param   pLogger             The logger.
     3922 * @param   pLoggerInt          The logger.
    33943923 * @param   pErrInfo            Where to return extended error information.
    33953924 *                              Optional.
    33963925 */
    3397 static int rtR3LogOpenFileDestination(PRTLOGGER pLogger, PRTERRINFO pErrInfo)
     3926static int rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo)
    33983927{
    33993928    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);
    34033932
    34043933        /* Rotate in case of appending to a too big log file,
    34053934           otherwise this simply doesn't do anything. */
    3406         rtlogRotate(pLogger, 0, true /* fFirst */, pErrInfo);
     3935        rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo);
    34073936    }
    34083937    else
    34093938    {
    34103939        /* 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);
    34133942
    34143943        /* 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);
    34193948        }
    34203949        else
     
    34333962 * Used by the RTLogFlush() function.
    34343963 *
    3435  * @param   pLogger     The logger instance to write to. NULL is not allowed!
     3964 * @param   pLoggerInt  The logger instance to write to. NULL is not allowed!
    34363965 * @param   fNeedSpace  Set if the caller assumes space will be made available.
    34373966 */
    3438 static void rtlogFlush(PRTLOGGER pLogger, bool fNeedSpace)
    3439 {
    3440     uint32_t const cchScratch = pLogger->offScratch;
    3441     if (cchScratch == 0)
     3967static 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)
    34423977        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
    34463983    /*
    34473984     * If the ring buffer is active, the other destinations are only written
    34483985     * to when the ring buffer is flushed by RTLogFlush().
    34493986     */
    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';
    34563995    }
    34573996    /*
     
    34603999     */
    34614000    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))
    34654003#endif
    34664004    {
    34674005        /* Make sure the string is terminated.  On Windows, RTLogWriteDebugger
    34684006           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)
    34854019            {
    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);
    34894023            }
    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        }
    35134027#endif
    35144028
     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
    35154050        /* empty the buffer. */
    3516         pLogger->offScratch = 0;
     4051        pBufDesc->offBuf = 0;
     4052        if (pBufDesc->pAux)
     4053            pBufDesc->pAux->offBuf = 0;
     4054        *pchToFlush      = '\0';
    35174055
    35184056#ifdef IN_RING3
     
    35224060         * and footer messages.
    35234061         */
    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*/);
    35274065#endif
    35284066    }
     
    35344072         * buffer and insert a message indicating that we've dropped output.
    35354073         */
    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;
    35494090        }
    35504091    }
     
    35594100static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
    35604101{
    3561     PRTLOGGER pLogger = (PRTLOGGER)pv;
     4102    PRTLOGGERINTERNAL pLoggerInt  = (PRTLOGGERINTERNAL)pv;
    35624103    if (cbChars)
    35634104    {
     
    35654106        for (;;)
    35664107        {
    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)
    35704110            {
    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);
    35734166                AssertBreakpoint(); AssertBreakpoint();
    35744167            }
    35754168#endif
    35764169
    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 
    35964170            /* flush */
    3597             rtlogFlush(pLogger, true /*fNeedSpace*/);
     4171            rtlogFlush(pLoggerInt, true /*fNeedSpace*/);
    35984172        }
    35994173
     
    36064180         * There's always space for a terminator, and it's not counted.
    36074181         */
    3608         pLogger->achScratch[pLogger->offScratch] = '\0';
     4182        PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc;
     4183        pBufDesc->pchBuf[RT_MIN(pBufDesc->offBuf, pBufDesc->cbBuf - 1)] = '\0';
    36094184        return 0;
    36104185    }
     
    36784253static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars)
    36794254{
    3680     PRTLOGOUTPUTPREFIXEDARGS    pArgs = (PRTLOGOUTPUTPREFIXEDARGS)pv;
    3681     PRTLOGGER                   pLogger = pArgs->pLogger;
     4255    PRTLOGOUTPUTPREFIXEDARGS    pArgs      = (PRTLOGOUTPUTPREFIXEDARGS)pv;
     4256    PRTLOGGERINTERNAL           pLoggerInt = pArgs->pLoggerInt;
    36824257    if (cbChars)
    36834258    {
     
    36854260        for (;;)
    36864261        {
    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            }
    36954279#endif
    36964280
     
    36984282             * Pending prefix?
    36994283             */
    3700             if (*pfPendingPrefix)
     4284            if (pLoggerInt->fPendingPrefix)
    37014285            {
    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 #endif
    3713 
    37144286                /*
    37154287                 * Flush the buffer if there isn't enough room for the maximum prefix config.
    37164288                 * Max is 256, add a couple of extra bytes.  See CCH_PREFIX check way below.
    37174289                 */
    3718                 if (cb < 256 + 16)
     4290                if (cb >= 256 + 16)
     4291                    pLoggerInt->fPendingPrefix = false;
     4292                else
    37194293                {
    3720                     rtlogFlush(pLogger, true /*fNeedSpace*/);
    3721                     offScratch = pLogger->offScratch;
    3722                     cb = sizeof(pLogger->achScratch) - offScratch - 1;
     4294                    rtlogFlush(pLoggerInt, true /*fNeedSpace*/);
     4295                    continue;
    37234296                }
    37244297
     
    37274300                 * psz is pointing to the current position.
    37284301                 */
    3729                 psz = &pLogger->achScratch[offScratch];
    3730                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TS)
     4302                psz = &pchBuf[offBuf];
     4303                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TS)
    37314304                {
    37324305                    uint64_t     u64    = RTTimeNanoTS();
    37334306                    int          iBase  = 16;
    37344307                    unsigned int fFlags = RTSTR_F_ZEROPAD;
    3735                     if (pLogger->fFlags & RTLOGFLAGS_DECIMAL_TS)
     4308                    if (pLoggerInt->fFlags & RTLOGFLAGS_DECIMAL_TS)
    37364309                    {
    37374310                        iBase = 10;
    37384311                        fFlags = 0;
    37394312                    }
    3740                     if (pLogger->fFlags & RTLOGFLAGS_REL_TS)
     4313                    if (pLoggerInt->fFlags & RTLOGFLAGS_REL_TS)
    37414314                    {
    37424315                        static volatile uint64_t s_u64LastTs;
     
    37544327#define CCH_PREFIX_01   0 + 17
    37554328
    3756                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TSC)
     4329                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TSC)
    37574330                {
    37584331#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     
    37634336                    int          iBase  = 16;
    37644337                    unsigned int fFlags = RTSTR_F_ZEROPAD;
    3765                     if (pLogger->fFlags & RTLOGFLAGS_DECIMAL_TS)
     4338                    if (pLoggerInt->fFlags & RTLOGFLAGS_DECIMAL_TS)
    37664339                    {
    37674340                        iBase = 10;
    37684341                        fFlags = 0;
    37694342                    }
    3770                     if (pLogger->fFlags & RTLOGFLAGS_REL_TS)
     4343                    if (pLoggerInt->fFlags & RTLOGFLAGS_REL_TS)
    37714344                    {
    37724345                        static volatile uint64_t s_u64LastTsc;
     
    37844357#define CCH_PREFIX_02   CCH_PREFIX_01 + 17
    37854358
    3786                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_MS_PROG)
     4359                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_MS_PROG)
    37874360                {
    37884361#if defined(IN_RING3) || defined(IN_RC)
    37894362                    uint64_t u64 = RTTimeProgramMilliTS();
    37904363#else
    3791                     uint64_t u64 = (RTTimeNanoTS() - pLogger->pInt->nsR0ProgramStart) / RT_NS_1MS;
     4364                    uint64_t u64 = (RTTimeNanoTS() - pLoggerInt->nsR0ProgramStart) / RT_NS_1MS;
    37924365#endif
    37934366                    /* 1E8 milliseconds = 27 hours */
     
    37974370#define CCH_PREFIX_03   CCH_PREFIX_02 + 21
    37984371
    3799                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TIME)
     4372                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TIME)
    38004373                {
    38014374#if defined(IN_RING3) || defined(IN_RING0)
     
    38184391#define CCH_PREFIX_04   CCH_PREFIX_03 + (3+1+3+1+3+1+7+1)
    38194392
    3820                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG)
     4393                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG)
    38214394                {
    38224395
     
    38244397                    uint64_t u64 = RTTimeProgramMicroTS();
    38254398#else
    3826                     uint64_t u64 = (RTTimeNanoTS() - pLogger->pInt->nsR0ProgramStart) / RT_NS_1US;
     4399                    uint64_t u64 = (RTTimeNanoTS() - pLoggerInt->nsR0ProgramStart) / RT_NS_1US;
    38274400
    38284401#endif
     
    38424415
    38434416# if 0
    3844                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_DATETIME)
     4417                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_DATETIME)
    38454418                {
    38464419                    char szDate[32];
     
    38574430# endif
    38584431
    3859                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_PID)
     4432                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_PID)
    38604433                {
    38614434#ifndef IN_RC
     
    38694442#define CCH_PREFIX_07   CCH_PREFIX_06 + 9
    38704443
    3871                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TID)
     4444                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TID)
    38724445                {
    38734446#ifndef IN_RC
     
    38814454#define CCH_PREFIX_08   CCH_PREFIX_07 + 17
    38824455
    3883                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_THREAD)
     4456                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_THREAD)
    38844457                {
    38854458#ifdef IN_RING3
     
    38884461                    const char *pszName = "EMT-RC";
    38894462#else
    3890                     const char *pszName = pLogger->pInt->szR0ThreadName[0] ? pLogger->pInt->szR0ThreadName : "R0";
     4463                    const char *pszName = pLoggerInt->szR0ThreadName[0] ? pLoggerInt->szR0ThreadName : "R0";
    38914464#endif
    38924465                    psz = rtLogStPNCpyPad(psz, pszName, 16, 8);
     
    38944467#define CCH_PREFIX_09   CCH_PREFIX_08 + 17
    38954468
    3896                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_CPUID)
     4469                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_CPUID)
    38974470                {
    38984471#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     
    39074480
    39084481#ifndef IN_RC
    3909                 if (    (pLogger->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
    3910                     &&  pLogger->pInt->pfnPrefix)
     4482                if (    (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
     4483                    &&  pLoggerInt->pfnPrefix)
    39114484                {
    3912                     psz += pLogger->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg);
     4485                    psz += pLoggerInt->pfnPrefix(&pLoggerInt->Core, psz, 31, pLoggerInt->pvPrefixUserArg);
    39134486                    *psz++ = ' ';                                                               /* +32 */
    39144487                }
     
    39164489#define CCH_PREFIX_11   CCH_PREFIX_10 + 32
    39174490
    3918                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS)
     4491                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS)
    39194492                {
    39204493#ifdef IN_RING3 /** @todo implement these counters in ring-0 too? */
     
    39414514#define CCH_PREFIX_12   CCH_PREFIX_11 + 8
    39424515
    3943                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO)
     4516                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO)
    39444517                {
    39454518                    psz += RTStrFormatNumber(psz, pArgs->fFlags, 16, 8, 0, RTSTR_F_ZEROPAD);
     
    39484521#define CCH_PREFIX_13   CCH_PREFIX_12 + 9
    39494522
    3950                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG)
     4523                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_FLAG)
    39514524                {
    39524525#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;
    39544527#else
    39554528                    const char *pszGroup = NULL;
     
    39594532#define CCH_PREFIX_14   CCH_PREFIX_13 + 17
    39604533
    3961                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO)
     4534                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO)
    39624535                {
    39634536                    if (pArgs->iGroup != ~0U)
     
    39744547#define CCH_PREFIX_15   CCH_PREFIX_14 + 9
    39754548
    3976                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_GROUP)
     4549                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_GROUP)
    39774550                {
    3978                     const unsigned fGrp = pLogger->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0];
     4551                    const unsigned fGrp = pLoggerInt->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0];
    39794552                    const char *pszGroup;
    39804553                    size_t cchGroup;
     
    40094582                 * Done, figure what we've used and advance the buffer and free size.
    40104583                 */
    4011                 cb = psz - &pLogger->achScratch[offScratch];
    4012                 AssertMsg(cb <= 223, ("%#zx (%zd) - fFlags=%#x\n", cb, cb, pLogger->fFlags));
    4013                 pLogger->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;
    40154588            }
    40164589            else if (cb <= 0)
    40174590            {
    4018                 rtlogFlush(pLogger, true /*fNeedSpace*/);
    4019                 offScratch = pLogger->offScratch;
    4020                 cb = sizeof(pLogger->achScratch) - offScratch - 1;
     4591                rtlogFlush(pLoggerInt, true /*fNeedSpace*/);
     4592                continue;
    40214593            }
    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 #endif
    40324594
    40334595            /* how much */
     
    40394601            if (pszNewLine)
    40404602            {
    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                {
    40424611                    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                }
    40434620                else
    40444621                {
    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);
    40474625                }
    40484626            }
    4049 
    4050             /* copy */
    4051             memcpy(&pLogger->achScratch[offScratch], pachChars, cb);
     4627            else
     4628                memcpy(&pchBuf[offBuf], pachChars, cb);
    40524629
    40534630            /* advance */
    4054             pLogger->offScratch = offScratch += (uint32_t)cb;
    4055             cbRet += cb;
     4631            pBufDesc->offBuf = offBuf += (uint32_t)cb;
     4632            cbRet   += cb;
    40564633            cbChars -= cb;
    4057 
    4058             if (    pszNewLine
    4059                 &&  (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             }
    40694634
    40704635            /* done? */
     
    40824647         * There's always space for a terminator, and it's not counted.
    40834648         */
    4084         pLogger->achScratch[pLogger->offScratch] = '\0';
     4649        PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc;
     4650        pBufDesc->pchBuf[RT_MIN(pBufDesc->offBuf, pBufDesc->cbBuf - 1)] = '\0';
    40854651        return 0;
    40864652    }
     
    40944660 * logging kind which is currently enabled before writing anything to the log.
    40954661 *
    4096  * @param   pLogger     Pointer to logger instance. Must be non-NULL.
     4662 * @param   pLoggerInt  Pointer to logger instance. Must be non-NULL.
    40974663 * @param   fFlags      The logging flags.
    40984664 * @param   iGroup      The group.
     
    41024668 * @param   args        Format arguments.
    41034669 */
    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))
     4670static 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))
    41104690    {
    41114691        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;
    41154695        RTLogFormatV(rtLogOutputPrefixed, &OutputArgs, pszFormat, args);
    41164696    }
    41174697    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    }
    41224713}
    41234714
     
    41274718 * For calling rtlogLoggerExVLocked.
    41284719 *
    4129  * @param   pLogger     The logger.
     4720 * @param   pLoggerInt  The logger.
    41304721 * @param   fFlags      The logging flags.
    41314722 * @param   iGroup      The group.
     
    41354726 * @param   ...         Format arguments.
    41364727 */
    4137 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
     4728static void rtlogLoggerExFLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
    41384729{
    41394730    va_list va;
    41404731    va_start(va, pszFormat);
    4141     rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, va);
     4732    rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, va);
    41424733    va_end(va);
    41434734}
  • trunk/src/VBox/Runtime/common/log/logrel.cpp

    r82968 r90829  
    5656# include <stdio.h>
    5757#endif
    58 
    59 
    60 /*********************************************************************************************************************************
    61 *   Global Variables                                                                                                             *
    62 *********************************************************************************************************************************/
    63 #ifdef IN_RC
    64 /** 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_RC
    75     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_RC
    86     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         else
    95         {
    96             uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);
    97             uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
    98             if (   iGroup != UINT16_MAX
    99                  && (   (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_RC
    110 /**
    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 */
    12258
    12359
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette