How to destroy _reent structure
Sebastian Huber
sebastian.huber@embedded-brains.de
Wed Apr 24 19:18:00 GMT 2013
On 24/04/13 20:51, Joel Sherrill wrote:
> On 4/24/2013 12:54 PM, Sebastian Huber wrote:
>> On 24/04/13 13:10, Sebastian Huber wrote:
>>> Hello Corinna,
>>>
>>> On 04/24/2013 12:26 PM, Corinna Vinschen wrote:
>>>> On Apr 24 10:04, Sebastian Huber wrote:
>>>>> Hello,
>>>>>
>>>>> there is _REENT_INIT_PTR() for initialization, but how can I destroy
>>>>> a _reent structure. Is this _wrapup_reent()?
>>>> Try _reclaim_reent. But it's not the same as _REENT_INIT_PTR since
>>>> _REENT_INIT_PTR does not allocate any memory.
>>>>
>>>>
>>>> Corinna
>>>>
>>> so for initialization we can use:
>>>
>>> struct _reent *p = malloc(sizeof(*p));
>>> if (p != NULL) {
>>> _REENT_INIT_PTR(p);
>>> }
>>>
>>> For destruction we can use:
>>>
>>> _reclaim_reent(p);
>>> free(p);
>> If I use this sequence in RTEMS, then I have the following problem.
>> RTEMS opens (via open()) the file descriptors 0, 1 and 2 during system
>> initialization. In RTEMS the file descriptors are a global resource. A
>> thread will do the initialization steps above during creation time. Now
>> suppose a thread calls fopen(). This will check that _REENT is
>> initialized. This will execute the following code for stdin, stdout and
>> stderr FILE streams (newlib/libc/stdio/findfp.c):
>>
>> [...]
>> static _VOID
>> _DEFUN(std, (ptr, flags, file, data),
>> FILE *ptr _AND
>> int flags _AND
>> int file _AND
>> struct _reent *data)
>> {
>> [...]
>> ptr->_file = file;
>> [...]
>> ptr->_close = __sclose;
>> [...]
>> }
>> [...]
>>
>> It simply assumes that file descriptors 0, 1 and 2 are available and
>> registers the __sclose() function (which will call close()). During
>> _reclaim_reent() the stdin, stdout and stderr FILE streams are closed.
>> Since we have no open() call for these file descriptors this will close
>> the global file descriptors 0, 1 and 2. I think at least for RTEMS we
>> should set ptr->_close to NULL.
> This goes back to the issue of whether the FILE * are per thread
> or per process. I know we have discussed this before and not resolved
> anything.
>
> As best I can tell from POSIX, open() integer descriptors are process
> wide. There is a set for the process.
>
> But I can't find a clear indication for "FILE *" from fopen().
> If they are per-process, then why are_stdin, _stdout, _stderr,
> and _sf in the reent structure?
>
> Should I be able to fopen() a file in one thread, exit that thread,
> and then be able to use the FILE * pointer in another thread?
>
> I am trying to back off and make sure I understand the C99
> and POSIX requirements.
I think this per-thread stdin, stdout and stderr is a feature of
Newlib. I wouldn't change it, but we have to fix the thread creation
and destruction issues in RTEMS related to that. I will provide patches
in the next couple of days.
Streams opened with fopen() are part of _GLOBAL_REENT and not associated
with a particular thread. The stdin, stdout and stderr are a bit
different, since you don't have to open them, they simply exist.
>>> What is the purpose of _wrapup_reent()? Its not called from within
>>> Newlib and I don't find a function that can register an atexit handler
>>> in a non-global _reent structure. There is also no public header file
>>> for this function.
>> I think we should move the _wrapup_reent() into a separate file.
> I suspect _wrapup_reent() is dead. But moving it is probably a safe
> alternative to killing it.
>
> I wondered a bit about cleanup_glue().
>
> + cleanup_glue() is not referenced outside reent.c. Should it be static?
> + cleanup_glue() is recursive. Is this desirable? Can its use in
> _reclaim_reent() be replaced with a loop?
>
>
Oh.
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.huber@embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the Newlib
mailing list