Changes for v2:

- Add locking for dwfltab.

* * *

New function that retrieves the Dwfl for a particular PID, or,
if the Dwfl is absent, creates it via a provided callback
and adds it to the table later, when the PID is confirmed
via dwfl_attach_state.

* libdwfl/libdwfl.h (dwfl_process_tracker_find_pid): New function.
* libdwfl/dwfl_process_tracker.h (dwfl_process_tracker_find_pid):
  New function; find a Dwfl in the dwfltab or create one using the
  provided callback.  The newly created Dwfl will be added to the
  dwfltab automatically when its pid is confirmed by a call to
  dwfl_attach_state.
* libdw/libdw.map: Add dwfl_process_tracker_find_pid.
---
 libdw/libdw.map                |  1 +
 libdwfl/dwfl_process_tracker.c | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/libdw/libdw.map b/libdw/libdw.map
index 77be3906..489d0a8f 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -398,4 +398,5 @@ ELFUTILS_0.193 {
     dwfl_process_tracker_cache_elf;
     dwfl_module_gettracker;
     dwfl_process_tracker_find_elf;
+    dwfl_process_tracker_find_pid;
 } ELFUTILS_0.192;
diff --git a/libdwfl/dwfl_process_tracker.c b/libdwfl/dwfl_process_tracker.c
index 200b622b..e473ebd7 100644
--- a/libdwfl/dwfl_process_tracker.c
+++ b/libdwfl/dwfl_process_tracker.c
@@ -67,6 +67,32 @@ Dwfl *dwfl_begin_with_tracker (Dwfl_Process_Tracker *tracker)
   return dwfl;
 }
 
+Dwfl *dwfl_process_tracker_find_pid (Dwfl_Process_Tracker *tracker,
+                                    pid_t pid,
+                                    Dwfl *(*callback) (Dwfl_Process_Tracker *,
+                                                       pid_t, void *),
+                                    void *arg)
+{
+  Dwfl *dwfl = NULL;
+
+  rwlock_rdlock (tracker->dwfltab_lock);
+  dwfltracker_dwfl_info *ent = dwfltracker_dwfltab_find(&tracker->dwfltab, 
pid);
+  rwlock_unlock (tracker->dwfltab_lock);
+
+  if (ent != NULL && !ent->invalid)
+    dwfl = ent->dwfl;
+  if (dwfl == NULL && callback != NULL)
+    dwfl = callback(tracker, pid, arg);
+  if (dwfl != NULL)
+    {
+      assert (dwfl->tracker == tracker);
+      /* XXX: dwfl added to dwfltab when dwfl->process set in 
dwfl_attach_state.
+         Prior to that, the pid is not confirmed. */
+    }
+
+  return dwfl;
+}
+
 void __libdwfl_add_dwfl_to_tracker (Dwfl *dwfl) {
   Dwfl_Process_Tracker *tracker = dwfl->tracker;
   assert (tracker != NULL);
-- 
2.47.0

Reply via email to