This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to use __DYNAMIC_REENT__ correctly in multithreaded applications?


Thomas,

  Just to let you know that I am working on a fix for this problem.
It is a little more complex than first thought but I have it working
for your test scenario.

  I have eliminated use of the fp->_data pointer which is pointless.
There is no point performing future tasks based on the reentrant struct for
the file when it was opened.  That cures one problem.  I fixed the
CHECK_INIT macro to use _REENT for now.  I have also done a whole bunch
of cleaning up with regards to _r functions.  There is still some cleanup
that could be done, but for a DYNAMIC_REENT or single-threaded app, everything
should be working much better.  Finally, I have added the _GLOBAL_REENT
macro to be used for manipulating the file list.  Keeping everything but
the thread's std streams on the main thread helps when exiting and performing
a closeall.

  I hope to check in the patch tomorrow.

-- Jeff J.

Thomas Pfaff wrote:
> 
> I can not do it this way because it must be fixed for cygwin and not on
> an application level.
> 
> As far as i can see the only problem with __DYNAMIC_REENT__ is this
> stdio related stuff, so i would suggest to fix it temporarly in newlib.
> 
> My proposal is:
> 
> Create a new macro _GLOBAL_REENT which returns _impure_ptr.
> Change all functions in stdio to use _GLOBAL_REENT instead of _REENT
> until there is a better solution.
> 
> Thomas
> 
> J. Johnston wrote:
> 
> > It's a design problem that isn't the fault of __DYNAMIC_REENT__ and
> > is going to require a little bit of thought.  One way you might bypass this problem is
> > to create an fopen stub for your application and have it call _fopen_r with
> > the default global reentrancy struct.
> >
> > -- Jeff J.
> >
> > Thomas Pfaff wrote:
> >
> >>Hello,
> >>
> >>some time ago i have added a __DYNAMIC_REENT__ to the cygwin part of
> >>config.h. The main purpose was to get thread safe errnos (without this
> >>define errno is stored process global in _impure_ptr).
> >>
> >>Now the reent structure for every thread is thread local and will be
> >>destroyed when the thread has terminated. A __getreent function was
> >>implemented to get the thread local reent.
> >>
> >>This leads to following problem:
> >>
> >>Each FILE structure contains a pointer to the reent structure of the
> >>thread that initially opened the file. If the thread terminates than the
> >>   reent pointer will point to an invalid address.
> >>
> >>Here is a simple testcase to illustrate this probleme:
> >>
> >>#include <stdio.h>
> >>#include <pthread.h>
> >>
> >>static FILE *fp;
> >>
> >>static void *threadfunc (void *parm)
> >>{
> >>   fp = fopen ("/tmp/testreent", "w");
> >>   return NULL;
> >>}
> >>
> >>int main(void)
> >>{
> >>   pthread_t thread;
> >>
> >>   pthread_create (&thread, NULL, threadfunc, NULL);
> >>   pthread_join (thread, NULL);
> >>
> >>   fprintf (fp, "test");
> >>   fclose (fp);
> >>
> >>   return 0;
> >>}
> >>
> >>A thread opens a file and terminates immediately. The mainthread will
> >>try to write to the opened file and segfaults in the CHECK_INIT macro in
> >>fwrite since the data part of the FILE pointer is no longer valid.
> >>
> >>I am a bit clueless now:
> >>How was DYNAMIC_REENT stuff meant to work  ?
> >>
> >>IMHO the only way to get this working is to remove the reent part in the
> >>FILE structure, but there might be a better solution.
> >>
> >>TIA,
> >>Thomas
> >
> >


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]