VirtualBox

Changeset 25510 in vbox


Ignore:
Timestamp:
Dec 19, 2009 10:19:30 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56183
Message:

r3/stream.cpp: serialize RTStrmPrintf on all platforms, not just the one with fwrite_unlocked.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r25494 r25510  
    556556        generic/RTUuidCreate-generic.cpp \
    557557        generic/mppresent-generic.cpp \
     558        generic/semrw-generic.cpp \
    558559        generic/timer-generic.cpp \
    559560        generic/utf16locale-generic.cpp \
     
    579580        r3/posix/semeventmulti-posix.cpp \
    580581        r3/posix/semmutex-posix.cpp \
    581         r3/posix/semrw-posix.cpp \
    582582        r3/posix/thread-posix.cpp \
    583583        r3/posix/timelocal-posix.cpp \
  • trunk/src/VBox/Runtime/r3/stream.cpp

    r21045 r25510  
    3535*******************************************************************************/
    3636#include <iprt/stream.h>
     37#include "internal/iprt.h"
     38
     39#include <iprt/asm.h>
     40#include <iprt/critsect.h>
    3741#include <iprt/string.h>
    38 #include <iprt/asm.h>
    3942#include <iprt/assert.h>
    4043#include <iprt/alloc.h>
     
    6770    int32_t volatile    i32Error;
    6871    /** Pointer to the LIBC file stream. */
    69     FILE                *pFile;
     72    FILE               *pFile;
     73#ifndef HAVE_FWRITE_UNLOCKED
     74    /** Critical section for serializing access to the stream. */
     75    PRTCRITSECT         pCritSect;
     76#endif
    7077} RTSTREAM;
    7178
     
    8087    0,
    8188    stdin
     89#ifndef HAVE_FWRITE_UNLOCKED
     90    , NULL
     91#endif
    8292};
    8393
     
    8898    0,
    8999    stderr
     100#ifndef HAVE_FWRITE_UNLOCKED
     101    , NULL
     102#endif
    90103};
    91104
     
    96109    0,
    97110    stdout
     111#ifndef HAVE_FWRITE_UNLOCKED
     112    , NULL
     113#endif
    98114};
    99115
     
    106122/** Pointer to the standard output stream. */
    107123RTDATADECL(PRTSTREAM)   g_pStdOut = &g_StdOut;
     124
     125
     126#ifndef HAVE_FWRITE_UNLOCKED
     127/**
     128 * Allocates and acquires the lock for the stream.
     129 *
     130 * @returns IPRT status.
     131 * @param   pStream     The stream (valid).
     132 */
     133static int rtStrmAllocLock(PRTSTREAM pStream)
     134{
     135    Assert(pStream->pCritSect == NULL);
     136
     137    PRTCRITSECT pCritSect = (PRTCRITSECT)RTMemAlloc(sizeof(*pCritSect));
     138    if (!pCritSect)
     139        return VERR_NO_MEMORY;
     140    int rc = RTCritSectInit(pCritSect);
     141    if (RT_SUCCESS(rc))
     142    {
     143        /* The native stream lock are normally not recursive .*/
     144        pCritSect->fFlags |= RTCRITSECT_FLAGS_NO_NESTING;
     145
     146        rc = RTCritSectEnter(pCritSect);
     147        if (RT_SUCCESS(rc))
     148        {
     149            if (RT_LIKELY(ASMAtomicCmpXchgPtr((void * volatile *)&pStream->pCritSect, pCritSect, NULL)))
     150                return VINF_SUCCESS;
     151
     152            RTCritSectLeave(pCritSect);
     153        }
     154        RTCritSectDelete(pCritSect);
     155    }
     156    RTMemFree(pCritSect);
     157
     158    /* Handle the lost race case... */
     159    pCritSect = (PRTCRITSECT)ASMAtomicReadPtr((void * volatile *)&pStream->pCritSect);
     160    if (pCritSect)
     161        return RTCritSectEnter(pCritSect);
     162
     163    return rc;
     164}
     165#endif /* !HAVE_FWRITE_UNLOCKED */
     166
     167
     168/**
     169 * Locks the stream.  May have to allocate the lock as well.
     170 *
     171 * @param   pStream     The stream (valid).
     172 */
     173DECLINLINE(void) rtStrmLock(PRTSTREAM pStream)
     174{
     175#ifdef HAVE_FWRITE_UNLOCKED
     176    flockfile(pStream->pFile);
     177#else
     178    if (RT_LIKELY(pStream->pCritSect))
     179        RTCritSectEnter(pStream->pCritSect);
     180    else
     181        rtStrmAllocLock(pStream);
     182#endif
     183}
     184
     185
     186/**
     187 * Unlocks the stream.
     188 *
     189 * @param   pStream     The stream (valid).
     190 */
     191DECLINLINE(void) rtStrmUnlock(PRTSTREAM pStream)
     192{
     193#ifdef HAVE_FWRITE_UNLOCKED
     194    funlockfile(pStream->pFile);
     195#else
     196    if (RT_LIKELY(pStream->pCritSect))
     197        RTCritSectLeave(pStream->pCritSect);
     198#endif
     199}
    108200
    109201
     
    252344            pStream->u32Magic = 0xdeaddead;
    253345            pStream->pFile = NULL;
     346#ifndef HAVE_FWRITE_UNLOCKED
     347            if (pStream->pCritSect)
     348            {
     349                RTCritSectEnter(pStream->pCritSect);
     350                RTCritSectLeave(pStream->pCritSect);
     351                RTCritSectDelete(pStream->pCritSect);
     352                RTMemFree(pStream->pCritSect);
     353                pStream->pCritSect = NULL;
     354            }
     355#endif
    254356            RTMemFree(pStream);
    255357            return VINF_SUCCESS;
    256358        }
     359
    257360        return RTErrConvertFromErrno(errno);
    258361    }
     
    543646            {
    544647                cchString--;            /* save space for the terminator. */
    545 #ifdef HAVE_FWRITE_UNLOCKED
    546                 flockfile(pStream->pFile);
    547 #endif
     648                rtStrmLock(pStream);
    548649                for (;;)
    549650                {
    550 #ifdef HAVE_FWRITE_UNLOCKED
     651#ifdef HAVE_FWRITE_UNLOCKED /** @todo darwin + freebsd(?) has fgetc_unlocked but not fwrite_unlocked, optimize... */
    551652                    int ch = fgetc_unlocked(pStream->pFile);
    552653#else
     
    586687                    }
    587688                }
    588 #ifdef HAVE_FWRITE_UNLOCKED
    589                 funlockfile(pStream->pFile);
    590 #endif
     689                rtStrmUnlock(pStream);
    591690
    592691                *pszString = '\0';
     
    671770        if (RT_SUCCESS(rc))
    672771        {
    673             /** @todo consider making this thread safe... */
    674 #ifdef HAVE_FWRITE_UNLOCKED
    675             flockfile(pStream->pFile);
     772            rtStrmLock(pStream);
    676773            rc = (int)RTStrFormatV(rtstrmOutput, pStream, NULL, NULL, pszFormat, args);
    677             funlockfile(pStream->pFile);
    678 #else
    679             rc = (int)RTStrFormatV(rtstrmOutput, pStream, NULL, NULL, pszFormat, args);
    680 #endif
     774            rtStrmUnlock(pStream);
    681775            Assert(rc >= 0);
    682776        }
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