+2021-02-04  Simon Marchi  <simon.marchi@efficios.com>
+
+       * async-event.h (async_event_handler_func):  Add documentation.
+       * async-event.c (check_async_event_handlers): Don't clear
+       async_event_handler ready flag.
+       * infrun.c (infrun_async_inferior_event_handler): Clear ready
+       flag.
+       * record-btrace.c (record_btrace_handle_async_inferior_event):
+       Likewise.
+       * record-full.c (record_full_async_inferior_event_handler):
+       Likewise.
+       * remote-notif.c (remote_async_get_pending_events_handler):
+       Likewise.
+       * remote.c (remote_async_inferior_event_handler): Likewise.
+
 2021-02-03  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * infrun.c (handle_inferior_event): Move stop_soon variable to
 
     {
       if (async_handler_ptr->ready)
        {
-         async_handler_ptr->ready = 0;
          event_loop_debug_printf ("invoking async event handler `%s`",
                                   async_handler_ptr->name);
          (*async_handler_ptr->proc) (async_handler_ptr->client_data);
 
 struct async_signal_handler;
 struct async_event_handler;
 typedef void (sig_handler_func) (gdb_client_data);
+
+/* Type of async event handler callbacks.
+
+   DATA is the client data originally passed to create_async_event_handler.
+
+   The callback is called when the async event handler is marked.  The callback
+   is responsible for clearing the async event handler if it no longer needs
+   to be called.  */
+
 typedef void (async_event_handler_func) (gdb_client_data);
 
 extern struct async_signal_handler *
 
 static void
 infrun_async_inferior_event_handler (gdb_client_data data)
 {
+  clear_async_event_handler (infrun_async_inferior_event_token);
   inferior_event_handler (INF_REG_EVENT);
 }
 
 
 static void
 record_btrace_handle_async_inferior_event (gdb_client_data data)
 {
+  clear_async_event_handler (record_btrace_async_inferior_event_handler);
   inferior_event_handler (INF_REG_EVENT);
 }
 
 
 static void
 record_full_async_inferior_event_handler (gdb_client_data data)
 {
+  clear_async_event_handler (record_full_async_inferior_event_token);
   inferior_event_handler (INF_REG_EVENT);
 }
 
 
 static void
 remote_async_get_pending_events_handler (gdb_client_data data)
 {
+  remote_notif_state *notif_state = (remote_notif_state *) data;
+  clear_async_event_handler (notif_state->get_pending_events_token);
   gdb_assert (target_is_non_stop_p ());
-  remote_notif_process ((struct remote_notif_state *) data, NULL);
+  remote_notif_process (notif_state, NULL);
 }
 
 /* Remote notification handler.  Parse BUF, queue notification and
 
 static void
 remote_async_inferior_event_handler (gdb_client_data data)
 {
-  inferior_event_handler (INF_REG_EVENT);
-
   remote_target *remote = (remote_target *) data;
   remote_state *rs = remote->get_remote_state ();
+  clear_async_event_handler (rs->remote_async_inferior_event_token);
+
+  inferior_event_handler (INF_REG_EVENT);
 
   /* inferior_event_handler may have consumed an event pending on the
      infrun side without calling target_wait on the REMOTE target, or