root/lang/c/mpio/trunk/mp/system/kqueue_impl.h @ 6633

Revision 6633, 2.1 kB (checked in by frsyuki, 6 years ago)

lang/c/mpio: added event::modify() interface

Line 
1#ifndef MP_SYSTEM_KQUEUE_IMPL_H__
2#define MP_SYSTEM_KQUEUE_IMPL_H__
3
4namespace mp {
5
6
7const short system::EVFILT_MAP[3] = {0, EVFILT_READ, EVFILT_WRITE};
8
9system::system()
10{
11        m_kqfd = kqueue();
12}
13
14system::backlog::backlog() : count(0), num(0) {}
15
16
17int system::add(int fd, short event)
18{
19        if( event == EV_READ | EV_WRITE ) {
20                struct kevent kev[2];
21                EV_SET(&kev[0], fd, EVFILT_READ,  EV_ADD, 0, 0, NULL);
22                EV_SET(&kev[1], fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
23                return kevent(m_kqfd, kev, 2, NULL, 0, NULL);
24        }
25        struct kevent kev;
26        EV_SET(&kev, fd, EVFILT_MAP[event], EV_ADD, 0, 0, NULL);
27        return kevent(m_kqfd, &kev, 1, NULL, 0, NULL);
28}
29
30int system::remove(int fd, short oldevent)
31{
32        if( oldevent == EV_READ | EV_WRITE ) {
33                struct kevent kev[2];
34                EV_SET(&kev[0], fd, EVFILT_READ,  EV_DELETE, 0, 0, NULL);
35                EV_SET(&kev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
36                return kevent(m_kqfd, kev, 2, NULL, 0, NULL);
37        }
38        struct kevent kev;
39        EV_SET(&kev, fd, EVFILT_MAP[oldevent], EV_DELETE, 0, 0, NULL);
40        return kevent(m_kqfd, &kev, 1, NULL, 0, NULL);
41}
42
43int system::modify(int fd, short oldevent, short newevent)
44{
45        short add_event = ~oldevent & newevent;
46        struct kevent kev;
47        if( add_event ) {
48                EV_SET(&kev, fd, EVFILT_MAP[add_event], EV_ADD, 0, 0, NULL);
49        } else {
50                short delete_event = oldevent & ~newevent;
51                EV_SET(&kev, fd, EVFILT_MAP[delete_event], EV_DELETE, 0, 0, NULL);
52        }
53        return kevent(m_kqfd, &kev, 1, NULL, 0, NULL);
54}
55
56int system::wait()
57{
58        m_backlog.count = 0;
59        return m_backlog.num = kevent(m_kqfd, NULL, 0, m_backlog.results, MP_EVENT_KQUEUE_MAX_RESULT, NULL);
60}
61
62int system::wait(int timeout_msec)
63{
64        struct timespec ts;
65        ts.tv_sec  = timeout_msec / 1000;
66        ts.tv_nsec = (timeout_msec % 1000) * 1000000;
67        m_backlog.count = 0;
68        return m_backlog.num = kevent(m_kqfd, NULL, 0, m_backlog.results, MP_EVENT_KQUEUE_MAX_RESULT, &ts);
69}
70
71bool system::next(int* rfd, short* revent)
72{
73        if( m_backlog.count >= m_backlog.num ) { return false; }
74        struct kevent* const kev = &m_backlog.results[m_backlog.count];
75        ++m_backlog.count;
76        *rfd = kev->ident;
77        *revent = kev->filter;
78        return true;
79}
80
81
82}  // namespace mp
83
84#endif /* mp/system/kqueue_impl.h */
85
Note: See TracBrowser for help on using the browser.