Re: [Vala] How to wrap select(2)'s fd_set?



* David Keijser wrote, On 05/02/09 13:07:
2009/2/5 Michael 'Mickey' Lauer <mickey vanille-media de>:
Am Friday 30 January 2009 14:26:51 schrieb Michael 'Mickey' Lauer:
Am Friday 30 January 2009 08:30:43 schrieb Jürg Billeter:
FdSet should be a struct, not a class, we do not need reference type
semantics here. This eliminates unnecessary heap allocation. FD_ZERO
should be bound as initialization method as it just zeroes the streuct.
Understood.

[CCode (cname = "fd_set", cheader_filename = "sys/select.h"]
public struct FdSet {
    [CCode (cname = "FD_ZERO")]
    public FdSet ();
    ...
}
With this change, I get a strange C-compilation error:

/local/pkg/fso/fso-gsm0710muxd/src/multiplexer.c: In
Funktion »multiplexer_writefd«:
/local/pkg/fso/fso-gsm0710muxd/src/multiplexer.c:324: Fehler: expected
expression before »do«
/local/pkg/fso/fso-gsm0710muxd/src/multiplexer.c:325: Fehler: expected
expression before »do«
/local/pkg/fso/fso-gsm0710muxd/src/multiplexer.c:326: Fehler: expected
expression before »do«

The respective generated code is:

gboolean multiplexer_writefd (Multiplexer* self, const char* command, gint
fd) {
        fd_set _tmp0 = {0};
        fd_set readfds;
        fd_set _tmp1 = {0};
        fd_set writefds;
        fd_set _tmp2 = {0};
        fd_set exceptfds;
        struct timeval t = {(glong) 1, (glong) 0};
        gint r;
        gboolean _tmp3;
        gssize bwritten;
        g_return_val_if_fail (self != NULL, FALSE);
        g_return_val_if_fail (command != NULL, FALSE);
        readfds = (FD_ZERO (&_tmp0), _tmp0);
        writefds = (FD_ZERO (&_tmp1), _tmp1);
        exceptfds = (FD_ZERO (&_tmp2), _tmp2);
        FD_SET (fd, &writefds);
...

I have no idea where this 'do' comes from.
Ok, I now found out:

FD_ZERO is defined as __FD_ZERO which in turn is defined as:

/* We don't use `memset' because this would require a prototype and
  the array isn't too big.  */
#define __FD_ZERO(s) \
 do { \
   unsigned int __i; \
   fd_set *__arr = (s); \
   for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
     __FDS_BITS (__arr)[__i] = 0; \
 } while (0)

The valac-generated part

readfds = (FD_ZERO (&_tmp0), _tmp0);
is a syntax error then.

Anything we can do about that or just give in and leaving FdSet a full class?

use memset ?

I have this vague memory of there being a way of marking a function as
a macro in vapi. if not perhaps it should be considered adding it as
macros are quite common.
Try the gcc extension something like:
readfds = (__extension__ ({ FD_ZERO(&_tmp0)} ), _tmp);

I recall someone saying that generally vala code is compiled by gcc.

However I would like vala to be able to disentangle the long tuples and write some human looking code... although it is a nasty job as the re-written code can no longer be followed by variable declarations, but this is much simpler to read:

FD_ZERO(&_tmp0);
readfds = _tmp0;

I wonder why _tmp0 needed to be used at all - I would have guessed to stop readfds accessing an uninitialized struct, but that doesn't make sense if readfds starts out as an uninitialized struct...

Sam




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