source/base: Support automatically configuring userdata

This makes callbacks work correctly as the systemd callback functions
need to know where to look for the object storing the real callback.
diff --git a/src/sdeventplus/internal/sdevent.hpp b/src/sdeventplus/internal/sdevent.hpp
index be8e0a8..7713cb8 100644
--- a/src/sdeventplus/internal/sdevent.hpp
+++ b/src/sdeventplus/internal/sdevent.hpp
@@ -36,6 +36,9 @@
     virtual sd_event_source*
         sd_event_source_unref(sd_event_source* source) const = 0;
 
+    virtual void* sd_event_source_set_userdata(sd_event_source* source,
+                                               void* userdata) const = 0;
+
     virtual int
         sd_event_source_get_description(sd_event_source* source,
                                         const char** description) const = 0;
@@ -141,6 +144,12 @@
         return ::sd_event_source_unref(source);
     }
 
+    void* sd_event_source_set_userdata(sd_event_source* source,
+                                       void* userdata) const override
+    {
+        return ::sd_event_source_set_userdata(source, userdata);
+    }
+
     int sd_event_source_get_description(sd_event_source* source,
                                         const char** description) const override
     {
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
index 94a5628..83908d1 100644
--- a/src/sdeventplus/source/base.cpp
+++ b/src/sdeventplus/source/base.cpp
@@ -163,6 +163,7 @@
     source(source, &internal::SdEvent::sd_event_source_ref,
            &internal::SdEvent::sd_event_source_unref, event.getSdEvent())
 {
+    set_userdata();
 }
 
 Base::Base(const Event& event, sd_event_source* source, std::false_type) :
@@ -170,6 +171,14 @@
                          &internal::SdEvent::sd_event_source_unref,
                          std::false_type(), event.getSdEvent())
 {
+    set_userdata();
+}
+
+Base::Base(Base&& other) :
+    event(std::move(other.event)), source(std::move(other.source)),
+    prepare(std::move(other.prepare))
+{
+    set_userdata();
 }
 
 Base& Base::operator=(Base&& other)
@@ -186,9 +195,16 @@
         event = std::move(other.event);
         source = std::move(other.source);
         prepare = std::move(other.prepare);
+
+        set_userdata();
     }
     return *this;
 }
 
+void Base::set_userdata()
+{
+    event.getSdEvent()->sd_event_source_set_userdata(source.get(), this);
+}
+
 } // namespace source
 } // namespace sdeventplus
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
index d576b24..ed30016 100644
--- a/src/sdeventplus/source/base.hpp
+++ b/src/sdeventplus/source/base.hpp
@@ -47,11 +47,13 @@
     Base(const Base& other) = delete;
     Base& operator=(const Base& other) = delete;
     // We don't want to allow any kind of slicing.
-    Base(Base&& other) = default;
+    Base(Base&& other);
     Base& operator=(Base&& other);
 
   private:
     Callback prepare;
+
+    void set_userdata();
 };
 
 } // namespace source
diff --git a/src/sdeventplus/test/sdevent.hpp b/src/sdeventplus/test/sdevent.hpp
index fd05b30..9b39d50 100644
--- a/src/sdeventplus/test/sdevent.hpp
+++ b/src/sdeventplus/test/sdevent.hpp
@@ -34,6 +34,9 @@
     MOCK_CONST_METHOD1(sd_event_source_unref,
                        sd_event_source*(sd_event_source*));
 
+    MOCK_CONST_METHOD2(sd_event_source_set_userdata,
+                       void*(sd_event_source*, void*));
+
     MOCK_CONST_METHOD2(sd_event_source_get_description,
                        int(sd_event_source*, const char**));
     MOCK_CONST_METHOD2(sd_event_source_set_description,
diff --git a/test/source/base.cpp b/test/source/base.cpp
index 0ca093b..69ae8e2 100644
--- a/test/source/base.cpp
+++ b/test/source/base.cpp
@@ -65,7 +65,11 @@
     {
         EXPECT_CALL(mock, sd_event_ref(event.get()))
             .WillOnce(Return(event.get()));
+        void* userdata;
+        EXPECT_CALL(mock, sd_event_source_set_userdata(source, testing::_))
+            .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
         auto ret = std::make_unique<BaseImpl>(event, source, std::false_type());
+        EXPECT_EQ(ret.get(), userdata);
         EXPECT_EQ(source, ret->get());
         EXPECT_NE(&event, &ret->get_event());
         EXPECT_EQ(event.get(), ret->get_event().get());
@@ -83,7 +87,11 @@
 
     void empty_base(BaseImpl&& other)
     {
+        void* userdata;
+        EXPECT_CALL(mock, sd_event_source_set_userdata(other.get(), testing::_))
+            .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
         BaseImpl mover(std::move(other));
+        EXPECT_EQ(&mover, userdata);
         EXPECT_EQ(nullptr, other.get());
         EXPECT_EQ(nullptr, other.get_event().get());
         EXPECT_FALSE(other.get_prepare());
@@ -111,7 +119,11 @@
         .WillOnce(Return(expected_event));
     EXPECT_CALL(mock, sd_event_source_ref(expected_source))
         .WillOnce(Return(expected_source));
+    void* userdata;
+    EXPECT_CALL(mock, sd_event_source_set_userdata(expected_source, testing::_))
+        .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
     BaseImpl source(*event, expected_source);
+    EXPECT_EQ(&source, userdata);
     EXPECT_EQ(expected_source, source.get());
     EXPECT_NE(event.get(), &source.get_event());
     EXPECT_EQ(expected_event, source.get_event().get());
@@ -124,7 +136,11 @@
 {
     EXPECT_CALL(mock, sd_event_ref(expected_event))
         .WillOnce(Return(expected_event));
+    void* userdata;
+    EXPECT_CALL(mock, sd_event_source_set_userdata(expected_source, testing::_))
+        .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
     BaseImpl source(*event, expected_source, std::false_type());
+    EXPECT_EQ(&source, userdata);
     EXPECT_EQ(expected_source, source.get());
     EXPECT_NE(event.get(), &source.get_event());
     EXPECT_EQ(expected_event, source.get_event().get());
@@ -138,7 +154,11 @@
     std::unique_ptr<BaseImpl> source1 = make_base(*event, expected_source);
     set_prepare_placeholder(*source1);
 
+    void* userdata;
+    EXPECT_CALL(mock, sd_event_source_set_userdata(expected_source, testing::_))
+        .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
     BaseImpl source2(std::move(*source1));
+    EXPECT_EQ(&source2, userdata);
     EXPECT_EQ(nullptr, source1->get());
     EXPECT_EQ(nullptr, source1->get_event().get());
     EXPECT_FALSE(source1->get_prepare());
@@ -171,8 +191,12 @@
     empty_base(std::move(*source2));
 
     {
-        testing::InSequence seq;
+        void* userdata;
+        EXPECT_CALL(mock,
+                    sd_event_source_set_userdata(expected_source, testing::_))
+            .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
         *source2 = std::move(*source1);
+        EXPECT_EQ(source2.get(), userdata);
     }
     EXPECT_EQ(nullptr, source1->get());
     EXPECT_EQ(nullptr, source1->get_event().get());
@@ -200,7 +224,12 @@
 
     {
         expect_base_destruct(*event2, expected_source2);
+        void* userdata;
+        EXPECT_CALL(mock,
+                    sd_event_source_set_userdata(expected_source, testing::_))
+            .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
         *source2 = std::move(*source1);
+        EXPECT_EQ(source2.get(), userdata);
     }
     EXPECT_EQ(nullptr, source1->get());
     EXPECT_EQ(nullptr, source1->get_event().get());