This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin 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?


A monster patch has been checked in.  I found a problem in stdio64/fseeko64.c
using struct stat when calling _fstat64_r. I could not switch to use stat64
as Cygwin has not defined it externally.  For now, stdio64/fseeko64.c will use _fstat_r
instead of _fstat64_r.

I have rebuilt on linux and cygwin. Give it a try.

There is still some reentrancy fixups that could be done but they will
not have any impact on a __DYNAMIC_REENT__ or non-threaded build which
work correctly by virtue of using _REENT.

-- 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







--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


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