diff --git a/src/event.cpp b/src/event.cpp
new file mode 100644
index 0000000..e9c11af
--- /dev/null
+++ b/src/event.cpp
@@ -0,0 +1,176 @@
+#include <sys/eventfd.h>
+
+#include <sdbusplus/event.hpp>
+#include <sdbusplus/exception.hpp>
+
+namespace sdbusplus::event
+{
+
+source::source(source&& s)
+{
+    if (&s == this)
+    {
+        return;
+    }
+    ev = std::exchange(s.ev, nullptr);
+    sourcep = std::exchange(s.sourcep, nullptr);
+}
+
+source& source::operator=(source&& s)
+{
+    if (nullptr != sourcep)
+    {
+        auto l = ev->obtain_lock();
+        sd_event_source_unref(sourcep);
+    }
+    ev = std::exchange(s.ev, nullptr);
+    sourcep = std::exchange(s.sourcep, nullptr);
+
+    return *this;
+}
+
+source::~source()
+{
+    if (nullptr != sourcep)
+    {
+        auto l = ev->obtain_lock();
+        sd_event_source_unref(sourcep);
+    }
+}
+
+condition::condition(condition&& c)
+{
+    if (&c == this)
+    {
+        return;
+    }
+
+    condition_source = std::move(c.condition_source);
+    fd = std::exchange(c.fd, -1);
+}
+
+condition& condition::operator=(condition&& c)
+{
+    condition_source = std::move(c.condition_source);
+    if (fd >= 0)
+    {
+        close(fd);
+    }
+    fd = std::exchange(c.fd, -1);
+
+    return *this;
+}
+
+void condition::signal()
+{
+    uint64_t value = 1;
+    auto rc = write(fd, &value, sizeof(value));
+    if (rc < static_cast<decltype(rc)>(sizeof(value)))
+    {
+        throw exception::SdBusError(errno, __func__);
+    }
+}
+
+void condition::ack()
+{
+    uint64_t value = 0;
+    auto rc = read(fd, &value, sizeof(value));
+    if (rc < static_cast<decltype(rc)>(sizeof(value)))
+    {
+        throw exception::SdBusError(errno, __func__);
+    }
+}
+
+event::event()
+{
+    if (auto rc = sd_event_new(&eventp); rc < 0)
+    {
+        throw exception::SdBusError(-rc, __func__);
+    }
+    run_condition = add_condition(run_wakeup, this);
+}
+
+void event::run_one(std::chrono::microseconds timeout)
+{
+    auto l = obtain_lock<false>();
+
+    auto rc = sd_event_run(eventp, static_cast<uint64_t>(timeout.count()));
+    if (rc < 0)
+    {
+        throw exception::SdBusError(-rc, __func__);
+    }
+}
+
+void event::break_run()
+{
+    run_condition.signal();
+}
+
+source event::add_io(int fd, uint32_t events, sd_event_io_handler_t handler,
+                     void* data)
+{
+    auto l = obtain_lock();
+
+    source s{*this};
+
+    auto rc = sd_event_add_io(eventp, &s.sourcep, fd, events, handler, data);
+    if (rc < 0)
+    {
+        throw exception::SdBusError(-rc, __func__);
+    }
+
+    return s;
+}
+
+condition event::add_condition(sd_event_io_handler_t handler, void* data)
+{
+    // We don't need any locks here because we only touch the sd_event
+    // indirectly through `add_io` which handles its own locking.
+
+    auto fd = eventfd(0, 0);
+    if (fd < 0)
+    {
+        throw exception::SdBusError(errno, __func__);
+    }
+
+    try
+    {
+        auto io = add_io(fd, EPOLLIN, handler, data);
+        return {std::move(io), std::move(fd)};
+    }
+    catch (...)
+    {
+        close(fd);
+        throw;
+    }
+}
+
+int event::run_wakeup(sd_event_source*, int, uint32_t, void* data)
+{
+    auto self = static_cast<event*>(data);
+    self->run_condition.ack();
+
+    return 0;
+}
+
+template <bool Signal>
+std::unique_lock<std::recursive_mutex> event::obtain_lock()
+{
+    std::unique_lock<std::recursive_mutex> l{this->lock, std::defer_lock_t()};
+    if constexpr (Signal)
+    {
+        if (!l.try_lock())
+        {
+            run_condition.signal();
+            l.lock();
+        }
+    }
+    else
+    {
+        l.lock();
+    }
+
+    return l;
+}
+
+} // namespace sdbusplus::event
