Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
d07bf3b8
Commit
d07bf3b8
authored
Sep 29, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More capabilities core API WIP.
parent
398dac0d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
377 additions
and
26 deletions
+377
-26
arena.c++
c++/src/capnp/arena.c++
+60
-6
arena.h
c++/src/capnp/arena.h
+16
-5
capability-context.c++
c++/src/capnp/capability-context.c++
+64
-0
capability-context.h
c++/src/capnp/capability-context.h
+158
-0
capability.c++
c++/src/capnp/capability.c++
+5
-6
capability.h
c++/src/capnp/capability.h
+0
-0
layout.c++
c++/src/capnp/layout.c++
+16
-0
layout.h
c++/src/capnp/layout.h
+19
-4
object.h
c++/src/capnp/object.h
+34
-0
rpc.capnp
c++/src/capnp/rpc.capnp
+5
-5
No files found.
c++/src/capnp/arena.c++
View file @
d07bf3b8
...
...
@@ -24,10 +24,13 @@
#define CAPNP_PRIVATE
#include "arena.h"
#include "message.h"
#include "capability.h"
#include <kj/debug.h>
#include <vector>
#include <string.h>
#include <stdio.h>
#include "capability.h"
#include "capability-context.h"
namespace
capnp
{
namespace
_
{
// private
...
...
@@ -99,10 +102,42 @@ void BasicReaderArena::reportReadLimitReached() {
}
}
namespace
{
class
DummyClientHook
final
:
public
ClientHook
{
public
:
Request
<
ObjectPointer
,
TypelessAnswer
>
newCall
(
uint64_t
interfaceId
,
uint16_t
methodId
)
const
override
{
KJ_FAIL_REQUIRE
(
"Calling capability that was extracted from a message that had no "
"capability context."
);
}
kj
::
Promise
<
void
>
whenResolved
()
const
override
{
return
kj
::
READY_NOW
;
}
kj
::
Own
<
ClientHook
>
addRef
()
const
override
{
return
kj
::
heap
<
DummyClientHook
>
();
}
void
*
getBrand
()
const
override
{
return
nullptr
;
}
};
}
// namespace
kj
::
Own
<
ClientHook
>
BasicReaderArena
::
extractCap
(
const
_
::
StructReader
&
capDescriptor
)
{
KJ_FAIL_REQUIRE
(
"Message contained a capability but is not imbued with a capability context."
)
{
return
kj
::
heap
<
DummyClientHook
>
();
}
}
// =======================================================================================
ImbuedReaderArena
::
ImbuedReaderArena
(
Arena
*
base
)
:
base
(
base
),
segment0
(
nullptr
,
SegmentId
(
0
),
nullptr
,
nullptr
)
{}
ImbuedReaderArena
::
ImbuedReaderArena
(
Arena
*
base
,
CapExtractorBase
*
capExtractor
)
:
base
(
base
),
capExtractor
(
capExtractor
),
segment0
(
nullptr
,
SegmentId
(
0
),
nullptr
,
nullptr
)
{}
ImbuedReaderArena
::~
ImbuedReaderArena
()
noexcept
(
false
)
{}
SegmentReader
*
ImbuedReaderArena
::
imbue
(
SegmentReader
*
baseSegment
)
{
...
...
@@ -139,8 +174,6 @@ SegmentReader* ImbuedReaderArena::imbue(SegmentReader* baseSegment) {
return
result
;
}
// implements Arena ------------------------------------------------
SegmentReader
*
ImbuedReaderArena
::
tryGetSegment
(
SegmentId
id
)
{
return
imbue
(
base
->
tryGetSegment
(
id
));
}
...
...
@@ -149,6 +182,10 @@ void ImbuedReaderArena::reportReadLimitReached() {
return
base
->
reportReadLimitReached
();
}
kj
::
Own
<
ClientHook
>
ImbuedReaderArena
::
extractCap
(
const
_
::
StructReader
&
capDescriptor
)
{
return
capExtractor
->
extractCapInternal
(
capDescriptor
);
}
// =======================================================================================
BasicBuilderArena
::
BasicBuilderArena
(
MessageBuilder
*
message
)
...
...
@@ -288,10 +325,19 @@ void BasicBuilderArena::reportReadLimitReached() {
}
}
kj
::
Own
<
ClientHook
>
BasicBuilderArena
::
extractCap
(
const
_
::
StructReader
&
capDescriptor
)
{
KJ_FAIL_REQUIRE
(
"Message contains no capabilities."
);
}
void
BasicBuilderArena
::
injectCap
(
_
::
PointerBuilder
pointer
,
kj
::
Own
<
ClientHook
>&&
cap
)
{
KJ_FAIL_REQUIRE
(
"Cannot inject capability into a builder that has not been imbued with a "
"capability context."
);
}
// =======================================================================================
ImbuedBuilderArena
::
ImbuedBuilderArena
(
BuilderArena
*
base
)
:
base
(
base
),
segment0
(
nullptr
)
{}
ImbuedBuilderArena
::
ImbuedBuilderArena
(
BuilderArena
*
base
,
CapInjectorBase
*
capInjector
)
:
base
(
base
),
capInjector
(
capInjector
),
segment0
(
nullptr
)
{}
ImbuedBuilderArena
::~
ImbuedBuilderArena
()
noexcept
(
false
)
{}
SegmentBuilder
*
ImbuedBuilderArena
::
imbue
(
SegmentBuilder
*
baseSegment
)
{
...
...
@@ -334,6 +380,10 @@ void ImbuedBuilderArena::reportReadLimitReached() {
base
->
reportReadLimitReached
();
}
kj
::
Own
<
ClientHook
>
ImbuedBuilderArena
::
extractCap
(
const
_
::
StructReader
&
capDescriptor
)
{
return
capInjector
->
getInjectedCapInternal
(
capDescriptor
);
}
SegmentBuilder
*
ImbuedBuilderArena
::
getSegment
(
SegmentId
id
)
{
return
imbue
(
base
->
getSegment
(
id
));
}
...
...
@@ -344,5 +394,9 @@ BuilderArena::AllocateResult ImbuedBuilderArena::allocate(WordCount amount) {
return
result
;
}
void
ImbuedBuilderArena
::
injectCap
(
_
::
PointerBuilder
pointer
,
kj
::
Own
<
ClientHook
>&&
cap
)
{
return
capInjector
->
injectCapInternal
(
pointer
,
kj
::
mv
(
cap
));
}
}
// namespace _ (private)
}
// namespace capnp
c++/src/capnp/arena.h
View file @
d07bf3b8
...
...
@@ -34,10 +34,13 @@
#include <kj/mutex.h>
#include "common.h"
#include "message.h"
#include "layout.h"
namespace
capnp
{
class
TypelessCapability
;
class
CapExtractorBase
;
class
CapInjectorBase
;
class
ClientHook
;
namespace
_
{
// private
...
...
@@ -182,7 +185,7 @@ public:
// the VALIDATE_INPUT() macro which may throw an exception; if it return normally, the caller
// will need to continue with default values.
virtual
kj
::
Own
<
TypelessCapability
>
extractCap
(
const
_
::
StructReader
&
capDescriptor
)
;
virtual
kj
::
Own
<
ClientHook
>
extractCap
(
const
_
::
StructReader
&
capDescriptor
)
=
0
;
// Given a StructReader for a capability descriptor embedded in the message, return the
// corresponding capability.
};
...
...
@@ -196,6 +199,7 @@ public:
// implements Arena ------------------------------------------------
SegmentReader
*
tryGetSegment
(
SegmentId
id
)
override
;
void
reportReadLimitReached
()
override
;
kj
::
Own
<
ClientHook
>
extractCap
(
const
_
::
StructReader
&
capDescriptor
);
private
:
MessageReader
*
message
;
...
...
@@ -210,7 +214,7 @@ private:
class
ImbuedReaderArena
final
:
public
Arena
{
public
:
ImbuedReaderArena
(
Arena
*
base
);
ImbuedReaderArena
(
Arena
*
base
,
CapExtractorBase
*
capExtractor
);
~
ImbuedReaderArena
()
noexcept
(
false
);
KJ_DISALLOW_COPY
(
ImbuedReaderArena
);
...
...
@@ -219,9 +223,11 @@ public:
// implements Arena ------------------------------------------------
SegmentReader
*
tryGetSegment
(
SegmentId
id
)
override
;
void
reportReadLimitReached
()
override
;
kj
::
Own
<
ClientHook
>
extractCap
(
const
_
::
StructReader
&
capDescriptor
);
private
:
Arena
*
base
;
CapExtractorBase
*
capExtractor
;
// Optimize for single-segment messages so that small messages are handled quickly.
SegmentReader
segment0
;
...
...
@@ -248,7 +254,7 @@ public:
// the arena is guaranteed to succeed. Therefore callers should try to allocate from a specific
// segment first if there is one, then fall back to the arena.
virtual
void
injectCap
(
_
::
PointerBuilder
pointer
,
kj
::
Own
<
TypelessCapability
>&&
cap
)
=
0
;
virtual
void
injectCap
(
_
::
PointerBuilder
pointer
,
kj
::
Own
<
ClientHook
>&&
cap
)
=
0
;
// Add the capability to the message and initialize the given pointer as an interface pointer
// pointing to this cap.
};
...
...
@@ -271,10 +277,12 @@ public:
// implements Arena ------------------------------------------------
SegmentReader
*
tryGetSegment
(
SegmentId
id
)
override
;
void
reportReadLimitReached
()
override
;
kj
::
Own
<
ClientHook
>
extractCap
(
const
_
::
StructReader
&
capDescriptor
);
// implements BuilderArena -----------------------------------------
SegmentBuilder
*
getSegment
(
SegmentId
id
)
override
;
AllocateResult
allocate
(
WordCount
amount
)
override
;
void
injectCap
(
_
::
PointerBuilder
pointer
,
kj
::
Own
<
ClientHook
>&&
cap
);
private
:
MessageBuilder
*
message
;
...
...
@@ -294,7 +302,7 @@ class ImbuedBuilderArena final: public BuilderArena {
// A BuilderArena imbued with the ability to inject capabilities.
public
:
ImbuedBuilderArena
(
BuilderArena
*
base
);
ImbuedBuilderArena
(
BuilderArena
*
base
,
CapInjectorBase
*
capInjector
);
~
ImbuedBuilderArena
()
noexcept
(
false
);
KJ_DISALLOW_COPY
(
ImbuedBuilderArena
);
...
...
@@ -304,13 +312,16 @@ public:
// implements Arena ------------------------------------------------
SegmentReader
*
tryGetSegment
(
SegmentId
id
)
override
;
void
reportReadLimitReached
()
override
;
kj
::
Own
<
ClientHook
>
extractCap
(
const
_
::
StructReader
&
capDescriptor
);
// implements BuilderArena -----------------------------------------
SegmentBuilder
*
getSegment
(
SegmentId
id
)
override
;
AllocateResult
allocate
(
WordCount
amount
)
override
;
void
injectCap
(
_
::
PointerBuilder
pointer
,
kj
::
Own
<
ClientHook
>&&
cap
);
private
:
BuilderArena
*
base
;
CapInjectorBase
*
capInjector
;
ImbuedSegmentBuilder
segment0
;
...
...
c++/src/capnp/capability-context.c++
0 → 100644
View file @
d07bf3b8
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define CAPNP_PRIVATE
#include "capability-context.h"
#include "arena.h"
#include <kj/debug.h>
namespace
capnp
{
CapReaderContext
::
CapReaderContext
(
CapExtractorBase
&
extractor
)
:
extractor
(
&
extractor
)
{}
CapReaderContext
::~
CapReaderContext
()
noexcept
(
false
)
{
if
(
extractor
==
nullptr
)
{
kj
::
dtor
(
arena
());
}
}
ObjectPointer
::
Reader
CapReaderContext
::
imbue
(
ObjectPointer
::
Reader
base
)
{
KJ_REQUIRE
(
extractor
!=
nullptr
,
"imbue() can only be called once."
);
KJ_IF_MAYBE
(
oldArena
,
base
.
reader
.
getArena
())
{
kj
::
ctor
(
arena
(),
oldArena
,
extractor
);
}
else
{
KJ_FAIL_REQUIRE
(
"Cannot imbue unchecked message."
);
}
extractor
=
nullptr
;
return
ObjectPointer
::
Reader
(
base
.
reader
.
imbue
(
arena
()));
}
CapBuilderContext
::
CapBuilderContext
(
CapInjectorBase
&
injector
)
:
injector
(
&
injector
)
{}
CapBuilderContext
::~
CapBuilderContext
()
noexcept
(
false
)
{
if
(
injector
==
nullptr
)
{
kj
::
dtor
(
arena
());
}
}
ObjectPointer
::
Builder
CapBuilderContext
::
imbue
(
ObjectPointer
::
Builder
base
)
{
KJ_REQUIRE
(
injector
!=
nullptr
,
"imbue() can only be called once."
);
kj
::
ctor
(
arena
(),
&
base
.
builder
.
getArena
(),
injector
);
injector
=
nullptr
;
return
ObjectPointer
::
Builder
(
base
.
builder
.
imbue
(
arena
()));
}
}
// namespace capnp
c++/src/capnp/capability-context.h
0 → 100644
View file @
d07bf3b8
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Classes for imbuing message readers/builders with a capability context.
//
// These classes are for use by RPC implementations. Application code need not know about them.
//
// Normally, MessageReader and MessageBuilder do not support interface pointers because they
// are not RPC-aware and so have no idea how to convert between a serialized CapabilityDescriptor
// and a live capability. To fix this, a reader/builder object needs to be "imbued" with a
// capability context. This creates a new reader/builder which points at the same object but has
// the ability to deal with interface fields. Use `CapReaderContext` and `CapBuilderContext` to
// accomplish this.
#ifndef CAPNP_CAPABILITY_CONTEXT_H_
#define CAPNP_CAPABILITY_CONTEXT_H_
#include "layout.h"
#include "object.h"
#include <kj/mutex.h>
namespace
capnp
{
class
ClientHook
;
namespace
_
{
// private
class
ImbuedReaderArena
;
class
ImbuedBuilderArena
;
}
// namespace _ (private)
class
CapExtractorBase
{
// Non-template base class for CapExtractor<T>.
private
:
virtual
kj
::
Own
<
ClientHook
>
extractCapInternal
(
const
_
::
StructReader
&
capDescriptor
)
=
0
;
friend
class
_
::
ImbuedReaderArena
;
};
class
CapInjectorBase
{
// Non-template base class for CapInjector<T>.
private
:
virtual
void
injectCapInternal
(
_
::
PointerBuilder
builder
,
kj
::
Own
<
ClientHook
>&&
cap
)
=
0
;
virtual
kj
::
Own
<
ClientHook
>
getInjectedCapInternal
(
const
_
::
StructReader
&
capDescriptor
)
=
0
;
friend
class
_
::
ImbuedBuilderArena
;
};
template
<
typename
CapDescriptor
>
class
CapExtractor
:
public
CapExtractorBase
{
// Callback used to read a capability from a message, implemented by the RPC system.
// `CapDescriptor` is the struct type which the RPC implementation uses to represent
// capabilities. (On the wire, an interface pointer actually points to a struct of this type.)
public
:
virtual
kj
::
Own
<
ClientHook
>
extractCap
(
typename
CapDescriptor
::
Reader
descriptor
)
=
0
;
// Given the descriptor read off the wire, construct a live capability.
private
:
kj
::
Own
<
ClientHook
>
extractCapInternal
(
const
_
::
StructReader
&
capDescriptor
)
override
final
{
return
extractCap
(
typename
CapDescriptor
::
Reader
(
capDescriptor
));
}
};
template
<
typename
CapDescriptor
>
class
CapInjector
:
public
CapInjectorBase
{
// Callback used to write a capability into a message, implemented by the RPC system.
// `CapDescriptor` is the struct type which the RPC implementation uses to represent
// capabilities. (On the wire, an interface pointer actually points to a struct of this type.)
public
:
virtual
void
injectCap
(
typename
CapDescriptor
::
Builder
descriptor
,
kj
::
Own
<
ClientHook
>&&
cap
)
=
0
;
// Fill in the given descriptor so that it describes the given capability.
virtual
kj
::
Own
<
ClientHook
>
getInjectedCap
(
typename
CapDescriptor
::
Reader
descriptor
)
=
0
;
// Read back a cap that was previously injected with `injectCap`. This should return a new
// reference.
private
:
void
injectCapInternal
(
_
::
PointerBuilder
builder
,
kj
::
Own
<
ClientHook
>&&
cap
)
override
final
{
injectCap
(
typename
CapDescriptor
::
Builder
(
builder
.
initCapDescriptor
(
_
::
structSize
<
CapDescriptor
>
())),
kj
::
mv
(
cap
));
}
kj
::
Own
<
ClientHook
>
getInjectedCapInternal
(
const
_
::
StructReader
&
capDescriptor
)
{
return
getInjectedCap
(
typename
CapDescriptor
::
Reader
(
capDescriptor
));
}
};
// -------------------------------------------------------------------
class
CapReaderContext
{
// Class which can "imbue" reader objects from some other message with a capability context,
// so that interface pointers found in the message can be extracted and called.
//
// `imbue()` can only be called once per context.
public
:
CapReaderContext
(
CapExtractorBase
&
extractor
);
~
CapReaderContext
()
noexcept
(
false
);
ObjectPointer
::
Reader
imbue
(
ObjectPointer
::
Reader
base
);
private
:
CapExtractorBase
*
extractor
;
// becomes null once arena is allocated
void
*
arenaSpace
[
12
+
sizeof
(
kj
::
MutexGuarded
<
void
*>
)
/
sizeof
(
void
*
)];
_
::
ImbuedReaderArena
&
arena
()
{
return
*
reinterpret_cast
<
_
::
ImbuedReaderArena
*>
(
arenaSpace
);
}
friend
class
_
::
ImbuedReaderArena
;
};
class
CapBuilderContext
{
// Class which can "imbue" reader objects from some other message with a capability context,
// so that interface pointers found in the message can be set to point at live capabilities.
//
// `imbue()` can only be called once per context.
public
:
CapBuilderContext
(
CapInjectorBase
&
injector
);
~
CapBuilderContext
()
noexcept
(
false
);
ObjectPointer
::
Builder
imbue
(
ObjectPointer
::
Builder
base
);
private
:
CapInjectorBase
*
injector
;
// becomes null once arena is allocated
void
*
arenaSpace
[
12
+
sizeof
(
kj
::
MutexGuarded
<
void
*>
)
/
sizeof
(
void
*
)];
_
::
ImbuedBuilderArena
&
arena
()
{
return
*
reinterpret_cast
<
_
::
ImbuedBuilderArena
*>
(
arenaSpace
);
}
friend
class
_
::
ImbuedBuilderArena
;
};
}
// namespace capnp
#endif // CAPNP_CAPABILITY_CONTEXT_H_
c++/src/capnp/capability.c++
View file @
d07bf3b8
...
...
@@ -24,19 +24,18 @@
#include "capability.h"
namespace
capnp
{
namespace
_
{
// private
CallResult
::
Pipeline
CallResult
::
Pipeline
::
getPointerField
(
uint16_t
pointerIndex
)
const
{
auto
newOps
=
kj
::
heapArray
<
PipelineManager
::
Op
>
(
ops
.
size
()
+
1
);
TypelessAnswer
::
Pipeline
TypelessAnswer
::
Pipeline
::
getPointerField
(
uint16_t
pointerIndex
)
const
{
auto
newOps
=
kj
::
heapArray
<
PipelineOp
>
(
ops
.
size
()
+
1
);
for
(
auto
i
:
kj
::
indices
(
ops
))
{
newOps
[
i
]
=
ops
[
i
];
}
auto
&
newOp
=
newOps
[
ops
.
size
()];
newOp
.
type
=
Pipeline
Manager
::
Op
::
GET_POINTER_FIELD
;
newOp
.
type
=
PipelineOp
::
GET_POINTER_FIELD
;
newOp
.
pointerIndex
=
pointerIndex
;
return
Pipeline
(
call
->
addRef
(),
kj
::
mv
(
newOps
));
return
Pipeline
(
hook
->
addRef
(),
kj
::
mv
(
newOps
));
}
}
// namespace _ (private)
}
// namespace capnp
c++/src/capnp/capability.h
View file @
d07bf3b8
This diff is collapsed.
Click to expand it.
c++/src/capnp/layout.c++
View file @
d07bf3b8
...
...
@@ -2104,6 +2104,14 @@ PointerReader PointerBuilder::asReader() const {
return
PointerReader
(
segment
,
pointer
,
std
::
numeric_limits
<
int
>::
max
());
}
BuilderArena
&
PointerBuilder
::
getArena
()
const
{
return
*
segment
->
getArena
();
}
PointerBuilder
PointerBuilder
::
imbue
(
ImbuedBuilderArena
&
newArena
)
const
{
return
PointerBuilder
(
newArena
.
imbue
(
segment
),
pointer
);
}
// =======================================================================================
// PointerReader
...
...
@@ -2139,6 +2147,14 @@ bool PointerReader::isNull() const {
return
pointer
==
nullptr
||
pointer
->
isNull
();
}
kj
::
Maybe
<
Arena
&>
PointerReader
::
getArena
()
const
{
return
segment
==
nullptr
?
nullptr
:
segment
->
getArena
();
}
PointerReader
PointerReader
::
imbue
(
ImbuedReaderArena
&
newArena
)
const
{
return
PointerReader
(
newArena
.
imbue
(
segment
),
pointer
,
nestingLimit
);
}
// =======================================================================================
// StructBuilder
...
...
c++/src/capnp/layout.h
View file @
d07bf3b8
...
...
@@ -39,7 +39,7 @@
namespace
capnp
{
class
TypelessCapability
;
class
ClientHook
;
namespace
_
{
// private
...
...
@@ -54,7 +54,10 @@ struct WirePointer;
struct
WireHelpers
;
class
SegmentReader
;
class
SegmentBuilder
;
class
Arena
;
class
BuilderArena
;
class
ImbuedReaderArena
;
class
ImbuedBuilderArena
;
// =============================================================================
...
...
@@ -284,7 +287,7 @@ public:
ListBuilder
getList
(
FieldSize
elementSize
,
const
word
*
defaultValzue
);
ListBuilder
getStructList
(
StructSize
elementSize
,
const
word
*
defaultValue
);
template
<
typename
T
>
typename
T
::
Builder
getBlob
(
const
void
*
defaultValue
,
ByteCount
defaultSize
);
kj
::
Own
<
TypelessCapability
>
getCapability
();
kj
::
Own
<
ClientHook
>
getCapability
();
// Get methods: Get the value. If it is null, initialize it to a copy of the default value.
// The default value is encoded as an "unchecked message" for structs, lists, and objects, or a
// simple byte array for blobs.
...
...
@@ -300,7 +303,7 @@ public:
void
setStruct
(
const
StructReader
&
value
);
void
setList
(
const
ListReader
&
value
);
template
<
typename
T
>
void
setBlob
(
typename
T
::
Reader
value
);
void
setCapability
(
kj
::
Own
<
TypelessCapability
>&&
cap
);
void
setCapability
(
kj
::
Own
<
ClientHook
>&&
cap
);
// Set methods: Initialize the pointer to a newly-allocated copy of the given value, discarding
// the existing object.
...
...
@@ -321,6 +324,12 @@ public:
PointerReader
asReader
()
const
;
BuilderArena
&
getArena
()
const
;
// Get the arena containing this pointer.
PointerBuilder
imbue
(
ImbuedBuilderArena
&
newArena
)
const
;
// Imbue the pointer with a capability context, returning the imbued pointer.
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the pointer resides.
WirePointer
*
pointer
;
// Pointer to the pointer.
...
...
@@ -342,7 +351,7 @@ public:
ListReader
getList
(
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
template
<
typename
T
>
typename
T
::
Reader
getBlob
(
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
kj
::
Own
<
TypelessCapability
>
getCapability
();
kj
::
Own
<
ClientHook
>
getCapability
();
// Get methods: Get the value. If it is null, return the default value instead.
// The default value is encoded as an "unchecked message" for structs, lists, and objects, or a
// simple byte array for blobs.
...
...
@@ -352,6 +361,12 @@ public:
// word* can actually be passed to readUnchecked() to read the designated sub-object later. If
// this isn't an unchecked message, throws an exception.
kj
::
Maybe
<
Arena
&>
getArena
()
const
;
// Get the arena containing this pointer.
PointerReader
imbue
(
ImbuedReaderArena
&
newArena
)
const
;
// Imbue the pointer with a capability context, returning the imbued pointer.
private
:
SegmentReader
*
segment
;
// Memory segment in which the pointer resides.
const
WirePointer
*
pointer
;
// Pointer to the pointer. null = treat as null pointer.
...
...
c++/src/capnp/object.h
View file @
d07bf3b8
...
...
@@ -63,6 +63,7 @@ struct ObjectPointer {
_
::
PointerReader
reader
;
friend
struct
ObjectPointer
;
friend
class
Orphanage
;
friend
class
CapReaderContext
;
};
class
Builder
{
...
...
@@ -143,6 +144,7 @@ struct ObjectPointer {
private
:
_
::
PointerBuilder
builder
;
friend
class
CapBuilderContext
;
};
};
...
...
@@ -281,6 +283,38 @@ inline Orphan<T> Orphan<ObjectPointer>::releaseAs() {
return
Orphan
<
T
>
(
kj
::
mv
(
builder
));
}
// Using ObjectPointer as the template type should work...
template
<>
inline
typename
ObjectPointer
::
Reader
ObjectPointer
::
Reader
::
getAs
<
ObjectPointer
>
()
{
return
*
this
;
}
template
<>
inline
typename
ObjectPointer
::
Builder
ObjectPointer
::
Builder
::
getAs
<
ObjectPointer
>
()
{
return
*
this
;
}
template
<>
inline
typename
ObjectPointer
::
Builder
ObjectPointer
::
Builder
::
initAs
<
ObjectPointer
>
()
{
clear
();
return
*
this
;
}
template
<>
inline
void
ObjectPointer
::
Builder
::
setAs
<
ObjectPointer
>
(
ObjectPointer
::
Reader
value
)
{
return
builder
.
copyFrom
(
value
.
reader
);
}
template
<>
inline
void
ObjectPointer
::
Builder
::
adopt
<
ObjectPointer
>
(
Orphan
<
ObjectPointer
>&&
orphan
)
{
builder
.
adopt
(
kj
::
mv
(
orphan
.
builder
));
}
template
<>
inline
Orphan
<
ObjectPointer
>
ObjectPointer
::
Builder
::
disownAs
<
ObjectPointer
>
()
{
return
Orphan
<
ObjectPointer
>
(
builder
.
disown
());
}
template
<>
inline
Orphan
<
ObjectPointer
>
Orphan
<
ObjectPointer
>::
releaseAs
()
{
return
kj
::
mv
(
*
this
);
}
}
// namespace capnp
#endif // CAPNP_OBJECT_H_
c++/src/capnp/rpc.capnp
View file @
d07bf3b8
...
...
@@ -950,7 +950,7 @@ using JoinAnswer = Object;
#
# # Level 4 features -----------------------------------------------
#
# newJoiner(count :UInt32)
:
NewJoinerResponse;
# newJoiner(count :UInt32)
:
NewJoinerResponse;
# # Prepare a new Join operation, which will eventually lead to forming a new direct connection
# # to the host of the joined capability. `count` is the number of capabilities to join.
#
...
...
@@ -973,7 +973,7 @@ using JoinAnswer = Object;
# # message on it with the specified `ProvisionId` in order to receive the final capability.
# }
#
# acceptConnectionFromJoiner(parts
:
List(JoinKeyPart), paths :List(VatPath))
# acceptConnectionFromJoiner(parts
:
List(JoinKeyPart), paths :List(VatPath))
# :ConnectionAndProvisionId;
# # Called on a joined capability's host to receive the connection from the joiner, once all
# # key parts have arrived. The caller should expect to receive an `Accept` message over the
...
...
@@ -1002,17 +1002,17 @@ using JoinAnswer = Object;
# sendToTarget :RecipientId;
# }
#
# connectToIntroduced(capId
:
ThirdPartyCapId) :ConnectionAndProvisionId;
# connectToIntroduced(capId
:
ThirdPartyCapId) :ConnectionAndProvisionId;
# # Given a ThirdPartyCapId received over this connection, connect to the third party. The
# # caller should then send an `Accept` message over the new connection.
#
# acceptIntroducedConnection(recipientId
: RecipientId): Connection
# acceptIntroducedConnection(recipientId
:RecipientId) :Connection;
# # Given a RecipientId received in a `Provide` message on this `Connection`, wait for the
# # recipient to connect, and return the connection formed. Usually, the first message received
# # on the new connection will be an `Accept` message.
# }
#
# st
ur
ct ConnectionAndProvisionId {
# st
ru
ct ConnectionAndProvisionId {
# # **(level 3)**
#
# connection :Connection;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment