site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=QOeQ7am4wNTGStQrM31YtMkPhPQLuXenbUW2EW7s5Rg=; b=R56Y2nIAH/MgInOfxqTZtUAbyQYG5tlWwh+4a0iaYge+6mvUs77SYqssuBU534SQEd Ia/HbyWuUHUUYUpmtWVn8pXwGjA+8My3eUy/E4l4MRsnzb5LNtKimL0LiAr+wecfUot0 7mb62Q3lG1obYxfwE0F9NU+vHxGurGMjUPYWk= Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=ixmyp8Y4O9jgSpqHTquLel5TXI+7ay3DTG7wAOJ33VyO92r7YpX4703zm8voBh8kyy rAmhLd8RJoFQf8h5jGLoRAO2CZbhy/3lbLRI3fmXO5lWHaYV/UKSIOxFH+5MsZBYX9lz 5O4AQlFyPbJ53bU1rkyoUUuPVv3FkOLW7U/38= 2009/4/2 A.M. <agentm@themactionfaction.com>:
On Apr 2, 2009, at 11:07 AM, Påhl Melin wrote:
Hi all,
I have a question regarding the order events are returned from a kevent() call on a kqueue, if I only supply one event in the event list and no events are changed? Is there a predefined order in which the filters are processed and returned as events when there are multiple events available at the same time?
For example if I have two filters, one EVFILT_READ filter and one EVFILT_WRITE filter and there is available room in both the read and the write buffers. If I make four subsequent calls, in what order will the events be returned? Will I get EVFILT_READ, EVFILT_WRITE, EVFILT_READ, EVFILT_WRITE? Or will I e.g. get one of the events repeatedly until that buffer is empty/full, like EVFILT_READ until I have read everything in the read buffer? Or is random or some other algorithm?
What I want to do is to alternate between read and write events to get good responsiveness. I suppose I could change the events in the kqueue but it would be easier to rely on some guaranteed behavior.
The order you receive is the order that the kernel put the events in the queue- that is, after all, what makes it a k*queue*. If this is socket communications, you will get spammed with EVFILT_WRITE events as long as the socket buffer is full; however, this does not imply that you will get no read events in between. But you should selectively enable and disable EVFILT_WRITE events based on whether or not you actually have stuffed the socket buffer (when the non-blocking socket I/O returns fewer bytes than what you passed in).
I'm writing a messaging framework that sends asynchronous messages between processes on a local machine using Unix Domain Sockets and between machines using normal TCP/IP sockets. My idea was to use a design where I keep an open socket between two nodes and have one "service" thread handling the communication on the socket using a kqueue and looping around a kevent() call. When there are outgoing commands present, the thread enables the EVFILT_WRITE filter and waits for available space in the write buffer. When all commands are written to the socket, the EVFILT_WRITE filter is disabled. At the same time I also would have a EVFILT_READ enabled, receiving incoming replies for the commands and also asynchronous incoming messages. In a very simplified form without error checking, my loop would look like this: for (;;) { numberOfEvents = kevent(kq, NULL, 0, &event, 1, NUL); if (event.filter == EVFILT_READ) { // handle read events } else if (event.filter == EVFILT_WRITE) { // handle write events } } In the read and write event handling I would read or write a few bytes for the current command and I would then continue the loop waiting in the kevent() statement again. When I have multiple commands and replies I assume that the kevent() would return immediately with the data member containing the remaining bytes to be read (or space left in the write buffer). I would expect the kqueue not to be filled up with EVFILT_READ and EVFILT_WRITE events, but to have only one of each whenever the buffers are "ready". But the question is if I'm guaranteed to have alternating read and write events? Or if I get starvation of any kind? I don't see anything about this matter in the man pages so I'm curious if it's specified at all?
I haven't experienced any event starvation situation, but in case you have, the best approach would be to implement an array over kqueue. Simply read more than one event into your own queue and you can algortithmically decide which events to process (and then remove them from the array- obviously it's no longer a queue). But don't waste time implementing this approach unless you are indeed experiencing starvation.
Thanks, I hadn't really considered returning multiple events and make my own decision. But it would of course be easier if a reasonable decision was already made by the kevent() call.
Since one thread can only do so much, if you have lots of socket or sources, then you may want to break their processing into separate thread (kqueue is thread-safe and works well across multiple threads). Even a single socket read and write events could be broken out across threads.
That's interesting. I what sense is kqueue thread safe? Can I wait on the same kqueue in two different threads, each calling kevent() or do I make two kqueue:s, one with a read filter and the other queue with a write event on the same socket descriptor?
Cheers, M
Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This email sent to site_archiver@lists.apple.com