Re: ORBit writev screwedness ...
- From: Sebastian Wilhelmi <wilhelmi ira uka de>
- To: Michael Meeks <michael ximian com>
- Cc: orbit-list gnome org
- Subject: Re: ORBit writev screwedness ...
- Date: 05 Feb 2002 13:18:14 +0100
Hi,
> > This may well be down to the IOVEC limit on many unix's being much much
> > lower than on Linux;
> >
> > See bugzilla.gnome.org 56270 for 1 attempt at a fix which I must
> > confess doesn't impress me.
>
> While we're at it:
>
> I once coded a 'right' solution for IOV_MAX for ORBit-mt, but never got
> around to actually post it here for general use.
>
> As is little known, linux does not support very long IOV_MAX (up until
> 2.0 only 16 was supported, from 2.2 on 1024), but glibc just does the
> natural thing, once the kernel calls fails. It just concatenates all
> buffers into a stack buffer and calls write. Thus the configure.in test
> didn't notice, that only 1024 (or 16) io_vecs are supported.
>
> So this might (and did for multi threaded CORBA applications, as they
> have limited stack-size per thread) lead to a segmentation fault and a
> crash.
>
> So I programmed the following code-snippet, which will lead to better
> results than the configure.in test:
As there was no reaction, I figured to make a patch myself. It is
attached against CVS HEAD linc. It should really be included and might
also benefit ORBit-stable.
Bye,
Sebastian
--
Sebastian Wilhelmi
mailto:wilhelmi@ira.uka.de
http://goethe.ira.uka.de/~wilhelmi
Index: acconfig.h
===================================================================
RCS file: /cvs/gnome/linc/acconfig.h,v
retrieving revision 1.4
diff -p -u -b -B -r1.4 acconfig.h
--- acconfig.h 2001/10/24 06:20:42 1.4
+++ acconfig.h 2002/02/05 12:09:56
@@ -10,5 +10,4 @@
* Sun Microsystems, Inc.
*/
#undef socklen_t
-#undef WRITEV_IOVEC_LIMIT
#undef HAVE_SOCKADDR_SA_LEN
Index: configure.in
===================================================================
RCS file: /cvs/gnome/linc/configure.in,v
retrieving revision 1.52
diff -p -u -b -B -r1.52 configure.in
--- configure.in 2002/01/28 17:27:36 1.52
+++ configure.in 2002/02/05 12:09:56
@@ -122,44 +122,6 @@ fi
AC_C_BIGENDIAN
-AC_MSG_CHECKING(maximum number of iovecs for a writev)
-AC_TRY_RUN([
-#include <fcntl.h>
-#include <sys/uio.h>
-#include <stdio.h>
-#include <unistd.h>
-#define NIOVECS 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2
-int main(int argc, char *argv[])
-{
- char dumbuf[20] = "\n";
- struct iovec iovecs[NIOVECS];
- int i,fd;
- FILE *f;
-
- for(i = 0; i < NIOVECS; i++) {
- iovecs[i].iov_base = dumbuf;
- iovecs[i].iov_len = 1;
- }
-
- f = fopen("conftestval", "w");
- fd=open("/dev/null", O_WRONLY);
- if(fd==-1)
- return(1);
-
- for(i = 1; 2*i < NIOVECS; i *= 2)
- if(writev(fd, iovecs, 2*i) < 0)
- break;
- fprintf(f, "%d\n", i);
-
- close(fd);
- fclose(f);
- return 0;
-}
-], WRITEV_IOVEC_LIMIT="`cat conftestval`", WRITEV_IOVEC_LIMIT=1024, WRITEV_IOVEC_LIMIT=1024)
-
-AC_MSG_RESULT($WRITEV_IOVEC_LIMIT)
-AC_DEFINE_UNQUOTED(WRITEV_IOVEC_LIMIT, $WRITEV_IOVEC_LIMIT)
-
if test "x$GCC" = "xyes" -a "x$enable_compile_warnings" != "xno"; then
WARN_CFLAGS="-Wall -Wunused -Wmissing-prototypes -Wmissing-declarations"
else
Index: src/linc-connection.c
===================================================================
RCS file: /cvs/gnome/linc/src/linc-connection.c,v
retrieving revision 1.61
diff -p -u -b -B -r1.61 linc-connection.c
--- src/linc-connection.c 2002/01/21 16:24:03 1.61
+++ src/linc-connection.c 2002/02/05 12:09:57
@@ -478,6 +478,46 @@ linc_connection_read (LINCConnection *cn
return bytes_read;
}
+/* Determine the maximum size of the iovec vector */
+
+#if defined (UIO_MAXIOV) /* Glibc */
+# define LINC_IOV_MAX (UIO_MAXIOV)
+#elif defined (MAXIOV) /* HPUX */
+# define LINC_IOV_MAX (MAXIOV)
+#elif defined (IOV_MAX) /* AIX */
+# define LINC_IOV_MAX (IOV_MAX)
+#elif defined (_SC_IOV_MAX) /* SGI */
+# define LINC_IOV_MAX_INIT (sysconf (_SC_IOV_MAX))
+#else /* Safe Guess */
+# define LINC_IOV_MAX 16
+#endif
+
+/* If the value requires initialization, define the function here */
+#if defined (LINC_IOV_MAX_INIT)
+# define LINC_IOV_MAX linc_iov_max
+ static guint linc_iov_max = 0;
+ static inline void
+ linc_iov_max_init ()
+ {
+ if (linc_iov_max == 0)
+ {
+ gint max;
+ G_LOCK_DEFINE_STATIC (linc_iov_max);
+ G_LOCK (linc_iov_max);
+ if (linc_iov_max == 0)
+ {
+ max = LINC_IOV_MAX_INIT;
+ if (max <= 0)
+ max = 16;
+ linc_iov_max = max;
+ }
+ G_UNLOCK (linc_iov_max);
+ }
+ }
+#else
+# define linc_iov_max_init()
+#endif
+
static glong
write_data (LINCConnection *cnx, QueuedWrite *qw)
{
@@ -486,6 +526,8 @@ write_data (LINCConnection *cnx, QueuedW
g_return_val_if_fail (cnx->status == LINC_CONNECTED,
LINC_IO_FATAL_ERROR);
+ linc_iov_max_init ();
+
while ((qw->nvecs > 0) && (qw->vecs->iov_len > 0)) {
int n;
@@ -499,7 +541,7 @@ write_data (LINCConnection *cnx, QueuedW
else
#endif
n = writev (cnx->priv->fd, qw->vecs,
- MIN (qw->nvecs, WRITEV_IOVEC_LIMIT));
+ MIN (qw->nvecs, LINC_IOV_MAX));
d_printf ("wrote %d bytes\n", n);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]