blob: 4705a87c88f2e4422f4d8d7e14bd729ca42f0969 [file] [log] [blame]
/** @file
One way multi tunnel
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@section details Details
Part of the utils library which contains classes that use multiple
components of the IO-Core to implement some useful functionality. The
classes also serve as good examples of how to use the IO-Core.
*/
#pragma once
#include "I_OneWayTunnel.h"
/** Maximum number which can be tunnelled too */
#define ONE_WAY_MULTI_TUNNEL_LIMIT 4
/**
A generic state machine that connects a source virtual connection to
multiple target virtual connections. A OneWayMultiTunnel is similar to
the OneWayTunnel module. However, instead of connection one source
to one target, it connects multiple virtual connections - a source
vc and multiple target vcs, and copies the data from the source
to the target vcs. The maximum number of Target VCs is limited by
ONE_WAY_MULTI_TUNNEL_LIMIT.
If manipulate_fn is not nullptr, then the tunnel acts as a filter,
processing all data arriving from the source vc by the manipulate_fn
function, before sending to the target vcs. By default, the
manipulate_fn is set to nullptr, yielding the identity function.
@see OneWayTunnel
*/
struct OneWayMultiTunnel : public OneWayTunnel {
//
// Public Interface
//
OneWayMultiTunnel();
// Use One of the following init functions to start the tunnel.
/**
This init function sets up the read (calls do_io_read) and the write
(calls do_io_write).
@param vcSource source VConnection. A do_io_read should not have
been called on the vcSource. The tunnel calls do_io_read on this VC.
@param vcTargets array of Target VConnections. A do_io_write should
not have been called on any of the vcTargets. The tunnel calls
do_io_write on these VCs.
@param n_vcTargets size of vcTargets.
@param aCont continuation to call back when the tunnel finishes. If
not specified, the tunnel deallocates itself without calling
back anybody.
@param size_estimate size of the MIOBuffer to create for reading/
writing to/from the VC's.
@param nbytes number of bytes to transfer.
@param asingle_buffer whether the same buffer should be used to read
from vcSource and write to vcTarget. This should be set to true
in most cases, unless the data needs be transformed.
@param aclose_source if true, the tunnel closes vcSource at the
end. If aCont is not specified, this should be set to true.
@param aclose_target if true, the tunnel closes vcTarget at the end.
If aCont is not specified, this should be set to true.
@param manipulate_fn if specified, the tunnel calls this function
with the input and the output buffer, whenever it gets new data
in the input buffer. This function can transform the data in the
input buffer.
@param water_mark for the MIOBuffer used for reading.
*/
void init(VConnection *vcSource, VConnection **vcTargets, int n_vcTargets, Continuation *aCont = nullptr,
int size_estimate = 0, // 0 == best guess
int64_t nbytes = TUNNEL_TILL_DONE, bool asingle_buffer = true, bool aclose_source = true, bool aclose_target = true,
Transform_fn manipulate_fn = nullptr, int water_mark = 0);
/**
Use this init function if both the read and the write sides have
already been setup. The tunnel assumes that the read VC and the
write VCs are using the same buffer and frees that buffer when the
transfer is done (either successful or unsuccessful).
@param aCont continuation to call back when the tunnel finishes. If
not specified, the tunnel deallocates itself without calling back
anybody.
@param SourceVio read VIO of the Source VC.
@param TargetVios array of write VIOs of the Target VCs.
@param n_vioTargets size of TargetVios array.
@param aclose_source if true, the tunnel closes vcSource at the
end. If aCont is not specified, this should be set to true.
@param aclose_target ff true, the tunnel closes vcTarget at the
end. If aCont is not specified, this should be set to true.
*/
void init(Continuation *aCont, VIO *SourceVio, VIO **TargetVios, int n_vioTargets, bool aclose_source = true,
bool aclose_target = true);
//
// Private
//
int startEvent(int event, void *data);
void reenable_all() override;
void close_target_vio(int result, VIO *vio = nullptr) override;
int n_vioTargets = 0;
bool source_read_previously_completed = false;
MIOBufferAccessor topOutBuffer;
VIO *vioTargets[ONE_WAY_MULTI_TUNNEL_LIMIT];
};
extern ClassAllocator<OneWayMultiTunnel> OneWayMultiTunnelAllocator;