Greetings! Since discovering libevent for myself I've been wondering why where is still no support for Edge-Triggered behaviour, which from my point of view could be easily implemented.
There were many talks already among Linux kernel developers as well as application developers about how and why to use it. I have also discovered that people already were trying to implement such functionality with greater or lesser degree of success, e.g. here: https://webmail.iro.umontreal.ca/pipermail/gambit-list/2005-August/000367.html So I tried to do it once again and a link to a patch is given below. But the problem with Edge-Triggered behaviour is that few people understand it. There is simply no clear understanding among application developers of how Edge-Triggered works, which produces Fear, Uncertainity and Doubt (FUD). Therefore I think I have to provide some guidelines about this. libevent is currently by default Level-Triggered (LT), this means that an event is generated every time kqueue/epoll/select/whatever is invoked and a descriptor has data available to read or IO space available to write to. With Edge-Triggered (ET) behaviour an event is generated every time the amount of data available to read overcomes threshold of 0 or the amount of IO space available to write to overcomes threshold of 0. This means that no new events will be generated unless the application will read out all available incoming data or fill all available outbound IO space. This means that whenever a descriptor available to read is reported and Edge-Triggered behaviour takes place the application have to read out all the data until EOF or error or EAGAIN will be returned by read/readv. In the similar way whenever a descriptor available to write is reported and Edge-Triggered behaviour takes place the application have to write all the data it has until an error or EAGAIN will be returned by write/writev/sendfile. Such a strategy is also recommended by select_tut(2) man page (see section SELECT LAW point 6) to prevent IO starvation. So there is nothing mystical behind it and similar strategy has been already existing in pre-ET era. This has a significant advantage, that whenever you read and you run out of destination buffer/IO space there is no need to unarm the descriptor by calling event_del, you just have to remember somewhere that the descriptor is still available to read. Then you return to it when the destination buffer/IO space emerges. In the similar way where is not need to rearm the descriptor whenever data emerges to be sent out. You just have to remember in your application that the descriptor was available to write and simply continue to write. With epoll/kqueue this saves you a number of system calls which is the source of additional performance. With kqueue Edge-Triggered behaviour could be simply enforced using EV_CLEAR flag according to this message: http://www.cs.helsinki.fi/linux/linux-kernel/2001-38/0547.html The patch itself is submitted into SF's patch tracking system: http://sourceforge.net/tracker/index.php?func=detail&aid=1968284&group_id=50884&atid=461324 This patch introduces EV_ET flag. Whenever you specify EV_ET in event_set call a specific module will try enforce Edge-Triggered behaviour. Whevever Edge-Triggered behaviour takes place ,the event argument of a callback will additionally contain EV_ET flag, and you should react accordingly. When methods are used, which do not support ET such as select or poll, no EV_ET flag will be ever set. The file test/test_et.c demonstrates the usage of EV_ET flag. I hope that maintainers will agree to integrate the patch in future versions of libevent. Good luck and additional performance to your applications! -- Best regards, Valery Kholodkov _______________________________________________ Libevent-users mailing list Libevent-users@monkey.org http://monkeymail.org/mailman/listinfo/libevent-users