| /** @file |
| |
| One way 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. |
| |
| */ |
| |
| #if !defined (_I_OneWayTunnel_h_) |
| #define _I_OneWayTunnel_h_ |
| |
| #include "I_EventSystem.h" |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // |
| // OneWayTunnel |
| // |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| #define TUNNEL_TILL_DONE INT64_MAX |
| |
| #define ONE_WAY_TUNNEL_CLOSE_ALL NULL |
| |
| typedef void (*Transform_fn) (MIOBufferAccessor & in_buf, MIOBufferAccessor & out_buf); |
| |
| /** |
| A generic state machine that connects two virtual conections. A |
| OneWayTunnel is a module that connects two virtual connections, a source |
| vc and a target vc, and copies the data between source and target. Once |
| the tunnel is started using the init() call, it handles all the events |
| from the source and target and optionally calls a continuation back when |
| its done. On success it calls back the continuation with VC_EVENT_EOS, |
| and with VC_EVENT_ERROR on failure. |
| |
| If manipulate_fn is not NULL, 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 vc. By default, the manipulate_fn |
| is set to NULL, yielding the identity function. manipulate_fn takes |
| a IOBuffer containing the data to be written into the target virtual |
| connection which it may manipulate in any manner it sees fit. |
| |
| */ |
| struct OneWayTunnel: public Continuation |
| { |
| // |
| // Public Interface |
| // |
| |
| // Copy nbytes from vcSource to vcTarget. When done, call |
| // aCont back with either VC_EVENT_EOS (on success) or |
| // VC_EVENT_ERROR (on error) |
| // |
| |
| // Use these to construct/destruct OneWayTunnel objects |
| |
| /** |
| Allocates a OneWayTunnel object. |
| |
| @return new OneWayTunnel object. |
| |
| */ |
| static OneWayTunnel *OneWayTunnel_alloc(); |
| |
| /** Deallocates a OneWayTunnel object. */ |
| static void OneWayTunnel_free(OneWayTunnel *); |
| |
| static void SetupTwoWayTunnel(OneWayTunnel * east, OneWayTunnel * west); |
| OneWayTunnel(); |
| virtual ~ OneWayTunnel(); |
| |
| // 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 vcTarget target VConnection. A do_io_write should not have |
| been called on the vcTarget. The tunnel calls do_io_write on this VC. |
| @param aCont continuation to call back when the tunnel finishes. If |
| not specified, the tunnel deallocates itself without calling back |
| anybody. Otherwise, its the callee's responsibility to deallocate |
| the tunnel with OneWayTunnel_free. |
| @param size_estimate size of the MIOBuffer to create for |
| reading/writing to/from the VC's. |
| @param aMutex lock that this tunnel will run under. If aCont is |
| specified, the Continuation's lock is used instead of aMutex. |
| @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 watermark for the MIOBuffer used for reading. |
| |
| */ |
| void init(VConnection * vcSource, VConnection * vcTarget, Continuation * aCont = NULL, int size_estimate = 0, // 0 = best guess |
| ProxyMutex * aMutex = NULL, |
| int64_t nbytes = TUNNEL_TILL_DONE, |
| bool asingle_buffer = true, |
| bool aclose_source = true, |
| bool aclose_target = true, Transform_fn manipulate_fn = NULL, int water_mark = 0); |
| |
| /** |
| This init function sets up only the write side. It assumes that the |
| read VConnection has already been setup. |
| |
| @param vcSource source VConnection. Prior to calling this |
| init function, a do_io_read should have been called on this |
| VConnection. The tunnel uses the same MIOBuffer and frees |
| that buffer when the transfer is done (either successful or |
| unsuccessful). |
| @param vcTarget target VConnection. A do_io_write should not have |
| been called on the vcTarget. The tunnel calls do_io_write on |
| this VC. |
| @param aCont The Continuation to call back when the tunnel |
| finishes. If not specified, the tunnel deallocates itself without |
| calling back anybody. |
| @param SourceVio VIO of the vcSource. |
| @param reader IOBufferReader that reads from the vcSource. This |
| reader is provided to vcTarget. |
| @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. |
| */ |
| void init(VConnection * vcSource, |
| VConnection * vcTarget, |
| Continuation * aCont, |
| VIO * SourceVio, IOBufferReader * reader, bool aclose_source = true, bool aclose_target = true); |
| |
| /** |
| 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 VC are using the same buffer and frees that buffer |
| when the transfer is done (either successful or unsuccessful) |
| @param aCont The 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 TargetVio write VIO of the Target VC. |
| @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. |
| |
| */ |
| void init(Continuation * aCont, |
| VIO * SourceVio, VIO * TargetVio, bool aclose_source = true, bool aclose_target = true); |
| |
| // |
| // Private |
| // |
| OneWayTunnel(Continuation * aCont, |
| Transform_fn manipulate_fn = NULL, bool aclose_source = false, bool aclose_target = false); |
| |
| int startEvent(int event, void *data); |
| |
| virtual void transform(MIOBufferAccessor & in_buf, MIOBufferAccessor & out_buf); |
| |
| /** Result is -1 for any error. */ |
| void close_source_vio(int result); |
| |
| virtual void close_target_vio(int result, VIO * vio = ONE_WAY_TUNNEL_CLOSE_ALL); |
| |
| void connection_closed(int result); |
| |
| virtual void reenable_all(); |
| |
| bool last_connection(); |
| |
| VIO *vioSource; |
| VIO *vioTarget; |
| Continuation *cont; |
| Transform_fn manipulate_fn; |
| int n_connections; |
| int lerrno; |
| |
| bool single_buffer; |
| bool close_source; |
| bool close_target; |
| bool tunnel_till_done; |
| |
| /** Non-NULL when this is one side of a two way tunnel. */ |
| OneWayTunnel *tunnel_peer; |
| bool free_vcs; |
| |
| private: |
| OneWayTunnel(const OneWayTunnel &); |
| OneWayTunnel & operator =(const OneWayTunnel &); |
| |
| }; |
| |
| #endif |