00001 /** @file 00002 00003 One way tunnel 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 00023 @section details Details 00024 00025 Part of the utils library which contains classes that use multiple 00026 components of the IO-Core to implement some useful functionality. The 00027 classes also serve as good examples of how to use the IO-Core. 00028 00029 */ 00030 00031 #if !defined (_I_OneWayTunnel_h_) 00032 #define _I_OneWayTunnel_h_ 00033 00034 #include "I_EventSystem.h" 00035 00036 ////////////////////////////////////////////////////////////////////////////// 00037 // 00038 // OneWayTunnel 00039 // 00040 ////////////////////////////////////////////////////////////////////////////// 00041 00042 #define TUNNEL_TILL_DONE INT64_MAX 00043 00044 #define ONE_WAY_TUNNEL_CLOSE_ALL NULL 00045 00046 typedef void (*Transform_fn) (MIOBufferAccessor & in_buf, MIOBufferAccessor & out_buf); 00047 00048 /** 00049 A generic state machine that connects two virtual conections. A 00050 OneWayTunnel is a module that connects two virtual connections, a source 00051 vc and a target vc, and copies the data between source and target. Once 00052 the tunnel is started using the init() call, it handles all the events 00053 from the source and target and optionally calls a continuation back when 00054 its done. On success it calls back the continuation with VC_EVENT_EOS, 00055 and with VC_EVENT_ERROR on failure. 00056 00057 If manipulate_fn is not NULL, then the tunnel acts as a filter, 00058 processing all data arriving from the source vc by the manipulate_fn 00059 function, before sending to the target vc. By default, the manipulate_fn 00060 is set to NULL, yielding the identity function. manipulate_fn takes 00061 a IOBuffer containing the data to be written into the target virtual 00062 connection which it may manipulate in any manner it sees fit. 00063 00064 */ 00065 struct OneWayTunnel: public Continuation 00066 { 00067 // 00068 // Public Interface 00069 // 00070 00071 // Copy nbytes from vcSource to vcTarget. When done, call 00072 // aCont back with either VC_EVENT_EOS (on success) or 00073 // VC_EVENT_ERROR (on error) 00074 // 00075 00076 // Use these to construct/destruct OneWayTunnel objects 00077 00078 /** 00079 Allocates a OneWayTunnel object. 00080 00081 @return new OneWayTunnel object. 00082 00083 */ 00084 static OneWayTunnel *OneWayTunnel_alloc(); 00085 00086 /** Deallocates a OneWayTunnel object. */ 00087 static void OneWayTunnel_free(OneWayTunnel *); 00088 00089 static void SetupTwoWayTunnel(OneWayTunnel * east, OneWayTunnel * west); 00090 OneWayTunnel(); 00091 virtual ~ OneWayTunnel(); 00092 00093 // Use One of the following init functions to start the tunnel. 00094 /** 00095 This init function sets up the read (calls do_io_read) and the write 00096 (calls do_io_write). 00097 00098 @param vcSource source VConnection. A do_io_read should not have 00099 been called on the vcSource. The tunnel calls do_io_read on this VC. 00100 @param vcTarget target VConnection. A do_io_write should not have 00101 been called on the vcTarget. The tunnel calls do_io_write on this VC. 00102 @param aCont continuation to call back when the tunnel finishes. If 00103 not specified, the tunnel deallocates itself without calling back 00104 anybody. Otherwise, its the callee's responsibility to deallocate 00105 the tunnel with OneWayTunnel_free. 00106 @param size_estimate size of the MIOBuffer to create for 00107 reading/writing to/from the VC's. 00108 @param aMutex lock that this tunnel will run under. If aCont is 00109 specified, the Continuation's lock is used instead of aMutex. 00110 @param nbytes number of bytes to transfer. 00111 @param asingle_buffer whether the same buffer should be used to read 00112 from vcSource and write to vcTarget. This should be set to true in 00113 most cases, unless the data needs be transformed. 00114 @param aclose_source if true, the tunnel closes vcSource at the 00115 end. If aCont is not specified, this should be set to true. 00116 @param aclose_target if true, the tunnel closes vcTarget at the 00117 end. If aCont is not specified, this should be set to true. 00118 @param manipulate_fn if specified, the tunnel calls this function 00119 with the input and the output buffer, whenever it gets new data 00120 in the input buffer. This function can transform the data in the 00121 input buffer 00122 @param water_mark watermark for the MIOBuffer used for reading. 00123 00124 */ 00125 void init(VConnection * vcSource, VConnection * vcTarget, Continuation * aCont = NULL, int size_estimate = 0, // 0 = best guess 00126 ProxyMutex * aMutex = NULL, 00127 int64_t nbytes = TUNNEL_TILL_DONE, 00128 bool asingle_buffer = true, 00129 bool aclose_source = true, 00130 bool aclose_target = true, Transform_fn manipulate_fn = NULL, int water_mark = 0); 00131 00132 /** 00133 This init function sets up only the write side. It assumes that the 00134 read VConnection has already been setup. 00135 00136 @param vcSource source VConnection. Prior to calling this 00137 init function, a do_io_read should have been called on this 00138 VConnection. The tunnel uses the same MIOBuffer and frees 00139 that buffer when the transfer is done (either successful or 00140 unsuccessful). 00141 @param vcTarget target VConnection. A do_io_write should not have 00142 been called on the vcTarget. The tunnel calls do_io_write on 00143 this VC. 00144 @param aCont The Continuation to call back when the tunnel 00145 finishes. If not specified, the tunnel deallocates itself without 00146 calling back anybody. 00147 @param SourceVio VIO of the vcSource. 00148 @param reader IOBufferReader that reads from the vcSource. This 00149 reader is provided to vcTarget. 00150 @param aclose_source if true, the tunnel closes vcSource at the 00151 end. If aCont is not specified, this should be set to true. 00152 @param aclose_target if true, the tunnel closes vcTarget at the 00153 end. If aCont is not specified, this should be set to true. 00154 */ 00155 void init(VConnection * vcSource, 00156 VConnection * vcTarget, 00157 Continuation * aCont, 00158 VIO * SourceVio, IOBufferReader * reader, bool aclose_source = true, bool aclose_target = true); 00159 00160 /** 00161 Use this init function if both the read and the write sides have 00162 already been setup. The tunnel assumes that the read VC and the 00163 write VC are using the same buffer and frees that buffer 00164 when the transfer is done (either successful or unsuccessful) 00165 @param aCont The Continuation to call back when the tunnel finishes. If 00166 not specified, the tunnel deallocates itself without calling back 00167 anybody. 00168 00169 @param SourceVio read VIO of the Source VC. 00170 @param TargetVio write VIO of the Target VC. 00171 @param aclose_source if true, the tunnel closes vcSource at the 00172 end. If aCont is not specified, this should be set to true. 00173 @param aclose_target if true, the tunnel closes vcTarget at the 00174 end. If aCont is not specified, this should be set to true. 00175 00176 */ 00177 void init(Continuation * aCont, 00178 VIO * SourceVio, VIO * TargetVio, bool aclose_source = true, bool aclose_target = true); 00179 00180 // 00181 // Private 00182 // 00183 OneWayTunnel(Continuation * aCont, 00184 Transform_fn manipulate_fn = NULL, bool aclose_source = false, bool aclose_target = false); 00185 00186 int startEvent(int event, void *data); 00187 00188 virtual void transform(MIOBufferAccessor & in_buf, MIOBufferAccessor & out_buf); 00189 00190 /** Result is -1 for any error. */ 00191 void close_source_vio(int result); 00192 00193 virtual void close_target_vio(int result, VIO * vio = ONE_WAY_TUNNEL_CLOSE_ALL); 00194 00195 void connection_closed(int result); 00196 00197 virtual void reenable_all(); 00198 00199 bool last_connection(); 00200 00201 VIO *vioSource; 00202 VIO *vioTarget; 00203 Continuation *cont; 00204 Transform_fn manipulate_fn; 00205 int n_connections; 00206 int lerrno; 00207 00208 bool single_buffer; 00209 bool close_source; 00210 bool close_target; 00211 bool tunnel_till_done; 00212 00213 /** Non-NULL when this is one side of a two way tunnel. */ 00214 OneWayTunnel *tunnel_peer; 00215 bool free_vcs; 00216 00217 private: 00218 OneWayTunnel(const OneWayTunnel &); 00219 OneWayTunnel & operator =(const OneWayTunnel &); 00220 00221 }; 00222 00223 #endif