Re: ORBit writev screwedness ...



Hi Michael,
 
> 	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.
> 
> 	Someone has committed another attempt at a fix - even worse than that
> to ORBit - which we are probably shipping now; in
> ORBit/src/ORBitutil/compat.c (g_writev) - which is multiply and
> unutterably broken.
> 
> 	I don't know what to do for the best really - is there anyone to work
> on this ? how did g_writev get as bad as it is ?
> 
> 	Possibly we can copy some working tested code to get around this from
> 'linc' - that actually does it write, handles multiple EAGAINs etc. etc.

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:

#if defined (UIO_MAXIOV) /* Glibc */
#define ORBIT_IOV_MAX (UIO_MAXIOV)
#elif defined (MAXIOV) /* HPUX */
#define ORBIT_IOV_MAX (MAXIOV)
#elif defined (IOV_MAX) /* AIX */
#define ORBIT_IOV_MAX (IOV_MAX)
#elif defined (_SC_IOV_MAX) /* SGI */
#define ORBIT_IOV_MAX_INIT (sysconf (_SC_IOV_MAX))
#else /* Safe Guess */
#define ORBIT_IOV_MAX 16
#endif

#if defined (ORBIT_IOV_MAX_INIT)
#define ORBIT_IOV_MAX orbit_iov_max
static gint orbit_iov_max = 0;
static inline void
orbit_iov_max_init ()
{
  if (orbit_iov_max == 0)
    {
      gint max;
      G_LOCK_DEFINE_STATIC (orbit_iov_max);
      G_LOCK (orbit_iov_max);
      if (orbit_iov_max == 0)
        {
          max = ORBIT_IOV_MAX_INIT;
          if (max <= 0)
            max = 16;
          orbit_iov_max = max;
        }
      G_UNLOCK (orbit_iov_max);
    }
}
#else
#define orbit_iov_max_init()
#endif

void
use_it () /* Here you just use the values from above */
{
  orbit_iov_max_init (); /* First initialize */
  
  ...

  writev ( ..., max (ORBIT_IOV_MAX, count));

  ...
}

Hope, that helps.

Bye,
Sebastian
-- 
Sebastian Wilhelmi
mailto:wilhelmi@ira.uka.de
http://goethe.ira.uka.de/~wilhelmi





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]