This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
[RFA]: fork safe stdio locks
- From: Thomas Pfaff <tpfaff at gmx dot net>
- To: newlib at sources dot redhat dot com
- Date: Mon, 08 Mar 2004 20:56:52 +0100
- Subject: [RFA]: fork safe stdio locks
As i already mentioned i think that stdio locks should be locked at fork
and unlocked in both the parent and the child afterwards to avoid a
deadlock in the child process (at least when you are working with
pthread mutexes for locking).
The attached patch will add 2 functions to findfp.c which can be called
at before and after fork.
Thomas
2004-03-08 Thomas Pfaff <tpfaff@gmx.net>
* libc/stdio/findfp.c (__sfp): Rename lock to __sfp_lock.
Change __sfp_lock to static global.
(__fp_lock): New static function.
(__fp_unlock): Ditto.
(__fp_lock_all): New function.
(__fp_unlock_all): Ditto.
Index: findfp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/findfp.c,v
retrieving revision 1.10
diff -u -p -r1.10 findfp.c
--- findfp.c 22 Jan 2004 22:06:57 -0000 1.10
+++ findfp.c 8 Mar 2004 19:55:00 -0000
@@ -25,6 +25,10 @@
#include <sys/lock.h>
#include "local.h"
+#ifndef __SINGLE_THREAD__
+__LOCK_INIT(static, __sfp_lock);
+#endif
+
static void
std (ptr, flags, file, data)
FILE *ptr;
@@ -87,9 +91,7 @@ __sfp (d)
struct _glue *g;
#ifndef __SINGLE_THREAD__
- __LOCK_INIT(static, lock);
-
- __lock_acquire(lock);
+ __lock_acquire(__sfp_lock);
#endif
if (!_GLOBAL_REENT->__sdidinit)
@@ -104,7 +106,7 @@ __sfp (d)
break;
}
#ifndef __SINGLE_THREAD__
- __lock_release(lock);
+ __lock_release(__sfp_lock);
#endif
d->_errno = ENOMEM;
return NULL;
@@ -112,7 +114,7 @@ __sfp (d)
found:
fp->_flags = 1; /* reserve this slot; caller sets real flags */
#ifndef __SINGLE_THREAD__
- __lock_release(lock);
+ __lock_release(__sfp_lock);
#endif
fp->_p = NULL; /* no current pointer */
fp->_w = 0; /* nothing to read or write */
@@ -192,3 +194,39 @@ __sinit (s)
std (s->_stderr, __SWR | __SNBF, 2, s);
}
+
+#ifndef __SINGLE_THREAD__
+static int
+__fp_lock (ptr)
+ FILE * ptr;
+{
+ __lock_acquire (*(_LOCK_RECURSIVE_T *)&ptr->_lock);
+
+ return 0;
+}
+
+static int
+__fp_unlock (ptr)
+ FILE * ptr;
+{
+ __lock_release (*(_LOCK_RECURSIVE_T *)&ptr->_lock);
+
+ return 0;
+}
+
+void
+__fp_lock_all ()
+{
+ __lock_acquire(__sfp_lock);
+
+ (void) _fwalk (_REENT, __fp_lock);
+}
+
+void
+__fp_unlock_all ()
+{
+ (void) _fwalk (_REENT, __fp_unlock);
+
+ __lock_release(__sfp_lock);
+}
+#endif