Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108//// getstream.cpp//// Copyright (c) Microsoft Corporation. All rights reserved.//// Defines _getstream(), which finds and locks a stream that is available for use.//#include <corecrt_internal_stdio.h>
static __crt_stdio_stream __cdecl find_or_allocate_unused_stream_nolock() throw(){ __crt_stdio_stream_data** const first_stream = __piob + _IOB_ENTRIES; __crt_stdio_stream_data** const last_stream = first_stream + _nstream - _IOB_ENTRIES;
for (__crt_stdio_stream_data** it = first_stream; it != last_stream; ++it) { // First, check to see whether the stream is valid and free for use: { __crt_stdio_stream stream(*it); if (stream.valid()) { if (stream.is_in_use()) continue;
stream.lock(); if (!stream.try_allocate()) { stream.unlock(); continue; }
return stream; } }
// Otherwise, there is no stream at this index yet, so we allocate one // and return it: { *it = _calloc_crt_t(__crt_stdio_stream_data, 1).detach(); if (*it == nullptr) break;
// Initialize the stream. Everything requires zero-initialization // (which we get from calloc), except the file handle and the lock: (*it)->_file = -1; __acrt_InitializeCriticalSectionEx(&(*it)->_lock, _CORECRT_SPINCOUNT, 0);
__crt_stdio_stream stream(*it);
// Note: This attempt will always succeed, because we hold the only // pointer to the stream object (since we just allocated it): stream.try_allocate(); stream.lock();
return stream; } }
return __crt_stdio_stream();}
// Finds a stream not in use and makes it available to the caller. It is// intended for internal use inside the library only. It returns a pointer to// a free stream, or nullptr if all are in use. A stream becomes allocated// only if the caller decides to use it by setting a mode (r, w, or r/w). The// stream is returned locked; the caller is responsible for unlocking the stream.__crt_stdio_stream __cdecl __acrt_stdio_allocate_stream() throw(){ __crt_stdio_stream stream;
__acrt_lock(__acrt_stdio_index_lock); __try { stream = find_or_allocate_unused_stream_nolock(); if (!stream.valid()) __leave;
stream->_cnt = 0; stream->_tmpfname = nullptr; stream->_ptr = nullptr; stream->_base = nullptr; stream->_file = -1; } __finally { __acrt_unlock(__acrt_stdio_index_lock); } __endtry
return stream;}
void __cdecl __acrt_stdio_free_stream(__crt_stdio_stream stream) throw(){ stream->_ptr = nullptr; stream->_base = nullptr; stream->_cnt = 0; stream->_file = -1; stream->_charbuf = 0; stream->_bufsiz = 0; stream->_tmpfname = nullptr; stream.deallocate();}