diff -ur orig/meta1-1.0.PreAlpha28.0/include/sm/pmfapi.h meta1-1.0.PreAlpha28.0/include/sm/pmfapi.h
--- orig/meta1-1.0.PreAlpha28.0/include/sm/pmfapi.h	2008-10-30 06:52:59.000000000 +0200
+++ meta1-1.0.PreAlpha28.0/include/sm/pmfapi.h	2009-06-04 18:11:05.000000000 +0300
@@ -313,7 +313,11 @@
 
 	pmfi_msg_rplc_stat_F	 pmfi_msg_rplc_stat;
 
-	char		 pmfi_unused[64];
+	uint32_t         pmfi_thrmax_s;
+	uint32_t         pmfi_thrmax_h;
+	uint32_t         pmfi_fdmax;
+	
+	char		 pmfi_unused[52];
 };
 
 LIBMILTER_API sm_ret_T sm_pmfi_init(pmg_ctx_P *_pmg_ctx);
diff -ur orig/meta1-1.0.PreAlpha28.0/libpmilter/pmilter_init.c meta1-1.0.PreAlpha28.0/libpmilter/pmilter_init.c
--- orig/meta1-1.0.PreAlpha28.0/libpmilter/pmilter_init.c	2006-10-05 07:27:38.000000000 +0300
+++ meta1-1.0.PreAlpha28.0/libpmilter/pmilter_init.c	2009-06-06 09:22:53.000000000 +0300
@@ -13,6 +13,7 @@
 #include "sm/assert.h"
 #include "sm/memops.h"
 #include "sm/evthr.h"
+#include "sm/pmfapi.h"
 #include "pmilter.h"
 
 #if MTA_USE_PMILTER
@@ -111,7 +112,7 @@
 	if (sm_is_err(ret))
 	{
 		sm_io_fprintf(smioerr,
-			"sev=ERROR, func=sm_pmilt_init, thr_init=%x\n", ret);
+			"sev=ERROR, func=sm_pmilt_init, thr_init=%m\n", ret);
 		goto error;
 	}
 
@@ -120,16 +121,21 @@
 	{
 		ret = sm_error_perm(SM_EM_Q, i);
 		sm_io_fprintf(smioerr,
-			"sev=ERROR, func=sm_pmilt_init, mutex_init=%x\n", i);
+			"sev=ERROR, func=sm_pmilt_init, mutex_init=%m\n", ret);
 		goto error;
 	}
 
-	/* initialize event threads system; CONF */
-	ret = evthr_init(&pmg_ctx->pmg_ev_ctx, 2, 6, 10);
+	/* initialize event threads system */
+#define SM_PMFI_DEF_VAL(val, dfl) (((val) > 0) ? (val) : dfl)
+	ret = evthr_init(&pmg_ctx->pmg_ev_ctx,
+		       SM_PMFI_DEF_VAL(pmg_ctx->pmg_pmilter->pmfi_thrmax_s, 2),
+		       SM_PMFI_DEF_VAL(pmg_ctx->pmg_pmilter->pmfi_thrmax_h, 6),
+		       SM_PMFI_DEF_VAL(pmg_ctx->pmg_pmilter->pmfi_fdmax, 10));
+
 	if (sm_is_err(ret))
 	{
 		sm_io_fprintf(smioerr,
-			"sev=ERROR, func=sm_pmilt_init, evthr_init=%x\n", ret);
+			"sev=ERROR, func=sm_pmilt_init, evthr_init=%m\n", ret);
 		goto error;
 	}
 
--- orig/meta1-1.0.PreAlpha28.0/doc/README.tex	2009-01-02 05:48:13.000000000 +0200
+++ meta1-1.0.PreAlpha28.0/doc/README.tex	2009-06-03 10:14:42.000000000 +0300
@@ -1610,6 +1610,19 @@
 port for inet socket
 (type {\tt socket} only).
 \item
+\verb|min_connections|\index{min_connections}:
+minumum number of simultaneously open connections
+(type {\tt socket} only). Default is 1. See below for
+a description.
+\item
+\verb|max_connections|\index{min_connections}:
+maximum number of simultaneously open connections
+(type {\tt socket} only).
+\item
+\verb|timeout|\index{timeout}:
+time to wait for the answer from the socket map.
+Default is 5 seconds (type {\tt socket} only).
+\item
 \verb|maps|\index{maps}:
 list of map names to use in the map
 (type {\tt sequence} only).
@@ -1619,7 +1632,7 @@
 for {\tt socket} maps either
 a Unix domain socket (\verb|path|)
 or an inet socket (\verb|address| and \verb|port|)
-must be specified.
+must be specified. 
 
 Example:
 
@@ -1631,6 +1644,30 @@
 map seq2 { type = sequence; maps = { password, otherusers }; }
 \end{verbatim}
 
+By default, SMAR opens a single connection to each socket map
+configured, which means that accesses to this map are serialized. As a
+result, each incoming connection waits in a queue while all
+previous connections are served. This may create intolerable
+delays on loaded servers. To avoid this, use {\tt min\_connections}
+and {\tt max\_connections} to create a spool of map connections, e.g.:
+
+\begin{verbatim}
+map userdb {
+    type = socket;
+    path = "/var/spool/meta1/smap/userdb";
+    mapname = userdb;
+    min_connections = 10;
+    max_connections = 512;
+}
+\end{verbatim}
+
+This way, when a need to consult the map arrives, SMAR looks
+for the first free connection among the opened ones and uses it. If
+there are no more free connections and the number of opened
+connections is less than {\tt max\_connections}, SMAR will create a
+new connection to serve the request. Otherwise, if the maximum number
+of connections is reached, SMAR will wait until any of them becomes
+available again.
 
 \subsection{Configuration Options for SMAR}
 \label{ConfigurationOptionsforSMAR}
