Still stuck with the above issue: 3 errors pending.

I decided to make a try with /dev/poll with the new SunOS.c attached 
file... and it works!
x==================
$ ct/_ctcheck
........................................................

PASS
x==================

It was a bit more difficult because /dev/poll does not preserve any user 
data, so I created a structure array of a given fixed length. The problem 
is to determine that array length as I need one position in the array per 
file descriptor to poll... The tests pass when the array length is 3 at 
least but can you help me on this side ? Can you tell me if there is a 
maximum of fd each process will pass to sockwant ?

I can't say I like the code but it looks like it works for now... No idea 
if this will work in production though.

This does not remove the questions I had in my previous post ;-)

Thanks

-- 
You received this message because you are subscribed to the Google Groups 
"beanstalk-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/beanstalk-talk.
For more options, visit https://groups.google.com/d/optout.
#include <sys/devpoll.h>
#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "dat.h"

static int  wfd;
static char buf0[512]; /* buffer of zeros */
#define UDATALEN 10
static struct {
    int inuse;
    int fd;
    void* user;
} udata[UDATALEN];


/* Allocate disk space.
 * Expects fd's offset to be 0; may also reset fd's offset to 0.
 * Returns 0 on success, and a positive errno otherwise. */
int
rawfalloc(int fd, int len)
{
    /* return posix_fallocate(fd, 0, len); */
    int i, w;

    for (i = 0; i < len; i += w) {
        w = write(fd, buf0, sizeof buf0);
        if (w == -1) return errno;
    }

    lseek(fd, 0, 0); /* do not care if this fails */

    return 0;
}


int
sockinit(void)
{
    wfd = open("/dev/poll", O_RDWR);
    if (wfd < 0) {
        twarn("open_/dev/poll");
        return -1;
    }
    return 0;
}


int
sockwant(Socket *s, int rw)
{
    int events, i1, i2;
    struct pollfd apollfd;

    if (!s->added && !rw) {
        return 0;
    } else if (!s->added && rw) {
        s->added = 1;
    }

    switch (rw) {
    case 0:
        events = POLLREMOVE;
        break;
    case 'r':
        events = POLLIN;
        break;
    case 'w':
        events = POLLOUT;
        break;
    default:
        events = 0;
        break;
    }

    /* Find the fd related udata bucket or a free one */
    for (i1 = 0, i2 = -1; i1 < UDATALEN; i1++) {
        if (udata[i1].inuse == 0) {
            if (i2 < 0) i2 = i1;
        } else if (udata[i1].fd == s->fd) {
            break;
        }
    }
    if (i1 < UDATALEN) {
        i2 = i1;
    } else {
        if (i2 < 0) {
            twarn("no more udata available!");
            return -1;
        }
    }
    udata[i2].inuse = (rw) ? 1 : 0;
    udata[i2].fd = s->fd;
    udata[i2].user = s;

    /* Send a fd to watch for to /dev/poll */
    apollfd.fd = s->fd;
    apollfd.events = events;
    apollfd.revents = 0;
    if (write(wfd, &apollfd, sizeof(struct pollfd)) != sizeof(struct pollfd)) {
      return -1;
    }
    return 0;
}


int
socknext(Socket **s, int64 timeout)
{
    int r, i1, i2;
    struct dvpoll advpoll;
    struct pollfd apollfd;

    advpoll.dp_timeout = timeout / 1000000;
    advpoll.dp_nfds = 1;
    advpoll.dp_fds = &apollfd;
    r = ioctl(wfd, DP_POLL, &advpoll);
    if (r < 0 && errno != EINTR) {
        twarn("ioctl_/dev/poll");
        exit(1);
    }

    if (r > 0) {
        /* Find the fd related udata bucket */
        for (i1 = 0; i1 < UDATALEN; i1++) {
            if (udata[i1].inuse == 0) {
                ;
            } else if (udata[i1].fd == advpoll.dp_fds[0].fd) {
                break;
            }
        }
        if (i1 < UDATALEN) {
            *s = udata[i1].user;
        } else {
            twarn("ioctl_/dev/poll udata not found!");
        }

        if (apollfd.revents & POLLHUP) {
            return 'h';
        } else if (apollfd.revents & POLLIN) {
            return 'r';
        } else if (apollfd.revents & POLLOUT) {
            return 'w';
        }
    }
    return 0;
}

Reply via email to