13fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton//===--------------------- KQueue.cpp ---------------------------*- C++ -*-===//
23fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton//
33fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton//                     The LLVM Compiler Infrastructure
43fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton//
53fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton// This file is distributed under the University of Illinois Open Source
63fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton// License. See LICENSE.TXT for details.
73fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton//
83fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton//===----------------------------------------------------------------------===//
93fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
103fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton#include "KQueue.h"
113fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
123fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton#ifdef LLDB_USE_KQUEUES
133fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
143fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton#include "lldb/Core/Error.h"
153fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
163fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton#include "Utility/TimeSpecTimeout.h"
173fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
183fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Claytonusing namespace lldb_private;
193fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
203fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Claytonint
213fb2c93fdab778e3da7e340ae13f06678ef71db2Greg ClaytonKQueue::GetFD (bool can_create)
223fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton{
233fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    if (!IsValid () && can_create)
243fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        m_fd = kqueue();
253fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    return m_fd;
263fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton}
273fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
283fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Claytonint
293fb2c93fdab778e3da7e340ae13f06678ef71db2Greg ClaytonKQueue::Close ()
303fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton{
313fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    const int fd = m_fd;
323fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    if (fd >= 0)
333fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    {
343fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        m_fd = -1;
353fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        return close(fd);
363fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    }
373fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    return 0;
383fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton}
393fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
403fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Claytonint
413fb2c93fdab778e3da7e340ae13f06678ef71db2Greg ClaytonKQueue::WaitForEvents (struct kevent *events, int num_events, Error &error, uint32_t timeout_usec)
423fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton{
433fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    const int fd_kqueue = GetFD(false);
443fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    if (fd_kqueue >= 0)
453fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    {
463fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        TimeSpecTimeout timeout;
473fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        const struct timespec *timeout_ptr = timeout.SetRelativeTimeoutMircoSeconds32 (timeout_usec);
483fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        int result = ::kevent(fd_kqueue, NULL, 0, events, num_events, timeout_ptr);
493fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        if (result == -1)
503fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton            error.SetErrorToErrno();
513fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        else
523fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton            error.Clear();
533fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        return result;
543fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    }
553fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    else
563fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    {
573fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        error.SetErrorString("invalid kqueue fd");
583fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    }
593fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    return 0;
603fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton}
613fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
623fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Claytonbool
633fb2c93fdab778e3da7e340ae13f06678ef71db2Greg ClaytonKQueue::AddFDEvent (int fd, bool read, bool write, bool vnode)
643fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton{
653fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    const int fd_kqueue = GetFD(true);
663fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    if (fd_kqueue >= 0)
673fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    {
683fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        struct kevent event;
693fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        event.ident  = fd;
703fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        event.filter = 0;
713fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        if (read)
723fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton            event.filter |= EVFILT_READ;
733fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        if (write)
743fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton            event.filter |= EVFILT_WRITE;
753fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        if (vnode)
763fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton            event.filter |= EVFILT_VNODE;
773fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        event.flags  = EV_ADD | EV_CLEAR;
783fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        event.fflags = 0;
793fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        event.data   = 0;
803fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        event.udata  = NULL;
813fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        int err = ::kevent(fd_kqueue, &event, 1, NULL, 0, NULL);
823fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton        return err == 0;
833fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    }
843fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton    return false;
853fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton}
863fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton
873fb2c93fdab778e3da7e340ae13f06678ef71db2Greg Clayton#endif
88