Re: AMIGA will use Linux, but Linux has several "multimedia-deficiencies"

Malcolm Beattie (mbeattie@sable.ox.ac.uk)
Wed, 14 Jul 1999 10:45:58 +0100 (BST)


Gerard Roudier writes:
> You can select on message queues on AIX, IIRC, but this is not portable.
> MVS accepts additionnal parameters for the select() that allows to also
> wait for events on other types of resources (in the case you really want
> to use select under this O/S).
>
> Using select() and une unique message queue for read is possible with
> conjunction of SIGIO/SIGALRM with the risk of the application to lose time
> if it has very bad luck.
>
> You can implement something like that:
>
> If you expect event(s) from fds (basically SIGIO will kick ass you)
>
> 1) set an alarm of a few seconds (<=2 seconds for example)
> also set the alarm from the alarm handler.
>
> 2) get next message in blocking mode
>
> 3) if interrupted go with poll/select the fds
> (can be either SIGIO or SIGALRM)
>
> If you are so unfortunate that the SIGIO occurs between 1 and 2, your
> program will only be stuck for less than 1..2 seconds.
> (The period between (1) and (2) that may let msgrcv block can be minimized
> by some additionnal code).
>
> By the way, this works for me since 10 years in some applications, and I
> never have been able to get the problem in my testings. Indeed it is not
> clean and not optimal at all, but when you haven't the choice such a
> band-aid is really helpfull.

What's wrong with the usual way of forking/starting a thread which
blocks itself and writes a byte down a pipe when it's done? That's a
standard generic way of including any blocking behaviour at all into
a select/poll based event loop. Roughly,

void *msg_block(void *arg)
{
struct minfo *m = (struct minfo *)arg;
while (1) {
msgrcv(m->msgid, m->msgbuf, m->msgsz, m->msgflag);
write(m->fd, "*", 1);
}
}

/* main program */
pipe(msg_readfd, msg_writefd);
struct minfo m = { msgid, msgbuf, msgsz, msgflag, msg_writefd };
pthread_t msg_thread;
pthread_create(&msg_thread, 0, msg_block, &m);
...
while (1) {
/* main loop */
...
FD_SET(msg_readfd, &fdset);
select(n, &fdset, 0, 0, 0);
if (FD_ISSET(msg_readfd, &fdset)) {
/* got message in msgbuf */
}
...
}

Add error checking, argument checking, sync for finishing and
seasoning to taste. IMHO, the wart isn't the lack of an event waiting
syscall that copes with different sorts of "descriptor" but the
failure of SysV IPC to provide access to message queues by means of
an ordinary file descriptor in the first place. Even the POSIX.4/1b
mob didn't correct that for their message queues, for some reason.

--Malcolm

-- 
Malcolm Beattie <mbeattie@sable.ox.ac.uk>
Unix Systems Programmer
Oxford University Computing Services

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/