Skip to content

Commit 0c1e4d6

Browse files
author
Graham Palmer
committed
Remove explicit segment requesting ability from subscribers and separate runtime mapping request from initialization
1 parent d8cd8e6 commit 0c1e4d6

File tree

1 file changed

+42
-47
lines changed

1 file changed

+42
-47
lines changed

doc/design/draft/named-segments.md

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,29 @@ have the proper access rights.
5757

5858
### Optional additional requirements
5959

60-
* When initializing the runtime, a list of segment names may be provided. In this case, rather than mapping all shared memory segments available in the system, only those that are named shall be mapped.
61-
* When a communication endpoint requests a segment that has not been mapped, this may be configured to either result in a failure or in mapping the requested segment on the fly.
60+
* When initializing the runtime, the user may specify via an enum whether they wish to map
61+
* All segments to which the current process has read access
62+
* All segments to which the current process has write access
63+
* All segments to which the current process has either read or write access
64+
* No segments (Default)
65+
* The user may additionally map specific segments after initialization by calling
66+
* `mapSegmentForReading(name)`
67+
* This will check for existence of the specified segment and map it as long as user has read access to it
68+
* An informative error will be returned under the following circumstances
69+
* The segment has already been mapped
70+
* The segment does not exist
71+
* The segment exists but the current process does not have read access to it
72+
* `mapSegmentForWriting(name)`
73+
* This will check for the existence of the specified segment and map it as long as the user has write access to it
74+
* An informative error will be returned under the following circumstances
75+
* The segment has already been mapped
76+
* The segment does not exist
77+
* The segment exists but the current process does not have write access to it
78+
* When the user attempts to create a publisher that requests a segment which is not mapped, this will trigger the error handler and cause program termination.
79+
* In the future if expose a builder-pattern method of creating publishers, we could instead have the builder return an error indicating the segment is not mapped.
80+
* An alternative to the above is to add an additional enum with configuration options allowing for the runtime to map requested segments on the fly. This increases flexibility, however because it is already possible to tell the runtime to map a specific segment would not add much value. A user who wishes to ensure a publisher's segment is already mapped may simply call `mapSegmentForWriting(name)`, ignoring the error indicating that the segment has already been mapped.
81+
* When a subscriber is created, an error will only occur if **no** segment has been mapped. Otherwise if a publisher on the same channel as the subscriber publishes to a segment the subscriber does not have access to (whether because the segment is unmapped or because the subscriber does not have read access), this will result in a fatal error.
82+
* Improvements could be made to the RouDi logic determining if publishers and subscribers are compatible - to check if the subscriber has access to the segment in which the publisher publishes. This is however considered out of scope for the current design proposal.
6283

6384
## Design
6485

@@ -93,38 +114,21 @@ struct PublisherOptions
93114
ShmName_t segmentName{""};
94115
```
95116

96-
#### When creating a Subscriber
97-
98-
A similar field will be added to the [SubscriberOptions struct](../../../iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp), except that it will support multiple elements
99-
100-
```
101-
struct SubscriberOptions
102-
{
103-
...
104-
vector<ShmName_t, MAX_SUBSCRIBER_SEGMENTS> segmentNames{};
105-
```
106-
107-
`MAX_SUBSCRIBER_SEGMENTS` can be set to some reasonably small value to start with since explicitly allowing many but not all read-access segments is an unlikely use case.
108-
109-
If this assumption turns out to be wrong however, we can always update it to be `MAX_SHM_SEGMENTS` instead.
110-
111117
#### When creating Clients and Servers
112118

113-
Clients and Servers will have similar fields, distinguished by request/response:
119+
Clients and Servers will have similar fields as publishers for the messages which they produce:
114120

115121
```
116122
struct ClientOptions
117123
{
118124
...
119125
ShmName_t requestSegmentName{""};
120-
vector<ShmName_t, MAX_RESPONSE_SEGMENTS> responseSegmentNames{};
121126
```
122127

123128
```
124129
struct ServerOptions
125130
{
126131
...
127-
vector<ShmName_t, MAX_REQUEST_SEGMENTS> requestSegmentNames{};
128132
ShmName_t responseSegmentName{""};
129133
```
130134

@@ -141,17 +145,20 @@ Tying this together with requesting segments, this could look something like:
141145
class DefaultRuntimeBuilder
142146
{
143147
...
144-
IOX_BUILDER_PARAMETER(vector<ShmName_t>, shmSegmentNames, {});
145-
IOX_BUILDER_PARAMETER(bool, allowUnmappedSegments, false);
148+
IOX_BUILDER_PARAMETER(MappedSegments, premappedSegments, MappedSegments::ReadAndWrite)
149+
IOX_BUILDER_PARAMETER(vector<ShmName_t, MAX_SHM_SEGMENTS>, shmSegmentNames, {});
150+
IOX_BUILDER_PARAMETER(UnmappedSegmentBehavior, unmappedSegmentBehavior, UnmappedSegmentBehavior::LoadOnDemand);
146151
...
147152
public:
148153
expected<DefaultRuntime, RuntimeBuilderError> create() noexcept;
149154
```
150155

151-
The `create` method of this builder would then return a custom error if a
152-
segment was requested that either does not exist or the current process does not have access to.
156+
The `create` method of this builder would then return a custom error if:
157+
* A segment is requested which does not exist
158+
* A segment is requested which the current process does not have access to
159+
* A segment is requested which has already been captured by the `premappedSegments` option
153160

154-
Additionally, when a publisher or subscriber is created, the `allowUnmappedSegments` would determine whether or not we fail or try to map the newly requested segment on the fly.
161+
Additionally, when a publisheris created, the `unamppedSegmentBehavior` option would determine whether or not we fail or try to map the newly requested segment on the fly.
155162

156163
### Segment Matching Algorithm
157164

@@ -177,39 +184,27 @@ In RouDi, given:
177184
4. At the end of iteration, if a matching segment has been found, return the segment information
178185
5. Otherwise return an error indicating that no matching segment has been found
179186

180-
#### Endpoints requesting read access (Subscriber, Client Response, Server Request)
181-
182-
In RouDi, when handling a port request for a new subscriber (and WLOG for clients and servers), given:
183-
* PublisherOptions for a single publisher publishing on the requested topic
184-
* SubscriberOptions for the requested subscriber
185-
186-
We determine if the endpoints are compatible as follows (and we repeat this for each publisher if there are several):
187-
1. To determine if the subscriber and publisher segments match:
188-
1. If the list of segment names provided by the subscriber is non-empty, check if any name matches the name provided by the publisher (an empty name is a non-match)
189-
2. If the list of segment names provided by the subscriber is empty, then it is always a match
190-
2. Determine if blocking policies are compatible
191-
3. Determine if history request is compatible
192-
4. Return true if all cases are met
193-
194-
If no publisher is compatible with a subscriber, then RouDi will refuse to provide a port, as is the current behavior when subscribers have incompatible blocking policies.
195-
196187
#### Runtime requesting segments to map
197188

198189
In the client process, while initializing the runtime, given:
199190
* `userGroups` - A list of POSIX user groups a publishing process belongs to called
200-
* `segmentContainer` - A list of shared memory segment information
191+
* `segmentContainer` - A list of shared memory segment information
192+
* `premappedSegments` - An enum indicating which group of segments should be mapped by default
201193
* `segmentFilter` - A (possibly empty) list of segment names to filter against
202194

203195
In order to determine which segments to map:
204196

205-
1. If `segmentFilter` is empty then
206-
1. Determine which segments the process has access rights (read or write) to.
207-
2. Map all of them.
197+
1. Map segments according to the `premappedSegments` option
198+
1. If read access segments are requested, map every segment the user has read access to, but not write access
199+
2. If write access segments are requested, map every segment the user has write access to
200+
3. If read and write access segmeents are requested, map every segment the user has either read or write access to
201+
4. If no segments are requested, do nothing
208202
2. If `segmentFilter` is not empty
209203
1. Iterate over each name in the filter
210204
2. If there is a segment that matches the name in the filter
211-
1. If the process has access rights to that segment, map it
212-
2. If not, return an error indicating that a segment was requested the runtime does not have access to.
205+
1. If the segment has already been mapped, return an error indicating that a segment has been requested twice. The error should contain access permissions and the value of the `premappedSegments` option the user understands why it has already been mapped.
206+
2. Otherwise, if the process has access rights to that segment, map it
207+
2. If the process does not have access rights, return an error indicating that a segment was requested the runtime does not have access to.
213208
3. If there is no segment that matches the name in the filter, return an error indicating that there is no segment matching the one requested to be mapped.
214209

215210
## Development Roadmap

0 commit comments

Comments
 (0)