summaryrefslogtreecommitdiff
path: root/TAO/IIOP/lib/bridge/tcpoa.hh
blob: 47212d4f22bdbc6e88dc688ec9d758ec3f86e9e1 (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
// @(#)tcpoa.hh	1.6 95/10/02
// Copyright 1994-1995 by Sun Microsystems Inc.
// All Rights Reserved
//
// Simple "TCP" OA ... lets one create objrefs very thinly layered atop
// TCP addressing.  This OA holds no state whatsoever (!!!!), and only
// supports transient objects.
//
// You may well want to build more "advanced" OAs on top of this one,
// providing features such as activation of persistent objects.  (The
// BOA, for example, provides a persistent object activation facility.)
//
// In particular:  you will probably want to build atop this to plug in
// skeletons for any language binding, mapping individual objrefs to type
// and implementation information so support for CORBA::Object operations
// such as get_interface(), is_a(), get_implementation(), and the test for
// non-existence can all be handled by an Object Adapter, not by any
// application code.
//
// This might also be the appropriate level to define interfaces that'd
// let MT-unsafe window system toolkits hardwire their event dispatch
// frameworks into the one used by this ORB.  For MT-safe window system
// toolkits, such integration is not needed because everything works
// fine if the application just allocates one thread to handle dispatch
// of each subsystem's events (e.g. ORB, GUI, etc).
//

#ifndef	_TCPOA_HH
#define	_TCPOA_HH

class _EXPCLASS TCP_OA;
typedef TCP_OA	*TCP_OA_ptr;

extern const IID IID_TCP_OA;

class _EXPCLASS TCP_OA : public TOA {
  public:
    ////////////////////////////////////////////////////////////////////////
    //
    // TOA support ... TOA is intended to be a public API that anyone can
    // use, including skeletons.
    //
    ////////////////////////////////////////////////////////////////////////

    CORBA_Object_ptr __stdcall	create (
				    CORBA_OctetSeq	&obj_id,
				    CORBA_String	type_id,
				    CORBA_Environment	&env
				);

    void __stdcall		register_dir (
				    TOA::dsi_handler	handler,
				    void		*context,
				    CORBA_Environment	&env
				);
    
    void __stdcall		get_request  (
				    CORBA_Boolean	use_threads,
				    struct timeval	*tvp,
				    CORBA_Environment	&env
				);

    void __stdcall		please_shutdown (
				    CORBA_Environment	&env
				);

    //
    // Stuff required for COM IUnknown support
    //
    ULONG __stdcall		AddRef ();
    ULONG __stdcall		Release ();
    HRESULT __stdcall           QueryInterface (
				    REFIID	riid,
				    void	**ppv
				);


    ////////////////////////////////////////////////////////////////////////
    //
    // TCP_OA SPECIFIC from here on down ... all of this is subject to
    // change and simplification.  It's intended to be an internal API
    // providing efficient access to all basic IIOP functionality.
    //
    ////////////////////////////////////////////////////////////////////////

    //
    // OA initialisation, per the template in OMG TC doc 94-9-46
    //
    // NOTE that since this OA is not defined by OMG, it doesn't
    // go into the CORBA (and hence ORB) scope and acquiring this
    // OA is not an operation on any particular ORB.
    //
    // Also, this needs no configuration beyond which OA is used;
    // there's no need for argc/argv to control any initialization
    // options.
    //
    static TCP_OA_ptr		init (
				    CORBA_ORB_ptr	which_orb,
				    char		*oa_name,
				    CORBA_Environment	&env
				);

    //
    // Block till some request comes in, or "timeout" passes.  Handle any
    // requests with "handle_request", passing it "context" for access to
    // non-global application state.
    //
    // If the "do_thr_create" flag is set, "handle_request" is invoked in
    // a new thread rather than by the calling thread.
    //
    // If "check_forward" is null, all incoming requests are passed to
    // handle_request() and requests for objects can't be forwarded so
    // they arrive at any other process. 
    //
    // If "check_forward" is non-null, the function is called when the OA
    // needs to establish whether a request for a particular object (as
    // identified by "key") are handled in this process.  If it returns an
    // exception, the object is deemed not to exist (this is authoritative).
    // If the "fwd_ref" returned is non-null, the request is forwarded to
    // that object reference.  Otherwise (no exception, null "fwd_ref")
    // requests for that object may arrive via handle_request().
    //
    // This routine returns after a request arrives, regardless of whether
    // a thread started processing.
    //
    void __stdcall		get_request (
				    TOA::dsi_handler	handle_request,
				    void		check_forward (
					CORBA_OctetSeq		&key,
					CORBA_Object_ptr	&fwd_ref,
					void			*context,
					CORBA_Environment	&env
				    ),
				    CORBA_Boolean	do_thr_create,
				    void		*context,
				    timeval		*timeout,
				    CORBA_Environment	&env
				);

    //
    // OA user asks for a clean shutdown of the OA after currently
    // active calls complete.  OA "requester" (calls get_request)
    // asks if we're shutting down, and if so closes down transport
    // cleanly.
    //
    CORBA_Boolean		shutting_down ()
				{ return do_exit; }

    void			clean_shutdown (
				    CORBA_Environment	&env
				);

    //
    // When dispatching a request to an object, you need to be able to get
    // the object key you used to create the reference.  It's the main way
    // servers distinguish two object references from each other.
    //
    CORBA_OctetSeq 		*__stdcall get_key (
				    CORBA_Object_ptr	obj,
				    CORBA_Environment	&env
				);
    
    //
    // OA-specific state
    //
    CORBA_ORB_ptr		orb () const { return _orb; }

    //
    // Various request-specific state.
    //
    CORBA_OctetSeq 		*__stdcall get_target_key (
				    CORBA_Environment	&env
				);
    CORBA_Principal_ptr	__stdcall	get_client_principal (
				    CORBA_Environment	&env
				);

  // PRIVATE: 

    //
    // Data structure passed as "context" to the GIOP code, which then
    // calls back one of the two helper routines as part of handling any
    // particular incoming request.
    //
    struct dispatch_context {
	TOA::dsi_handler	skeleton;
	void			(*check_forward) (
				    CORBA_OctetSeq	&key,
				    CORBA_Object_ptr	&fwd_ref,
				    void		*context,
				    CORBA_Environment	&env
				);
	void			*context;
	TCP_OA			*oa;
	autorelease <server_endpoint>
				endpoint;
#ifdef	_POSIX_THREADS
	CORBA_Boolean		aggressive;
#endif	// _POSIX_THREADS
    };

  private:
    CORBA_UShort		port;
    CORBA_Boolean		do_exit;
    CORBA_ORB_ptr		_orb;
    unsigned			call_count;
    unsigned			refcount;
    server_endpoint		*endpoint;

    TOA::dsi_handler		skeleton;
    void			*context;

    //
    // Used internally by threaded (and unthreaded) code to
    // dispatch incoming GIOP messages
    //
    void			handle_message (
				    dispatch_context	&context,
				    CORBA_Environment	&env
				);

#ifdef	_POSIX_THREADS
    //
    // Used internally by threaded code to process incoming messages.
    //
    static void			*worker (void *arg);
#endif	// _POSIX_THREADS

    //
    // Constructor -- build it with a port number to listen to
    //
				TCP_OA (
				    CORBA_ORB_ptr	orb_arg,
				    CORBA_UShort	port,
				    CORBA_Environment	&env
				);
				virtual ~TCP_OA ();

    //
    // Copy and assignment:  just say no
    //
				TCP_OA (const TCP_OA &src);
    TCP_OA			&operator = (const TCP_OA &src);

#if	defined (__GNUG__)
    //
    // G++ (even 2.6.3) stupidly thinks instances can't be
    // created.  This de-warns.
    //
    friend class everyone_needs_a_friend;
#endif
};

typedef TCP_OA	*TCP_OA_ptr;


//
// Method code (only!) is defined to have access to three functions, for
// the orb, object, and OA involved in a call.
//
// In this version we implement these by access through routines that
// use thread-specific data in multithreaded environments; the routines
// themselves (implementation of the symbol) are not public, but the
// symbol is usable in any method code.
//
// NOTE: it'd be preferable to define the "orb" and "tcp_oa" symbols
// only within method code (e.g. protected member functions on some
// servant base class), but as we don't yet implement much server
// side mapping that's impractical.
//
// XXX many of these are now methods on CORBA_ServerRequest...
//
extern	CORBA_Object_ptr __stdcall	_this (void);

#endif	// _TCPOA_HH