(DCIGETTEXT): Protect tfind/tsearch calls.
authordrepper <drepper>
Sun, 26 Sep 2004 04:44:38 +0000 (04:44 +0000)
committerdrepper <drepper>
Sun, 26 Sep 2004 04:44:38 +0000 (04:44 +0000)
intl/dcigettext.c

index 65d8932..d711172 100644 (file)
@@ -439,7 +439,15 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
   search->domainname = (char *) domainname;
   search->category = category;
 
+  /* Since tfind/tsearch manage a balanced tree, concurrent tfind and
+     tsearch calls can be fatal.  */
+  __libc_rwlock_define_initialized (static, tree_lock);
+  __libc_rwlock_rdlock (tree_lock);
+
   foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
+
+  __libc_rwlock_unlock (tree_lock);
+
   freea (search);
   if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
     {
@@ -633,9 +641,14 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
                      newp->translation = retval;
                      newp->translation_length = retlen;
 
+                     __libc_rwlock_wrlock (tree_lock);
+
                      /* Insert the entry in the search tree.  */
                      foundp = (struct known_translation_t **)
                        tsearch (newp, &root, transcmp);
+
+                     __libc_rwlock_unlock (tree_lock);
+
                      if (foundp == NULL
                          || __builtin_expect (*foundp != newp, 0))
                        /* The insert failed.  */