Skip to content

[LLDB][SBProgress] Add a finalize method #128966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 3, 2025
Merged

Conversation

Jlalond
Copy link
Contributor

@Jlalond Jlalond commented Feb 26, 2025

This patch adds a finalize method which destroys the underlying RAII SBProgress. My primary motivation for this is so I can write better tests that are non-flaky, but after discussing with @clayborg in my DAP message improvement patch (#124648) this is probably an essential API despite that I originally argued it wasn't.

@Jlalond Jlalond requested a review from clayborg February 26, 2025 23:41
@llvmbot llvmbot added the lldb label Feb 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 26, 2025

@llvm/pr-subscribers-lldb

Author: Jacob Lalonde (Jlalond)

Changes

This patch adds a finalize method which destroys the underlying RAII SBProgress. My primary motivation for this is so I can write better tests that are non-flaky, but after discussing with @clayborg in my DAP message improvement patch (#124648) this is probably an essential API despite that I originally argued it wasn't.


Full diff: https://github.com/llvm/llvm-project/pull/128966.diff

4 Files Affected:

  • (modified) lldb/bindings/interface/SBProgressDocstrings.i (+7)
  • (modified) lldb/include/lldb/API/SBProgress.h (+5)
  • (modified) lldb/source/API/SBProgress.cpp (+14-1)
  • (modified) lldb/test/API/python_api/sbprogress/TestSBProgress.py (+14)
diff --git a/lldb/bindings/interface/SBProgressDocstrings.i b/lldb/bindings/interface/SBProgressDocstrings.i
index 2997fe619fcc7..50648b62411f8 100644
--- a/lldb/bindings/interface/SBProgressDocstrings.i
+++ b/lldb/bindings/interface/SBProgressDocstrings.i
@@ -12,3 +12,10 @@ and will always send an initial progress update, updates when
 Progress::Increment() is called, and also will make sure that a progress
 completed update is reported even if the user doesn't explicitly cause one
 to be sent.") lldb::SBProgress;
+
+%feature("docstring",
+"Explicitly end an SBProgress, this is a utility to send the progressEnd event
+without waiting for your language or language implementations non-deterministic destruction
+of the SBProgress object.
+
+Note once finalized, no further increments will be processed.") lldb::SBProgress::Finalize;
diff --git a/lldb/include/lldb/API/SBProgress.h b/lldb/include/lldb/API/SBProgress.h
index d574d1d2982b9..1558cdc08e080 100644
--- a/lldb/include/lldb/API/SBProgress.h
+++ b/lldb/include/lldb/API/SBProgress.h
@@ -59,6 +59,11 @@ class LLDB_API SBProgress {
 
   void Increment(uint64_t amount, const char *description = nullptr);
 
+  /// Explicitly finalize an SBProgress, this can be used to terminate a
+  /// progress on command instead of waiting for a garbage collection or other
+  /// finalizer.
+  void Finalize();
+
 protected:
   lldb_private::Progress &ref() const;
 
diff --git a/lldb/source/API/SBProgress.cpp b/lldb/source/API/SBProgress.cpp
index e67e289a60eff..4991d55ad0248 100644
--- a/lldb/source/API/SBProgress.cpp
+++ b/lldb/source/API/SBProgress.cpp
@@ -40,7 +40,20 @@ SBProgress::~SBProgress() = default;
 void SBProgress::Increment(uint64_t amount, const char *description) {
   LLDB_INSTRUMENT_VA(amount, description);
 
-  m_opaque_up->Increment(amount, description);
+  if (!m_opaque_up)
+    return;
+
+  std::optional<std::string> description_opt;
+  if (description && description[0])
+    description_opt = description;
+  m_opaque_up->Increment(amount, description_opt);
+}
+
+void SBProgress::Finalize() {
+  if (!m_opaque_up)
+    return;
+
+  m_opaque_up.reset();
 }
 
 lldb_private::Progress &SBProgress::ref() const { return *m_opaque_up; }
diff --git a/lldb/test/API/python_api/sbprogress/TestSBProgress.py b/lldb/test/API/python_api/sbprogress/TestSBProgress.py
index c456247da80c6..dd7e4b6f2ac5c 100644
--- a/lldb/test/API/python_api/sbprogress/TestSBProgress.py
+++ b/lldb/test/API/python_api/sbprogress/TestSBProgress.py
@@ -33,3 +33,17 @@ def test_without_external_bit_set(self):
         expected_string = "Test progress first increment"
         progress.Increment(1, expected_string)
         self.assertFalse(listener.PeekAtNextEvent(event))
+
+    def test_progress_finalize(self):
+        """Test SBProgress finalize sends the progressEnd event"""
+
+        progress = lldb.SBProgress("Test SBProgress", "Test finalize", self.dbg)
+        listener = lldb.SBListener("Test listener")
+        broadcaster = self.dbg.GetBroadcaster()
+        broadcaster.AddListener(listener, lldb.eBroadcastBitExternalProgressCategory)
+        event = lldb.SBEvent()
+        progress.Finalize()
+        self.assertTrue(listener.WaitForEvent(5, event))
+        stream = lldb.SBStream()
+        event.GetDescription(stream)
+        self.assertIn("type = end", stream.GetData())

@Jlalond Jlalond changed the title [SBProgress Add a finalize method [LLDB][SBProgress] Add a finalize method Feb 26, 2025
@Jlalond Jlalond force-pushed the sbprogress-finalize branch from c461be5 to eb5d36f Compare February 26, 2025 23:56
@@ -12,3 +12,10 @@ and will always send an initial progress update, updates when
Progress::Increment() is called, and also will make sure that a progress
completed update is reported even if the user doesn't explicitly cause one
to be sent.") lldb::SBProgress;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets add some usage documentation here for both non-determinisitic and deterministic progress class usage in python here. That way people can see this and use the class as intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember this being 1:1 with Progress and not being changed so I would think we should add a new doc string to Increment. Is there anything in particular you want to call out? Many of the deterministic/non-deterministic are predominantly relevant to DAP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made an attempt at summarizing this in increment in manner that doesn't expose too much about the externals. Specifically so that it doesn't go out of date instantly.

broadcaster.AddListener(listener, lldb.eBroadcastBitExternalProgressCategory)
event = lldb.SBEvent()
progress.Finalize()
self.assertTrue(listener.WaitForEvent(5, event))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you have to wait for the first progress start event and also the end event here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope! Because we create the progress event before wiring up the listener we only listen for the end message.

@Jlalond Jlalond force-pushed the sbprogress-finalize branch from d43f471 to 143e4da Compare February 27, 2025 19:21
@Jlalond Jlalond force-pushed the sbprogress-finalize branch from c8eab8a to 213d685 Compare February 27, 2025 19:53
@Jlalond Jlalond merged commit 3ff6fb6 into llvm:main Mar 3, 2025
10 checks passed
@Jlalond Jlalond deleted the sbprogress-finalize branch March 7, 2025 19:19
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
This patch adds a finalize method which destroys the underlying RAII
SBProgress. My primary motivation for this is so I can write better
tests that are non-flaky, but after discussing with @clayborg in my DAP
message improvement patch (llvm#124648) this is probably an essential API
despite that I originally argued it wasn't.
Jlalond added a commit that referenced this pull request Mar 29, 2025
We recently added an explicit finalize to SBProgress, #128966. I
realized while adding some additional implementations of SBProgress that
we should to add `with` support for ease of use. This patch addresses
adding and `__enter()__` method (which a no-op) and an `__exit()__` to
swig. I also refactor the emitter for the test to leverage `with`
instead of explicitly calling finalize, and I've updated the docstrings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants