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]

[PATCH]: Thread safe FILE allocation [WAS: Re: [RFC]: Thread safetyin __sfp and atexit]


Jeff Johnston wrote:
Thomas Pfaff wrote:

The list operations in __sfp and atexit are not thread safe AFAICS.

This could be avoided by using a mutex or atomic instructions when a FILE pointer is acquired or an atexit function is added.

The problem hereby is that such a mutex should be created on newlib initialization (_REENT_INIT on the _impure_ptr for example), but there might be better locations.

Doing list insert with atomic instructions on the other hand is easy on i86 (i486 and above) but might be a problem on other platfomrs.

Comments are welcome.

Thomas


You can't assume atomic instructions exist for all platforms. I think something akin to the ENV_LOCK. MALLOC_LOCK methods used by the getenv and malloc family routines would be appropriate.
-- Jeff J.

Attached is what i think would be appropriate.
It protects the FILE pointer list by using __LOCK_INIT, __lock_acquire and __lock_release.


Thomas

2004-01-22 Thomas Pfaff <tpfaff@gmx.net>

	* libc/stdio/findfp.c (__sfp): Protect global FILE pointer list
	by a lock when newlib is multithreaded.
--- findfp.c.org	2004-01-22 13:52:35.135137600 +0100
+++ findfp.c	2004-01-22 13:53:31.976872000 +0100
@@ -86,6 +86,12 @@ __sfp (d)
   int n;
   struct _glue *g;
 
+#ifndef __SINGLE_THREAD__
+  __LOCK_INIT(static, lock);
+
+  __lock_acquire(lock); 
+#endif
+
   if (!_GLOBAL_REENT->__sdidinit)
     __sinit (_GLOBAL_REENT);
   for (g = &_GLOBAL_REENT->__sglue;; g = g->_next)
@@ -97,11 +103,17 @@ __sfp (d)
 	  (g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
 	break;
     }
+#ifndef __SINGLE_THREAD__
+  __lock_release(lock); 
+#endif
   d->_errno = ENOMEM;
   return NULL;
 
 found:
   fp->_flags = 1;		/* reserve this slot; caller sets real flags */
+#ifndef __SINGLE_THREAD__
+  __lock_release(lock); 
+#endif
   fp->_p = NULL;		/* no current pointer */
   fp->_w = 0;			/* nothing to read or write */
   fp->_r = 0;

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