Skip to content
davidhubbard edited this page Nov 15, 2023 · 8 revisions

⚠️ NOTE: This page is WIP. All the essential information is there, but we really ought to make it more digestible. If something doesn't make sense, please don't give up. Drop us a line, instead!

Rules for Ref Counting

  1. Each reference to a capability has an "owner." The owner is responsible for calling .Release() on the reference when it is no longer needed.
  2. Generated Foo_ServerToClient methods return a capability reference owned by the caller.
  3. The .AddRef() method returns a new reference to the same underlying capability, which is owned by the caller.
  4. Calling foo.Bar(baz) where foo and baz are capabilities transfers ownership of baz to foo. The foo instance will call baz.Release() when finished.
  5. Capabilities received as arguments to an RPC handler are borrowed and will be released when the RPC handler returns. Calling AddRef() returns a capability (owned by the caller) that may persist beyond the scope of the RPC handler, per rule 3.
  6. Capabilities returned by a method call are owned by the results struct, and live until that call's ReleaseFunc is invoked.

Special Cases

  1. [ BUG ] Passing the last reference for a capability to itself causes a deadlock.

Brief Go Reference Counting Diversion

Golang already handles object reference counting and garbage-collecting them after they are not used any more.

Capnproto adds to that by closely tying state to the Actor in Actor Model theory and explicitly garbage collecting it. This helps debuggability.