+ td_ta_clear_event_p = dlsym (thread_db->handle, "td_ta_clear_event");
+#else
+ td_ta_clear_event_p = &td_ta_clear_event;
+#endif
+
+ if (td_ta_clear_event_p != NULL)
+ {
+ struct thread_info *saved_inferior = current_inferior;
+ td_thr_events_t events;
+
+ switch_to_process (proc);
+
+ /* Set the process wide mask saying we aren't interested
+ in any events anymore. */
+ td_event_fillset (&events);
+ (*td_ta_clear_event_p) (thread_db->thread_agent, &events);
+
+ current_inferior = saved_inferior;
+ }
+ }
+}
+
+static void
+remove_thread_event_breakpoints (struct process_info *proc)
+{
+ struct thread_db *thread_db = proc->private->thread_db;
+
+ if (thread_db->td_create_bp != NULL)
+ {
+ struct thread_info *saved_inferior = current_inferior;
+
+ switch_to_process (proc);
+
+ delete_breakpoint (thread_db->td_create_bp);
+ thread_db->td_create_bp = NULL;
+
+ current_inferior = saved_inferior;
+ }
+}
+
+void
+thread_db_detach (struct process_info *proc)
+{
+ struct thread_db *thread_db = proc->private->thread_db;
+
+ if (thread_db)
+ {
+ disable_thread_event_reporting (proc);
+ remove_thread_event_breakpoints (proc);
+ }
+}
+
+/* Disconnect from libthread_db and free resources. */
+
+void
+thread_db_mourn (struct process_info *proc)
+{
+ struct thread_db *thread_db = proc->private->thread_db;
+ if (thread_db)
+ {