An important aspect to examine prior to diving into the actual implementation is the design issue regarding choice of modes among select, epoll and kqueue.
Several possible solutions exist. We shall consider ones that appear most relevant.
Case 1:
Replacing select in its entirety with either epoll or kqueue
As a convenience to the user, it makes sense to take the responsibility of choosing the path away from the user; make it in-built.
Since the choice is only among 2 options, usage of macros would be a convenient solution.[1]
That's pretty nifty.
As our primary aim is to provide an enhancement to the web server, augmenting extensibility features will be an added advantage. The code can be made generic, adapting a common structure to handle requests through either approach. The function activated can depend on the macro chosen in as per the approach declared previously.
struct kevent {
uintptr_t ident; /* identifier for this event */
int16_t filter; /* filter for event */
uint16_t flags; /* general flags */
uint32_t fflags; /* filter-specific flags */
intptr_t data; /* filter-specific data */
void *udata; /* opaque user data identifier */
};
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
We have provided the corresponding kqueue and epoll structures for reference.
Case 2:
Keeping select implementation, and having a choice between select and epoll/kqueue
This approach is an extension of the above. The user has a choice to either use select or an event mechanism (ie epoll/kqeueue. This choice will be made inherently depending on the type of the system)
Code modules have a design potential.[2] But they might be an overkill with respect to BOA.
Case 3:
The choice among select, epoll and kqueue is left to the user.
You might wonder whether this is really advisable. After all, the user must not be bothered with implementation technicality. But, in the future, there may arise an operating system that provides libraries containing both epoll and kqueue.[3] Perhaps a user extremely particular about performance with the knowledge of the type of traffic expected will also find this useful.
In the actual code, a three-way switch will comfortably handle this circumstance.
Note regarding kFreeBSD: (see link [3])
Apparently you can run both Linux and FreeBSD binaries on it. It supports calls up to Linux version 2.6.18. But, using macros here will result in only epoll being used. (we check for __APPLE__ and not FreeBSD. This operating system will fall under __UNIX__ flag.)
The situation appears thus, having articulated possible solutions. We do hope for your valuable suggestions or additions. They would be most helpful in making an appropriate choice.
[3] kFreeBSD