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 __stdcall 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
|