ReactOS 0.4.16-dev-853-g88d9285
stream.cpp
Go to the documentation of this file.
1//
2// getstream.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines _getstream(), which finds and locks a stream that is available for use.
7//
9
10
11
13{
14 __crt_stdio_stream_data** const first_stream = __piob + _IOB_ENTRIES;
15 __crt_stdio_stream_data** const last_stream = first_stream + _nstream - _IOB_ENTRIES;
16
17 for (__crt_stdio_stream_data** it = first_stream; it != last_stream; ++it)
18 {
19 // First, check to see whether the stream is valid and free for use:
20 {
22 if (stream.valid())
23 {
24 if (stream.is_in_use())
25 continue;
26
27 stream.lock();
28 if (!stream.try_allocate())
29 {
30 stream.unlock();
31 continue;
32 }
33
34 return stream;
35 }
36 }
37
38 // Otherwise, there is no stream at this index yet, so we allocate one
39 // and return it:
40 {
41 *it = _calloc_crt_t(__crt_stdio_stream_data, 1).detach();
42 if (*it == nullptr)
43 break;
44
45 // Initialize the stream. Everything requires zero-initialization
46 // (which we get from calloc), except the file handle and the lock:
47 (*it)->_file = -1;
49
51
52 // Note: This attempt will always succeed, because we hold the only
53 // pointer to the stream object (since we just allocated it):
54 stream.try_allocate();
55 stream.lock();
56
57 return stream;
58 }
59 }
60
61 return __crt_stdio_stream();
62}
63
64
65
66// Finds a stream not in use and makes it available to the caller. It is
67// intended for internal use inside the library only. It returns a pointer to
68// a free stream, or nullptr if all are in use. A stream becomes allocated
69// only if the caller decides to use it by setting a mode (r, w, or r/w). The
70// stream is returned locked; the caller is responsible for unlocking the stream.
72{
74
76 __try
77 {
79 if (!stream.valid())
80 __leave;
81
82 stream->_cnt = 0;
83 stream->_tmpfname = nullptr;
84 stream->_ptr = nullptr;
85 stream->_base = nullptr;
86 stream->_file = -1;
87 }
89 {
91 }
93
94 return stream;
95}
96
98{
99 stream->_ptr = nullptr;
100 stream->_base = nullptr;
101 stream->_cnt = 0;
102 stream->_file = -1;
103 stream->_charbuf = 0;
104 stream->_bufsiz = 0;
105 stream->_tmpfname = nullptr;
106 stream.deallocate();
107}
#define __cdecl
Definition: accygwin.h:79
void __cdecl __acrt_unlock(_In_ __acrt_lock_id lock)
Definition: locks.cpp:57
@ __acrt_stdio_index_lock
#define _CORECRT_SPINCOUNT
BOOL WINAPI __acrt_InitializeCriticalSectionEx(_Out_ LPCRITICAL_SECTION critical_section, _In_ DWORD spin_count, _In_ DWORD flags)
int _nstream
__crt_stdio_stream_data ** __piob
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const _In_ bool const _Inout_ __crt_cached_ptd_host &ptd throw()
Definition: cvt.cpp:119
__acrt_lock(__acrt_heap_lock)
#define _IOB_ENTRIES
Definition: stdio.h:23
#define __try
Definition: pseh2_64.h:172
#define __leave
Definition: pseh2_64.h:176
#define __endtry
Definition: pseh2_64.h:175
#define __finally
Definition: pseh2_64.h:174
void __cdecl __acrt_stdio_free_stream(__crt_stdio_stream stream)
Definition: stream.cpp:97
static __crt_stdio_stream __cdecl find_or_allocate_unused_stream_nolock()
Definition: stream.cpp:12
__crt_stdio_stream __cdecl __acrt_stdio_allocate_stream()
Definition: stream.cpp:71
Definition: parse.h:23