1//===--------------------- KQueue.cpp ---------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "KQueue.h"
11
12#ifdef LLDB_USE_KQUEUES
13
14#include "lldb/Core/Error.h"
15
16#include "Utility/TimeSpecTimeout.h"
17
18using namespace lldb_private;
19
20int
21KQueue::GetFD (bool can_create)
22{
23    if (!IsValid () && can_create)
24        m_fd = kqueue();
25    return m_fd;
26}
27
28int
29KQueue::Close ()
30{
31    const int fd = m_fd;
32    if (fd >= 0)
33    {
34        m_fd = -1;
35        return close(fd);
36    }
37    return 0;
38}
39
40int
41KQueue::WaitForEvents (struct kevent *events, int num_events, Error &error, uint32_t timeout_usec)
42{
43    const int fd_kqueue = GetFD(false);
44    if (fd_kqueue >= 0)
45    {
46        TimeSpecTimeout timeout;
47        const struct timespec *timeout_ptr = timeout.SetRelativeTimeoutMircoSeconds32 (timeout_usec);
48        int result = ::kevent(fd_kqueue, NULL, 0, events, num_events, timeout_ptr);
49        if (result == -1)
50            error.SetErrorToErrno();
51        else
52            error.Clear();
53        return result;
54    }
55    else
56    {
57        error.SetErrorString("invalid kqueue fd");
58    }
59    return 0;
60}
61
62bool
63KQueue::AddFDEvent (int fd, bool read, bool write, bool vnode)
64{
65    const int fd_kqueue = GetFD(true);
66    if (fd_kqueue >= 0)
67    {
68        struct kevent event;
69        event.ident  = fd;
70        event.filter = 0;
71        if (read)
72            event.filter |= EVFILT_READ;
73        if (write)
74            event.filter |= EVFILT_WRITE;
75        if (vnode)
76            event.filter |= EVFILT_VNODE;
77        event.flags  = EV_ADD | EV_CLEAR;
78        event.fflags = 0;
79        event.data   = 0;
80        event.udata  = NULL;
81        int err = ::kevent(fd_kqueue, &event, 1, NULL, 0, NULL);
82        return err == 0;
83    }
84    return false;
85}
86
87#endif
88