From f2f0fa7fd0efc221f1358dd4e440b5d51a5fb8b4 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 18 Jul 2024 13:29:34 -0400
Subject: Ditch `LLEventTrackable` aka `boost::signals2::trackable`.

Remove documented `LLEventPump` support for `LLEventTrackable`. That claimed
support was always a little bit magical/fragile. IF:

* a class included `LLEventTrackable` as a base class AND
* an instance of that class was managed by `boost::shared_ptr` AND
* you passed one of that class's methods and the `boost::shared_ptr`
  specifically to `boost::bind()` AND
* the resulting `boost::bind()` object was passed into `LLEventPump::listen()`

THEN the promise was that on destruction of that object, that listener would
automatically be disconnected -- instead of leaving a dangling pointer bound
into the `LLEventPump`, causing a crash on the next `LLEventPump::post()` call.

The only existing code in the viewer code base that exercised `LLEventTrackable`
functionality was in test programs. When the viewer calls `LLEventPump::listen()`,
it typically stores the resulting connection object in an `LLTempBoundListener`
variable, which guarantees disconnection on destruction of that variable.

The fact that `LLEventTrackable` support is specific to `boost::bind()`, that it
silently fails to keep its promise with `std::bind()` or a lambda or any other
form of C++ callable, makes it untrustworthy for new code.

Note that the code base still uses `boost::signals2::trackable` for other
`boost::signals2::signal` instances not associated with `LLEventPump`. We are
not changing those at this time.
---
 indra/test/llevents_tut.cpp | 58 +--------------------------------------------
 1 file changed, 1 insertion(+), 57 deletions(-)

(limited to 'indra/test/llevents_tut.cpp')

diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp
index 875ca9ad89..f9cc99203b 100644
--- a/indra/test/llevents_tut.cpp
+++ b/indra/test/llevents_tut.cpp
@@ -429,7 +429,7 @@ void events_object::test<9>()
 {
     set_test_name("listen(boost::bind(...TempListener...))");
     // listen() can't do anything about a plain TempListener instance:
-    // it's not managed with shared_ptr, nor is it an LLEventTrackable subclass
+    // it's not managed with shared_ptr
     bool live = false;
     LLEventPump& heaptest(pumps.obtain("heaptest"));
     LLBoundListener connection;
@@ -453,60 +453,4 @@ void events_object::test<9>()
     heaptest.stopListening("temp");
 }
 
-class TempTrackableListener: public TempListener, public LLEventTrackable
-{
-public:
-    TempTrackableListener(const std::string& name, bool& liveFlag):
-        TempListener(name, liveFlag)
-    {}
-};
-
-template<> template<>
-void events_object::test<10>()
-{
-    set_test_name("listen(boost::bind(...TempTrackableListener ref...))");
-    bool live = false;
-    LLEventPump& heaptest(pumps.obtain("heaptest"));
-    LLBoundListener connection;
-    {
-        TempTrackableListener tempListener("temp", live);
-        ensure("TempTrackableListener constructed", live);
-        connection = heaptest.listen(tempListener.getName(),
-                                     boost::bind(&TempTrackableListener::call,
-                                                 boost::ref(tempListener), _1));
-        heaptest.post(1);
-        check_listener("received", tempListener, 1);
-    } // presumably this will make tempListener go away?
-    // verify that
-    ensure("TempTrackableListener destroyed", ! live);
-    ensure("implicit disconnect", ! connection.connected());
-    // now just make sure we don't blow up trying to access a freed object!
-    heaptest.post(2);
-}
-
-template<> template<>
-void events_object::test<11>()
-{
-    set_test_name("listen(boost::bind(...TempTrackableListener pointer...))");
-    bool live = false;
-    LLEventPump& heaptest(pumps.obtain("heaptest"));
-    LLBoundListener connection;
-    {
-        TempTrackableListener* newListener(new TempTrackableListener("temp", live));
-        ensure("TempTrackableListener constructed", live);
-        connection = heaptest.listen(newListener->getName(),
-                                     boost::bind(&TempTrackableListener::call,
-                                                 newListener, _1));
-        heaptest.post(1);
-        check_listener("received", *newListener, 1);
-        // explicitly destroy newListener
-        delete newListener;
-    }
-    // verify that
-    ensure("TempTrackableListener destroyed", ! live);
-    ensure("implicit disconnect", ! connection.connected());
-    // now just make sure we don't blow up trying to access a freed object!
-    heaptest.post(2);
-}
-
 } // namespace tut
-- 
cgit v1.2.3