Changeset 25510 in vbox
- Timestamp:
- Dec 19, 2009 10:19:30 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56183
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r25494 r25510 556 556 generic/RTUuidCreate-generic.cpp \ 557 557 generic/mppresent-generic.cpp \ 558 generic/semrw-generic.cpp \ 558 559 generic/timer-generic.cpp \ 559 560 generic/utf16locale-generic.cpp \ … … 579 580 r3/posix/semeventmulti-posix.cpp \ 580 581 r3/posix/semmutex-posix.cpp \ 581 r3/posix/semrw-posix.cpp \582 582 r3/posix/thread-posix.cpp \ 583 583 r3/posix/timelocal-posix.cpp \ -
trunk/src/VBox/Runtime/r3/stream.cpp
r21045 r25510 35 35 *******************************************************************************/ 36 36 #include <iprt/stream.h> 37 #include "internal/iprt.h" 38 39 #include <iprt/asm.h> 40 #include <iprt/critsect.h> 37 41 #include <iprt/string.h> 38 #include <iprt/asm.h>39 42 #include <iprt/assert.h> 40 43 #include <iprt/alloc.h> … … 67 70 int32_t volatile i32Error; 68 71 /** 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 70 77 } RTSTREAM; 71 78 … … 80 87 0, 81 88 stdin 89 #ifndef HAVE_FWRITE_UNLOCKED 90 , NULL 91 #endif 82 92 }; 83 93 … … 88 98 0, 89 99 stderr 100 #ifndef HAVE_FWRITE_UNLOCKED 101 , NULL 102 #endif 90 103 }; 91 104 … … 96 109 0, 97 110 stdout 111 #ifndef HAVE_FWRITE_UNLOCKED 112 , NULL 113 #endif 98 114 }; 99 115 … … 106 122 /** Pointer to the standard output stream. */ 107 123 RTDATADECL(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 */ 133 static 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 */ 173 DECLINLINE(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 */ 191 DECLINLINE(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 } 108 200 109 201 … … 252 344 pStream->u32Magic = 0xdeaddead; 253 345 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 254 356 RTMemFree(pStream); 255 357 return VINF_SUCCESS; 256 358 } 359 257 360 return RTErrConvertFromErrno(errno); 258 361 } … … 543 646 { 544 647 cchString--; /* save space for the terminator. */ 545 #ifdef HAVE_FWRITE_UNLOCKED 546 flockfile(pStream->pFile); 547 #endif 648 rtStrmLock(pStream); 548 649 for (;;) 549 650 { 550 #ifdef HAVE_FWRITE_UNLOCKED 651 #ifdef HAVE_FWRITE_UNLOCKED /** @todo darwin + freebsd(?) has fgetc_unlocked but not fwrite_unlocked, optimize... */ 551 652 int ch = fgetc_unlocked(pStream->pFile); 552 653 #else … … 586 687 } 587 688 } 588 #ifdef HAVE_FWRITE_UNLOCKED 589 funlockfile(pStream->pFile); 590 #endif 689 rtStrmUnlock(pStream); 591 690 592 691 *pszString = '\0'; … … 671 770 if (RT_SUCCESS(rc)) 672 771 { 673 /** @todo consider making this thread safe... */ 674 #ifdef HAVE_FWRITE_UNLOCKED 675 flockfile(pStream->pFile); 772 rtStrmLock(pStream); 676 773 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); 681 775 Assert(rc >= 0); 682 776 }
Note:
See TracChangeset
for help on using the changeset viewer.