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;
}