Skip to content

Commit

Permalink
message: Add some explanatory comments
Browse files Browse the repository at this point in the history
  • Loading branch information
matheusd committed Jul 31, 2024
1 parent 531af00 commit 7beaec0
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
18 changes: 14 additions & 4 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const maxDepth = ^uint(0)
// A Message is a tree of Cap'n Proto objects, split into one or more
// segments of contiguous memory. The only required field is Arena.
// A Message is safe to read from multiple goroutines.
//
// A message must be set up with a fully valid Arena when reading or with
// a valid and empty arena by calling NewArena.
type Message struct {
// rlimit must be first so that it is 64-bit aligned.
// See sync/atomic docs.
Expand Down Expand Up @@ -60,6 +63,9 @@ type Message struct {

// NewMessage creates a message with a new root and returns the first
// segment. It is an error to call NewMessage on an arena with data in it.
//
// The new message is guaranteed to contain at least one segment and that
// segment is guaranteed to contain enough space for the root struct pointer.
func NewMessage(arena Arena) (*Message, *Segment, error) {
var msg Message
first, err := msg.Reset(arena)
Expand Down Expand Up @@ -93,10 +99,14 @@ func (m *Message) Release() {
m.Reset(nil)
}

// Reset the message to use a different arena, allowing it
// to be reused. This invalidates any existing pointers in
// the Message, releases all clients in the cap table, and
// releases the current Arena, so use with caution.
// Reset the message to use a different arena, allowing it to be reused. This
// invalidates any existing pointers in the Message, releases all clients in
// the cap table, and releases the current Arena, so use with caution.
//
// Reset fails if the new arena is not empty and is not able to allocate enough
// space for at least one segment and its root pointer. In other words, Reset
// with a non-nil arena must only be used for messages which will be modified,
// not read.
func (m *Message) Reset(arena Arena) (first *Segment, err error) {
m.capTable.Reset()
for k := range m.segs {
Expand Down
2 changes: 2 additions & 0 deletions segment.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ func (s *Segment) writePtr(off address, src Ptr, forceCopy bool) error {
return nil
case hasCapacity(src.seg.data, wordSize):
// Enough room adjacent to src to write a far pointer landing pad.
// TODO: instead of alloc (which may choose another segment),
// enforce to _always_ use seg (because we know it has capacity).
_, padAddr, _ := alloc(src.seg, wordSize)
src.seg.writeRawPointer(padAddr, srcRaw.withOffset(nearPointerOffset(padAddr, srcAddr)))
s.writeRawPointer(off, rawFarPointer(src.seg.id, padAddr))
Expand Down

0 comments on commit 7beaec0

Please sign in to comment.