mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 19:33:23 +00:00
[UCRT] Import Microsoft.Windows.SDK.CRTSource version 10.0.22621.3
Imported from https://www.nuget.org/packages/Microsoft.Windows.SDK.CRTSource/10.0.22621.3 License: MIT
This commit is contained in:
parent
f1b60c66f0
commit
04e0dc4a7a
568 changed files with 115483 additions and 0 deletions
106
sdk/lib/ucrt/stdio/stream.cpp
Normal file
106
sdk/lib/ucrt/stdio/stream.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue