summaryrefslogtreecommitdiff
path: root/TAO/docs/transport_current/index.html
blob: 72f9aaee44ddb8812b5e82478ba5e3887652fea9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<!-- $Id:$ -->

<HTML>
<HEAD>
<TITLE>Using the TAO::Transport::Current Feature</TITLE>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">

<LINK REL="STYLESHEET" HREF="transport_current.css">

</HEAD>

<BODY TEXT = "#000000" LINK="#000fff" VLINK="#ff0f0f" BGCOLOR="#ffffff">

<P>

<H1 ALIGN="CENTER">Using the TAO::Transport::Current Feature</H1>


<P ALIGN="CENTER">
Object Computing Inc.<BR>
St.Louis, Missouri
</P>

<P ALIGN="CENTER">
<SMALL><STRONG>
<A HREF="mailto:iliyan@ociweb.com">Iliyan Jeliazkov</A>
<A HREF="mailto:mesnier_p@ociweb.com">Phil Mesnier</A>
 and <A HREF="mailto:<john_c@ociweb.com">Ciju John</A>
</STRONG></SMALL>
</P>

<HR>

<P>
<H3>Scope and Context</H3><P>

<P>In TAO, it is just too hard to obtain statistical or pretty much any operational information about the network transport which the ORB is using. While this is a direct corollary of the CORBA's design paradigm which mandates hiding all this hairy stuff behind non-transparent abstractions, it also precludes effective ORB and network monitoring.
</P>

<P>
The Transport::Current feature intends to fill this gap by defining a 
framework for developing a wide range of solutions to this problem. It also provides a basic implementation for the most common case - the IIOP transport.
</P>

<P>
By definition, transport-specific information is available in
contexts where the ORB has selected a Transport:</P>

<UL>
  <LI>Within Client-side interception points;</LI>
  <LI>Within Server-side interception points;</LI>
  <LI>Inside a Servant up-call</LI>
</UL>

<P>
The implementation is based on a generic service-oriented
framework, implementing the TAO::Transport::Current interface. It is
an optional service, which can be dynamically loaded. This service makes 
the Transport::Current interface available through
orb->resolve_initial_references() . The basic idea is that whenever a Transport is 
chosen by the ORB, the Transport::Current (or a derivative) will have access 
to that instance and be able to provide some useful information.
</P>

<BR><HR>


<P>
<H3>
Programmer's Reference
</H3>

<P>
Consider the following IDL interface, describing a Factory for
producing TAO::Transport::Traits instance, which represents
transport-specific data.
</P>

<PRE>
#include <IOP.pidl>
#include <TimeBase.pidl>

module TAO
{
  /// A type used to represent counters
  typedef unsigned long long CounterT;

  module Transport
  {
    /// Used to signal that a call was made within improper invocation
    /// context.  Also, this exception is thrown if no Transport has
    /// been selected for the current thread, for example in a
    /// collocated invocation.

    exception NoContext
    {
    };

    // The primary interface, providing access to Transport
    // information, available to the current thread.

    local interface Current
    {
      /// Transport ID, unique within the process.
      readonly attribute long id raises (NoContext);

      /// Bytes sent/received through the transport.
      readonly attribute CounterT bytes_sent raises (NoContext);
      readonly attribute CounterT bytes_received raises (NoContext);

      /// Messages (requests and replies) sent/received using the current
      /// protocol.
      readonly attribute CounterT messages_sent raises (NoContext);
      readonly attribute CounterT messages_received raises (NoContext);

      /// The absolute time (miliseconds) since the transport has been
      /// open.
      readonly attribute TimeBase::TimeT open_since raises (NoContext);
    };
  };
};
</PRE>

<P>
As an example of a specialized Transport::Current is the Transport::IIOP::Current, which derives from Transport::Current and has an interface, described in the following IDL:
</P>

<PRE>
#include "TC.idl"

/// Provide a forward reference for the SSLIOP::Current
module SSLIOP
{
  interface Current;
};


module TAO
{
  module Transport
  {
    module IIOP
    {
      // The primary interface, providing access to IIOP-specific
      // transport information, if it is indeed an IIOP (-like) transport
      // that has been selected.

      local interface Current : TAO::Transport::Current
      {
        /// Remote host
        readonly attribute string remote_host raises (NoContext);

        /// Remote port Using long (signed) type to better accomodate
        /// the Java mapping, which has no support for unsigned values
        readonly attribute long remote_port raises (NoContext);

        /// Local host
        readonly attribute string local_host raises (NoContext);

        /// Local port
        readonly attribute long local_port raises (NoContext);

        /// If this is a "secure" transport, this method will give you
        /// the corresponding SSLIOP::Current
        readonly attribute ::SSLIOP::Current ssliop_current raises (NoContext);
      };
    };
  };
};
</PRE>


<P>
<H3>
User's Guide
</H3>

<P>
The TAO::Transport::Current can be used as a base interface for a more specialized TAO::Transport::X::Current. It is not required, however that a more specialized Current inherits from it.
</P>

<P>
Typical, generic usage is shown in the
$TAO_ROOT/orbsvcs/tests/Transport_Current/Framework test:
</P>

<PRE>
...
  // Get the Current object.                                                                                               
  ::CORBA::Object_var tcobject =
    orb->resolve_initial_references ("TAO::Transport::Current"
                                      ACE_ENV_SINGLE_ARG_DECL);
  ACE_TRY_CHECK;

  ::TAO::Transport::Current_var tc =
      ::TAO::Transport::Current::_narrow (tcobject.in ()
                                      ACE_ENV_SINGLE_ARG_DECL);
  ACE_TRY_CHECK;

  if (CORBA::is_nil (tc.in ()))
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P|%t) client - ERROR: Could not resolve ")
                  ACE_TEXT ("TAO::Transport::Current object.\n")));

      ACE_TRY_THROW (CORBA::INTERNAL ());
    }
...
</PRE>

<P>
Another example is available from the $TAO_ROOT/orbsvcs/tests/Transport_Current/IIOP test. This fragment shows how to obtain transport-specific information:
</P>

<PRE>
...
   // Get the specific Current object.
  CORBA::Object_var tcobject =
    orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("TAO::Transport::IIOP::Current")
                                     ACE_ENV_ARG_PARAMETER);
  ACE_TRY_CHECK;


  Transport::IIOP::Current_var tc =
    Transport::IIOP::Current::_narrow (tcobject.in ()
                                       ACE_ENV_SINGLE_ARG_DECL);
  ACE_TRY_CHECK;

  if (CORBA::is_nil (tc.in ()))
      ACE_TRY_THROW (CORBA::INTERNAL ());

  ::CORBA::String_var rhost (tc->remote_host (ACE_ENV_SINGLE_ARG_PARAMETER));
  ACE_TRY_CHECK;

  ::CORBA::String_var lhost (tc->local_host (ACE_ENV_SINGLE_ARG_PARAMETER));
  ACE_TRY_CHECK;

  ::CORBA::Long id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_TRY_CHECK;

  ::TAO::CounterT bs = tc->bytes_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_TRY_CHECK;

  ::TAO::CounterT br = tc->bytes_received (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_TRY_CHECK;

  ::TAO::CounterT rs = tc->messages_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_TRY_CHECK;

  ::TAO::CounterT rr = tc->messages_received (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_TRY_CHECK;
...
</PRE>



<P>
<H3>
Configuration, Bootstrap, Initialization and Operation
</H3>

<P>
To use the Transport Current features the framework must be loaded
through the Service Configuration framework. For example, using
something like this:
</P>

<PRE>
dynamic TAO_Transport_Current_Loader Service_Object * libTAO_Transport_Current.so:_make_TAO_Transport_Current_Loader() ""
</PRE>

<P>
The Transport_Current_Loader service uses an ORB initializer to register the "TAO::Transport::Current" name in a way that allows it to be resolved via orb->resolve_initial_references(). The implementation is the TAO::Transport::Current_Impl class.
</P>

<P>
A transport-specific Traits_Factory objects are loaded like this:
</P>

<PRE>
...
dynamic TAO_Transport_IIOP_Current_Loader Service_Object * TAO_TC_IIOP:_make_TAO_Transport_IIOP_Current_Loader() ""
...
</PRE>

<P>
Note that any number of transport-specific Current interfaces may be available at any one time.
</P>

<P>
Whenever a Transport::Current method is invoked, a pointer to the currently selected Transport instance must be accessible through Thread Specific Storage (TSS). For each thread, this is managed by modifying the TAO classes, instances of which are created on the stack during request/response processing.
</P>

<P>
<H3>
Implementation and Required Changes
</H3>

<P>
The primary implementation is predicated upon usage of thread specific
storage (TSS) and the guarantees C++ provides for calling the
constructor and the destructor of automatic (stack-based)
objects. Some existing objects, used in TAO will have to be modified
and the necessary changes, both for client and the server side are
detailed below.
</P>

<H4>
Client Side: Sending Requests or Replies
</H4>


<P>
The Profile_Transport_Resolver instance contains the reference to the
Transport, which is the TAO implementation structure that is needed to extract 
any protocol-specific information. An
instance of Profile_Transport_Resolver lives on the stack, starting
inside a call to Invocation_Adapter::invoke_remote_i(), or
LocateRequest_Invocation_Adapter::invoke(). In the case of collocated
invocations no such object is created.
</P>

<P>
It is then passed around the calls that follow, except for the calls
to the following Invocation_Base methods: send_request_interception(),
receive_other_interception(), receive_reply_interception(),
handle_any_exception(), handle_all_exception();
</P>

<P>
Note that these in turn call the client-side interception points and
that is where information about the transport will be needed. In order
to make the transport information accessible inside those methods, we
changed Profile_Transport_Resolver and the TAO_ServerRequest classes to
 incorporate an additional member:
</P>

<PRE>
...
TAO::Transport_Selection_Guard transport_;
...
</PRE>


<P>
This guard automatically keeps track of the currenty selected Transport from within its constructor and destructor. The rest of the TC framework  makes sure this pointer is stored in a thread-specific storage, by adding an additional member to TSS_Resources:
</P>

<PRE>
...
TAO::Transport_Selection_Guard* tsg_;
...
</PRE>

<P>
The idea is to keep a pointer to the last guard on the current thread. Each guard keeps a pointer to the previous, effectively creating a stack of transport selection guards. The stack structure ensures both that the selection/deselection of a Transport will be correctly handled. It also ensures that, in case the current thread temporarily changes the Transport, the previous “current” transport will be preserved, no matter how many times such change occurs. A good example for this is a nested up-call scenario.
</P>

<P>
Inside an interceptor, one can use the methods from Transport Current to obtain information on the currently selected transport. The implementation simply looks up the TAO_Transport pointer via TSS_Resources::tsg_ and obtains the requested data.
</P>



<H4>
Server Side: Request Processing
</H4>


<P>
On the server side, the TAO_ServerRequest instance already has a
Transport pointer. The TAO_ServerRequest lives on the stack, starting
its life inside a call to TAO_GIOP_Message_Base::process_request().
</P>

<P>
Similarly to the client-side, we changed the TAO_ServerRequest
to add a field:
</P>

<PRE>
...
TAO::Transport_Selection_Guard transport_;
...
</PRE>

<P>
Operation is similar to the client-side case. In the collocated case there may not be a 
transport available, so the TSS slot will be null.
</P>

<P>
Inside an interceptor then, one can use an RIR-resolved
TransportCurrent to create a specialization of TransportInfo, based on
the kind of Transport used. Then they would _downcast() it to the
specific type.
</P>

<H3>
Structural and Footprint Impact
</H3>

<P>
As the IIOP implementation of the Transport Current functionality requires additional 
data to be kept about the Transport, we added a new field to TAO_Transport:
</P>

<PRE>
...
  /// Transport statistics
  TAO::Transport::Stats* stats_
...
</PRE>

<P>
TAO::Transport::Stats is a simple structure, which keeps track of useful statistical 
information about how a transport is used:
</P>

<PRE>
...
    class TAO_Export Stats
    {
    public:
      Stats ();

      void messages_sent (size_t message_length);
      CORBA::LongLong messages_sent (void) const;
      CORBA::LongLong bytes_sent (void) const;

      void messages_received (size_t message_length);
      CORBA::LongLong messages_received (void) const;
      CORBA::LongLong bytes_received (void) const;

      void opened_since (const ACE_Time_Value& tv);
      const ACE_Time_Value& opened_since (void) const;

    private:
      CORBA::LongLong messages_rcvd_; // 32bits not enough (?)
      CORBA::LongLong messages_sent_; // 32bits not enough (?)

      ACE_Basic_Stats bytes_rcvd_;
      ACE_Basic_Stats bytes_sent_;

      ACE_Time_Value  opened_since_;
    };
...
</PRE>

<P>
To gather the statistics the TAO_Transport::send_message_shared() and TAO_Transport::process_parsed_messages() must be modified. These are non-virtual methods and are being called as part of request and reply processing regardless of what the most derived Transport type is. This property ensures that any specific Transport will have access to these statistics.
</P>

<H3>
Performance Impact
</H3>

<P>
As the implementation of the Transport Current functionality
necessitates some additional processing on the critical path of an
invocation, we are expecting a performance impact when the
functionality is being used. 
</P>

<P>
It is possible at build time, to
disable the functionality, so that applications only incur the penalty
if they require it. The ORB, by default will not support the Transport Current functionality. 
Use the following #define (in your config.h file) to enable it:
</P>

<PRE>
#define TAO_HAS_TRANSPORT_CURRENT 1
</PRE>

<H3>
Example Code
</H3>

<P>
Look at $TAO_ROOT/orbsvcs/tests/Transport_Current for code which illustrates and tests this feature.
</P>
</BODY>
</HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<!-- $Id$ -->

<HTML>
<HEAD>
<TITLE>Using TransportCurrent</TITLE>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">

<LINK REL="STYLESHEET" HREF="transport_current.css">

</HEAD>

<BODY TEXT = "#000000" LINK="#000fff" VLINK="#ff0f0f" BGCOLOR="#ffffff">

<P>

<H1 ALIGN="CENTER">TAOTransportCurrent</H1>
<P ALIGN="CENTER">
<STRONG>
<A HREF="mailto:iliyan@ociweb.com">Iliyan Jeliazkov</A>
<A HREF="mailto:mesnier_p@ociweb.com">Phil Mesnier</A>
 and <A HREF="mailto:<john_c@ociweb.com">Ciju John</A>
</STRONG>
</P>

<P ALIGN="CENTER">
Object Computing Inc.<BR>
St.Louis, Missouri
</P>

<HR>

<P>
<H3>Scope and Context</H3><P>

<P>By definition, transport-specific information is available in
contexts where the ORB has selected a Transport. The contexts covered
by this proposal are:</P>

<UL>
  <LI>client-side interception points;</LI>
  <LI>2.server-side interception points;</LI>
  <LI>3.servant up-call</LI>
</UL>

<P>
The design includes changes to the base TAO code to add a light-weight
framework, that allows the ORB core to register listeners interested
in Transport selection events. The framework simply keeps a list of
such listeners and notifies them in turn when a Transport is selected
in various points along the request processing path.
</P>

<P>
The second piece of the implementation is a generic service-based
framework, implementing the TAO::Transport::Current interface. It is
designed as an optional service, which can be dynamically loaded if
necessary. This service makes the Transport::Current available through
orb->resolve_initial_references() and also registers as a listener
with the Transport selection notification mechanism described
above. The basic idea is that whenever a Transport is chosen, during
the request/response processing, the TC will query any of the
registered TraitsFactory objects and will let the one that “knows” how
to handle the particular Transport, create a
TAO::Transport::Traits-derived object. Note also, that this service
also serves as the default TraitsFactory.
</P>

<P>
As described above, the third conceptual piece of the design is the
Transport-specific TraitsFactory object. It too is a dynamically
loaded service object, which upon loading will register with the
generic Transport Current framework.
</P>

<!-- End of Table of Contents -->
<BR><HR>


<P>
<H3>
Programmer's Reference
</H3>

<P>
Consider the following IDL interface, describing a Factory for
producing TAO::Transport::Traits instance, which represents
transport-specific data.
</P>

<PRE>
#include <IOP.pidl>
#include <Current.pidl>

#include "Traits_Factory.idl"

//#pragma prefix "omg.org"                                                                                                 

module TAO
{
  module Transport
  {

    // A factory for Transport Traits. Instances are registered with                                                       
    // the Transport Current to provide interpretation of a specific                                                        
    // Transport. The Current delegates to them the processing of a                                                        
    // Transport, based on whether or not the TTF supports a                                                              
    // particular protocol. Factories are searched in LIFO manner,                                                         
    // with respect of their order of registration. The first is the                                                       
    // default TF, which can handle any Transport in a generic way,                                                      
    // if no other TF lays claims to the Transport ID.                                                                   

    local interface TraitsFactory;


    // Serve as a base from which different specializations will be                                                        
    // derived. The specializations should add features for specific                                                       
    // protocols. For example, IIOPTraits, SSLIOPTraits, PBXIOPTraits,                                                     
    // etc.                                                                                                                

    local interface Traits
    {
      IOP::ProfileId tag ();
      boolean        is_bidirectional ();
      boolean        is_client ();
      boolean        is_server ();
      boolean        is_connected ();
    };

    // The main interface, providing access to the Transport-specific                                                      
    // information (traits), available to the current thread of                                                           
    // execution.                                                                                                          

    local interface Current
    : TraitsFactory    // This is also the default TF                                                                      
    {

      // Used to signal that a call was made within improper invocation                                                    
      // context.                                                                                                          

      exception BadContext
      {
      };

      // The client owns the returned Transport::Traits. The Current is                                                    
      // filling in the data from the Transport                                                                            

      Traits traits () raises (BadContext);

      // An interface to allow registering a new, perhaps more                                                             
      // specialized TraitsFactory.                                                                                        

      void register_traits_factory (in TraitsFactory tf);
   };

  };

};
</PRE>

<P>
The TraitsFactory is the basic interface the specific TraitsFactories
(like the one that knows about IIOP) must implement. Here is the
corresponding IDL (from Traits_Factory.idl)
</P>

<PRE>
#include <IOP.pidl>

//#pragma prefix "omg.org"                                                                                                 

module TAO
{
  module Transport
  {

    // A factory for Transport Traits. Instances are registered with                                                       
    // the Trasport Current to provide interpretation of a specific                                                        
    // Transport. The Current delegates to them the processing of a                                                        
    // Transport, based on wheather or not the TTF supports a                                                              
    // particular protocol. Factories are searched in LIFO manner,                                                         
    // with respect of their order of registration. The first is the                                                       
    // default TF, which can handle all Transport's in a generic way,                                                      
    // if no other TF lays claims to the Transport's ID.                                                                   

    local interface TraitsFactory
    {
      boolean is_supported (in IOP::ProfileId pid);
    };


  };

};
</PRE>

<P>
As an example of a specialized Transport Traits Factory, the
implementation includes IIOPTraits interface:
</P>

<PRE>
#include "Transport_Current.idl"

module TAO
{
  module Transport
  {

    // Interface IIOPTraits defines IIOP specific attributes                                                              

    local interface IIOPTraits
    : Traits
    {
      unsigned short remote_port ();
      string remote_host ();
      unsigned short local_port ();
      string local_host ();
    };

  };

};
</PRE>





<P>
<H3>
User's Guide
</H3>

<P>
The TAO::Transport::Traits is a base interface, from which different
specializations will be derived. For example, IIOPTransportInfo,
PBXIOPTransportInfo, etc. See below, in "TransportInfo Specialization"
for explanation of the mechanism for extending the framework with
protocol-specific TAO::Transport::TraitsFactory.
</P>

<P>
Typical, generic usage is shown in the
$TAO_ROOT/orbsvcs/tests/Transport_Current/Framework test:
</P>

<PRE>
...
  // Get the Current object.                                                                                               
  ::CORBA::Object_var tcobject =
    orb->resolve_initial_references ("TAOTransportCurrent"
                                      ACE_ENV_SINGLE_ARG_DECL);
  ACE_TRY_CHECK;

  ::TAO::Transport::Current_var tc =
      ::TAO::Transport::Current::_narrow (tcobject.in ()
                                      ACE_ENV_SINGLE_ARG_DECL);
  ACE_TRY_CHECK;

  if (CORBA::is_nil (tc.in ()))
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P|%t) client - ERROR: Could not resolve ")
                  ACE_TEXT ("TAOTransportCurrent object.\n")));

      ACE_TRY_THROW (CORBA::INTERNAL ());
    }

  ::TAO::Transport::Traits_var inf =
      tc->traits (ACE_ENV_SINGLE_ARG_DECL);
  ACE_TRY_CHECK;
...
</PRE>

<P>
Another example is available from the
$TAO_ROOT/orbsvcs/tests/Transport_Current/IIOP_Threading test. This
fragment shows how to obtain transport-specific traits:
</P>

</PRE>
...
  ::TAO::Transport::Traits_var inf = tc->traits (ACE_ENV_SINGLE_ARG_DECL);
  //tc->traits (ACE_ENV_SINGLE_ARG_DECL);                                                                                 
  ACE_TRY_CHECK;

  ::TAO::Transport::IIOPTraits_var iiopinf =
      ::TAO::Transport::IIOPTraits::_narrow (inf.in() ACE_ENV_ARG_PARAMETER);
  ACE_TRY_CHECK;

  iiopinf->remote_port ();
...
</PRE>



<P>
<H3>
Configuration, Bootstrap, Initialization and Operation
</H3>

<P>
To use the Transport Current features the framework must be loaded
through the Service Configuration framework. For example, using
something like this:
</P>

<PRE>
dynamic TAO_Transport_Current_Loader Service_Object * libTAO_Transport_Current.so:_make_TAO_Transport_Current_Loader() ""
</PRE>

<P>
The Transport_Current_Loader service uses an ORB initializer to register the "TAOTransportCurrent" name in a way that allows it to be resolved via orb->resolve_initial_references(). The implementation is the TAO::Transport::Current_Impl class, which in addition to TAO::Transport::Current, is also implementing the default Traits_Factory interface and the TAO::Transport::Listener interface.
</P>

<P>
Any transport-specific Traits_Factory objects are loaded like this:
</P>

<PRE>
dynamic TAO_IIOP_Traits_Loader Service_Object * libTAO_TC_IIOPTraits.so:_make_TAO_IIOP_Traits_Loader() ""
</PRE>

<P>
The corresponding service initialization is where the specific Traits
Factory registers itself with the TAO_Transport_Current_Loader.
</P>

<P>
Whenever the TC::traits() method is invoked, a pointer to the
currently selected Transport instance is (must be) accessible through
Thread Specific Storage (TSS). The TC will ask a Traits Factory (TF)
to make a specific Traits (T) instance. All TF instances implement a
method, which the TC uses to determine if it supports a given
Transport subclass. This is what the TC uses, when it iterates over
the list of registered TF instances in order to select an appropriate
one.
</P>

<P>
Once a TF is selected, its traits() method is invoked. There a TF,
which is always available – the default TF. It is implemented by the
TAO::Transport::Current_Impl class and merely returns generic Traits
instance.
</P>

<P>
The storing of the pointer to the selected Transport, for each thread
is managed by modifying the following TAO classes, instances of which
are created on the stack during request/response processing:
</P>


<P>
<H3>
Implementation and Required Changes
</H3>

<P>
The primary implementation is predicated upon usage of thread specific
storage (TSS) and the guarantees C++ provides for calling the
constructor and the destructor of automatic (stack-based)
objects. Some existing objects, used in TAO will have to be modified
and the necessary changes, both for client and the server side are
detailed below.
</P>

<H4>
Client Side: Sending Requests or Replies
</H4>


<P>
The Profile_Transport_Resolver instance contains the reference to the
Transport that is needed to extract protocol-specific information. An
instance of Profile_Transport_Resolver lives on the stack, starting
inside a call to Invocation_Adapter::invoke_remote_i(), or
LocateRequest_Invocation_Adapter::invoke(). In the case of collocated
invocations no such object is created.
</P>

<P>
It is then passed around the calls that follow, except for the calls
to the following Invocation_Base methods: send_request_interception(),
receive_other_interception(), receive_reply_interception(),
handle_any_exception(), handle_all_exception();
</P>

<P>
Note that these in turn call the client-side interception points and
that is where information about the transport will be needed. In order
to make the transport information accessible inside those methods, we
propose to change Profile_Transport_Resolver class to call: ...
</P>

<PRE>
...

this->stub_->orb_core ()->transport_listener_manager_notify (this->transport_);

...
</PRE>


<P>
from within its constructor. The rest of the TC framework will make
sure this pointer is stored in a thread-specific storage.
</P>

<P>
Inside an interceptor then, one can use a Transport Current to obtain
a specialized Traits instance. It then will have to be _downcast() to
the specific type. A pointer to the transport will be made available
through a TSS slot, managed by the Profile_Transport_Resolver.
</P>



<H4>
Server Side: Request Processing
</H4>


<P>
On the server side, the TAO_ServerRequest instance already has a
Transport pointer. The TAO_ServerRequest lives on the stack, starting
its life inside a call to TAO_GIOP_Message_Base::process_request().
</P>

<P>
Similarly to the client-side, we propose that TAO_ServerRequest
constructor make a call like this:
</P>

<PRE>
...
  // Tell anyone who would listen that we have a transport                                                                
  this->orb_core_->transport_listener_manager_notify (this->transport_);
...
</PRE>

<P>
n the collocated case there may not be a transport available, so the
TSS slot will be null.
</P>

<P>
Inside an interceptor then, one can use an RIR-resolved
TransportCurrent to create a specialization of TransportInfo, based on
the kind of Transport used. Then they would _downcast() it to the
specific type.
</P>

<H3>
Performance Impact
</H3>

<P>
As the implementation of the Transport Current functionality
necessitates some additional processing on the critical path of an
invocation, we are expecting a performance impact when the
functionality is being used. 
</P>

<P>
It is possible at build time, to
disable the functionality, so that applications only incur the penalty
if they require it. The ORB will not support the Transport Current functionality. The following #define will enable it:
</P>

<PRE>
#define TAO_HAS_TRANSPORT_CURRENT 1
</PRE>


</BODY>
</HTML>