feat(kernel): wake tasks on service registration #268
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Depends on #267
Currently, the
Registry::connect_*
methods return an error immediatelyif the requested service is not found in the registry. Most client types
implement a
from_registry
method which retry in a loop when therequested service is not found in the registry. These methods will wait
for a fixed (short) amount of time and then try again until the registry
returns the service.
This approach is quite inefficient, as we have to run a bunch of retry
loops that keep trying to access a service that may not be there. This
may happen several times before the service actually is registered,
especially when registering a service requires connecting to another
service.
This branch improves the efficiency of waiting for a service to be
registered. Now, rather than retrying with a fixed-duration sleep, we
instead have the
Registry
own aWaitCell
which is woken whenever anew service is registered. This wakes all takes potentially waiting to
connect, allowing them to re-check whether the service they want is in
the registry. This idea was initially proposed by @jamesmunns in a
comment on PR #259
Connections are now established using either
Registry::connect
, whichretries whenever a new service is registered, or
Registry::try_connect
which never retries.
Additionally, we now have the capacity to indicate that a service is not
found and that the registry is full, by closing the
WaitCell
. Inthis case, retrying will never succeed, because the registry is full and
if the service isn't already there, it will never be added. In this
case, the retrying methods will also return an error, rather than never
completing, so we avoid a potential task leak.
In order to make this change, we need to move the
RwLock
from beingaround the entire
Registry
to being inside the registry, arounditems
. This allows theWaitCell
to be accessed regardless. It alsoallows us to shorten the duration for which the lock is held. This
requires changing all methods on
Registry
to take&self
.Therefore, I've removed the wrapper methods on
Kernel
for connectingand registering, since they can now just be called on
kernel.registry
without a bunch of extra boilerplate for lock management. I've also
simplified the API surface of the registry a bit by removing the
connect
methods that don't take aHello
, and just usingRegistry::connect(())
in those cases. IMO, those methods weren'treally pulling their weight, and they required us to have a method named
Registry::try_connect_userspace_with_hello
if we were going to add anon-retrying
connect
variant. Now, we can just haveRegistry::try_connect_userspace
,Registry::connect_userspace
,Registry::connect
, andRegistry::try_connect
, which feels much lessegregious.