Page MenuHome GnuPG

agent: Clean up main loop and better cache handling of expiration (was: Adding agent_timer API for monitoring something and passphrase cache)
Testing, WishlistPublic

Description

Let us improve the main loop, for better cache handling of expiration.

Originally, the task was described as follows:
-------------------------------

In gpg-agent, currently, we have handle_tick function.
It is basically for monitoring some events.
In T3829, handle_tick also handles passphrase cache expiration.

In GnuPG 2.2, it was used for watching scdaemon process. In GnuPG 2.4 and later, it is now done by a thread.

For passphrase cache expiration, the way of handle_tick is not ideal:

  • the timing for an action at expire is not that exact (depends on the interval)
  • it may be too often to be more exact

I'd like to propose introducing agent_timer_* internal API, to address this issue. Something like:

  • agent_timer_create
  • agent_timer_settime
  • agent_timer_delete

... so that gpg-agent can run only when needed, somehow exact and can sleep on select when no events or requests.

Event Timeline

gniibe triaged this task as Wishlist priority.Aug 24 2023, 4:37 AM
gniibe created this task.

I concluded that it's just simpler not to do so. Since expected use cases are only for passphrase cache expiration and some monitoring something, it would be overkill.

Having such an API for timer introduces serialization (mutual exclusion) problem between timer expiration callback and a thread which accesses the resource (of timer and some objects). Note that we will need to handle two things: timer and the object in question (passphrase cache, in this case). Having two things, when we use the locks, it's crucial to keep the order. Otherwise, it introduces a dead lock (or more).

It's better to use a thread for waiting passphrase expiration, then, it only cares the serialization of the resource itself (no concern about the timer).

Currently, I'm going to implement following:

  • keep using the select timeout for monitoring something
  • introduce new way for passphrase cache expiration
    • a lock variable for passphrase cache (already exists)
    • access routines to the cache with the lock
      • put to the cache
      • get from the cache
    • a thread for the expiration
      • wait for nearest expiration
      • on the expiration:
        • lock the resource
        • expire the entry in question
        • unlock the resource

This adds a lot of complexity to a program which should be simple. I tend to say, just accept a small(?) race condition in cache flushing. The power issue of waking up every minute or so is a constructed one and does not result in a noticeable battery drain in real life.

Firstly, I clean up the code with each individual thread for monitoring something; That's T6692 and T6693.
Then, I pushed rG76a2f180286e: agent: Better interaction between main loop and cache expiration. and rG92de0387f04b: agent: Introduce management of timer to expire cache entries.
No more use of tick, but timers.

gniibe renamed this task from agent: Adding agent_timer API for monitoring something and passphrase cache to agent: Clean up main loop and better cache handling of expiration (was: Adding agent_timer API for monitoring something and passphrase cache).Sep 1 2023, 4:57 AM
gniibe updated the task description. (Show Details)
gniibe changed the task status from Open to Testing.Sep 1 2023, 7:13 AM