Index: trunk/docs/Changelog
===================================================================
--- trunk/docs/Changelog	(revision 239)
+++ trunk/docs/Changelog	(revision 240)
@@ -1,3 +1,9 @@
-2.5.7:
+2.5.8:
+	* fixed a bug in the MX resolver routine which causes it to fail 
+	  sometimes (issue reported by N. Rath).
+	* fixed deadlock with mutex_listall in sh_nmail_test_recipients() if 
+	  error occurs within sh_nmail_flush (problem reported by N. Rath)
+	
+2.5.7 (21-07-2009):
 	* sh_userfiles.c: set userUids = NULL at reconfiguration (issue
 	  reported by U. Melzer)
Index: trunk/src/sh_mail.c
===================================================================
--- trunk/src/sh_mail.c	(revision 239)
+++ trunk/src/sh_mail.c	(revision 240)
@@ -1584,4 +1584,5 @@
   length = res_query (hostname, C_IN, T_MX, 
 		      (unsigned char *) reply, 4095);
+
   if (length < 1)
     {
@@ -1649,4 +1650,5 @@
 	}
     }
+
   count         = ntohs (header->ancount);
   if (count < 1)
@@ -1688,5 +1690,5 @@
       /* HEADER NAME 
        */
-      ret = dn_expand ((unsigned char *) &reply, eom, comp_dn, 
+      ret = dn_expand ((unsigned char *) reply, eom, comp_dn, 
 		       (char *) expanded, 1023);
       comp_dn += ret;
@@ -1711,4 +1713,5 @@
 	}
 
+
       /* CLASS (re-use 'type' var)
        */
@@ -1723,4 +1726,5 @@
 	}
 
+
       /* TTL
        */
@@ -1758,5 +1762,5 @@
 	}
 
-      ret = dn_expand ((unsigned char *) &reply, eom, comp_dn, 
+      ret = dn_expand ((unsigned char *) reply, eom, comp_dn, 
 		       (char *) expanded, 1023);
       comp_dn += ret;
Index: trunk/src/sh_nmail.c
===================================================================
--- trunk/src/sh_nmail.c	(revision 239)
+++ trunk/src/sh_nmail.c	(revision 240)
@@ -44,4 +44,5 @@
 
 SH_MUTEX_INIT(mutex_listall, PTHREAD_MUTEX_INITIALIZER);
+SH_MUTEX_INIT(mutex_flush_l, PTHREAD_MUTEX_INITIALIZER);
 
 /* Pointer to last address */
@@ -376,4 +377,6 @@
 }
 
+/* Is not called from same(recursively) or different thread
+ */
 static
 int sh_nmail_flag_recipients (int level, const char * message, 
@@ -391,4 +394,6 @@
 }
 
+/* Can be called from same thread with mutex_listall held via sh_nmail_flush()
+ */
 static
 int sh_nmail_test_recipients (int level, const char * message, 
@@ -399,7 +404,11 @@
   if (message)
     {
-      SH_MUTEX_LOCK_UNSAFE(mutex_listall);
-      retval = sh_nmail_compute_recipients (level, message, alias, 0);
-      SH_MUTEX_UNLOCK_UNSAFE(mutex_listall);
+      if (0 == SH_MUTEX_TRYLOCK_UNSAFE(mutex_flush_l))
+	{
+	  SH_MUTEX_LOCK_UNSAFE(mutex_listall);
+	  retval = sh_nmail_compute_recipients (level, message, alias, 0);
+	  SH_MUTEX_UNLOCK_UNSAFE(mutex_listall);
+	  SH_MUTEX_UNLOCK_UNSAFE(mutex_flush_l);
+	}
     }
   return retval;
@@ -426,4 +435,6 @@
 }
 
+static int nmail_count = 0;
+
 /*
  * First mark list of recipients, then call sh_mail_msg().
@@ -433,5 +444,4 @@
 {
   volatile int retval = 0;
-  static int count = 0;
 
   /* Need to:
@@ -445,8 +455,8 @@
   if (0 == SH_MUTEX_TRYLOCK_UNSAFE(nmail_lock))
     {
-      ++count;
-      if (count != 1)
-	{
-	  --count;
+      ++nmail_count;
+      if (nmail_count != 1)
+	{
+	  --nmail_count;
 	  SH_MUTEX_UNLOCK_UNSAFE(nmail_lock);
 	  goto cleanup;
@@ -468,5 +478,5 @@
 	}
       SH_MUTEX_LOCK_UNSAFE(nmail_lock);
-      --count;
+      --nmail_count;
       SH_MUTEX_UNLOCK_UNSAFE(nmail_lock);
     }
@@ -477,4 +487,33 @@
 }
 
+static int sh_nmail_flush_int (void);
+
+int sh_nmail_flush ()
+{
+  int                retval = 0;
+
+  if (0 == SH_MUTEX_TRYLOCK_UNSAFE(nmail_lock))
+    {
+      ++nmail_count;
+      if (nmail_count != 1)
+	{
+	  --nmail_count;
+	  SH_MUTEX_UNLOCK_UNSAFE(nmail_lock);
+	  return retval;
+	}
+      SH_MUTEX_UNLOCK_UNSAFE(nmail_lock);
+
+      retval = sh_nmail_flush_int ();
+
+      SH_MUTEX_LOCK_UNSAFE(nmail_lock);
+      --nmail_count;
+      SH_MUTEX_UNLOCK_UNSAFE(nmail_lock);
+    }
+  return retval;
+}
+
+/* warning: variable âlistâ might be clobbered by âlongjmpâ or âvforkâ*/
+static struct alias ** list_dummy;
+
 /*
  * Loop over all recipients in stack. 
@@ -483,5 +522,5 @@
  */
 
-int sh_nmail_flush ()
+static int sh_nmail_flush_int ()
 {
   int                retval = 0;
@@ -491,4 +530,7 @@
   struct alias     * dlist;
 
+  /* warning: variable âlistâ might be clobbered by âlongjmpâ or âvforkâ*/
+  list_dummy = &list;
+
   SH_MUTEX_LOCK(mutex_listall);
 
@@ -529,5 +571,8 @@
       list = compiled_recipient_list;
       
+      SH_MUTEX_LOCK(mutex_flush_l);
       (void) sh_mail_msg(sh_string_str(msg));
+      SH_MUTEX_UNLOCK(mutex_flush_l);
+
       sh_string_destroy(&msg);
       
@@ -591,5 +636,7 @@
     if (smsg)
       {
+	SH_MUTEX_LOCK(mutex_flush_l);
 	(void) sh_mail_msg(sh_string_str(smsg));
+	SH_MUTEX_UNLOCK(mutex_flush_l);
 	sh_string_destroy(&smsg);
       }
@@ -656,5 +703,7 @@
     if (smsg)
       {
+	SH_MUTEX_LOCK(mutex_flush_l);
 	(void) sh_mail_msg(sh_string_str(smsg));
+	SH_MUTEX_UNLOCK(mutex_flush_l);
 	sh_string_destroy(&smsg);
       }
