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
|
// -*- Mode: C++; -*-
// Package : omniORB2
// giopDriver.h Created on: 6/2/96
// Author : Sai Lai Lo (sll)
//
// Copyright (C) 1996-1999 AT&T Laboratories Cambridge
//
// This file is part of the omniORB library
//
// The omniORB library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA
//
//
// Description:
// *** PROPRIETORY INTERFACE ***
//
/*
$Log: giopDriver.h,v $
Revision 1.1.2.2 1999/09/30 11:49:27 djr
Implemented catching user-exceptions in GIOP_S for all compilers.
Revision 1.1.2.1 1999/09/24 09:51:45 djr
Moved from omniORB2 + some new files.
Revision 1.11 1999/06/26 17:55:19 sll
Added new exception return type terminateProcessing.
Revision 1.10 1999/06/18 21:14:44 sll
Updated copyright notice.
Revision 1.9 1999/06/18 20:36:18 sll
Replaced _LC_attr with _core_attr.
Revision 1.8 1999/01/07 18:32:42 djr
Replaced _OMNIORB_NTDLL_IMPORT with _LC_attr.
Revision 1.7 1998/04/07 20:03:01 sll
Replace _OMNIORB2_NTDLL_ specification on class GIOP_basetypes
_OMNIORB_NTDLL_IMPORT on static member constants.
Revision 1.6 1997/08/21 22:20:50 sll
New system exception TRANSACTION_REQUIRED, TRANSACTION_ROLLEDBACK,
INVALID_TRANSACTION and WRONG_TRANSACION.
* Revision 1.5 1997/05/06 16:08:20 sll
* Public release.
*
*/
#ifndef __GIOPDRIVER_H__
#define __GIOPDRIVER_H__
#ifndef __OMNIOBJKEY_H__
#include <omniORB3/omniObjKey.h>
#endif
// The GIOP_C and GIOP_S classes are defined to drive the General Inter-ORB
// Protocol (GIOP). The GIOP protocol is asymmetric. GIOP_C provides the
// functions to drive the client side protocol. GIOP_S provides the server
// side functions.
//
// GIOP_C and GIOP_S are built on top of a strand. Direct access to the strand
// can be done via the NetBufferedStream class which is a public base
// class of GIOP_C and GIOP_S. Typically clients of GIOP_C and GIOP_S uses
// the NetBufferedStream interface to marshall and unmarshall arguments.
//
// Calling the constructors of GIOP_C and GIOP_S acquire a strand.
// GIOP_C and GIOP_S implements the appropriate exclusive access to the
// strand according to their internal states.
class GIOP_Basetypes {
public:
class MessageHeader {
public:
typedef _CORBA_Char HeaderType[8];
static _core_attr const HeaderType Request;
static _core_attr const HeaderType Reply;
static _core_attr const HeaderType CancelRequest;
static _core_attr const HeaderType LocateRequest;
static _core_attr const HeaderType LocateReply;
static _core_attr const HeaderType CloseConnection;
static _core_attr const HeaderType MessageError;
};
struct _SysExceptRepoID {
_CORBA_Char *id;
_CORBA_ULong len;
_SysExceptRepoID(_CORBA_Char *i) {
id = i; len = strlen((const char *)i);
}
};
class SysExceptRepoID {
public:
static _core_attr const _SysExceptRepoID UNKNOWN;
static _core_attr const _SysExceptRepoID BAD_PARAM;
static _core_attr const _SysExceptRepoID NO_MEMORY;
static _core_attr const _SysExceptRepoID IMP_LIMIT;
static _core_attr const _SysExceptRepoID COMM_FAILURE;
static _core_attr const _SysExceptRepoID INV_OBJREF;
static _core_attr const _SysExceptRepoID OBJECT_NOT_EXIST;
static _core_attr const _SysExceptRepoID NO_PERMISSION;
static _core_attr const _SysExceptRepoID INTERNAL;
static _core_attr const _SysExceptRepoID MARSHAL;
static _core_attr const _SysExceptRepoID INITIALIZE;
static _core_attr const _SysExceptRepoID NO_IMPLEMENT;
static _core_attr const _SysExceptRepoID BAD_TYPECODE;
static _core_attr const _SysExceptRepoID BAD_OPERATION;
static _core_attr const _SysExceptRepoID NO_RESOURCES;
static _core_attr const _SysExceptRepoID NO_RESPONSE;
static _core_attr const _SysExceptRepoID PERSIST_STORE;
static _core_attr const _SysExceptRepoID BAD_INV_ORDER;
static _core_attr const _SysExceptRepoID TRANSIENT;
static _core_attr const _SysExceptRepoID FREE_MEM;
static _core_attr const _SysExceptRepoID INV_IDENT;
static _core_attr const _SysExceptRepoID INV_FLAG;
static _core_attr const _SysExceptRepoID INTF_REPOS;
static _core_attr const _SysExceptRepoID BAD_CONTEXT;
static _core_attr const _SysExceptRepoID OBJ_ADAPTER;
static _core_attr const _SysExceptRepoID DATA_CONVERSION;
static _core_attr const _SysExceptRepoID TRANSACTION_REQUIRED;
static _core_attr const _SysExceptRepoID TRANSACTION_ROLLEDBACK;
static _core_attr const _SysExceptRepoID INVALID_TRANSACTION;
static _core_attr const _SysExceptRepoID WRONG_TRANSACTION;
static _core_attr const _CORBA_ULong maxIDLen;
static _core_attr const _CORBA_Char *version;
static _core_attr const _CORBA_ULong versionLen;
#define omniORB_GIOP_Basetypes_SysExceptRepoID_maxIDLen 46
};
static _core_attr size_t max_giop_message_size;
};
class GIOP_C : public GIOP_Basetypes, public NetBufferedStream {
public:
GIOP_C(Rope *r);
~GIOP_C();
enum State { Idle,
RequestInProgress,
WaitingForReply,
ReplyIsBeingProcessed,
Zombie
};
// A GIOP_C instance operates in one of the following states:
//
// Idle - no request has been initiated
// RequestInProgress - a request is being composed, arguments
// can be marshalled into the
// NetBufferedStream
// WaitingForReply - the request has been sent, no reply
// has come in yet.
// ReplyIsBeingProcessed - a reply has started arriving, results
// can be unmarshalled from the
// NetBufferedStream
// Zombie - the destructor has been called
//
// Calling the member functions InitialiseRequest(), ReceiveReply() and
// RequestCompleted() cause the GIOP_C to change state. The state transitions
// are as follows:
// +------------+
// | | ~GIOP_C()
// +----+---+ |
// | Zombie |<-------+
// +--------+
// ^
// | ~GIOP_C()
// |
// RequestCompleted() +----+---+ InitialiseRequest()
// +---------------->| Idle |---------------+
// | +---+----+ |
// | | V
// +-----------------------+ | +--------------------+
// | ReplyIsBeingProcessed | | | RequestInProgress |
// +-----------------------+ | +---------+----------+
// ^ | |
// | | |
// | | IssueLocateRequest() |
// | | |
// | | |
// | | |
// | | |
// | V |
// | +--------------------+ |
// +---------| WaitingForReply |<-------------+
// <got a proper +--------------------+ ReceiveReply()
// reply header while
// in ReceiveReply() or IssueLocateRequest()>
//
// The constructor initialises a GIOP_C to Idle state.
//
// When the destructor is called, the state is examined. If it is *not* in
// Idle or WaitingForReply, there is something seriously wrong with the
// NetBufferedStream. Also the state of the strand, on which the
// NetBufferedStream is built, is unknown. For this reason, the strand
// is marked as dying by the destructor. The destructor may be called
// multiple times. It simply returns if the instance is already in Zombie
// state.
//
// Calling the member functions InitialiseRequest(), ReceiveReply(),
// RequestCompleted() and IssueLocateRequest() while the GIOP_C is not
// in the appropriate state as indicated above would cause a
// CORBA::INTERNAL() exception to be raised.
//
void InitialiseRequest(const void* objkey,
const size_t objkeysize,
const char* opname,
const size_t opnamesize,
const size_t msgsize,
const _CORBA_Boolean oneway);
// Initialise a Request message.
// Note: <msgsize> is the size of the whole message including the
// GIOP message header and the Request message header.
GIOP::ReplyStatusType ReceiveReply();
void RequestCompleted(_CORBA_Boolean skip=0);
GIOP::LocateStatusType IssueLocateRequest(const void *objkey,
const size_t objkeysize);
static size_t RequestHeaderSize(const size_t objkeysize,
const size_t opnamesize);
// Return the header size. This includes the size of the GIOP message
// header and the Request message header.
size_t MaxMessageSize() const { return pd_max_message_size; }
// Returns the maximum size of a GIOP message (excluding the header) that
// can be delivered or received. This value is the smallest of two
// values: the ORB-wide limit and the transport dependent limit.
//
// If an incoming message exceeds this limit, the message will not be
// unmarshalled and the CORBA::COMM_FAILURE exception will be raised. The
// connection is closed as a result.
//
// If an outgoing message exceeds this limit, the CORBA::MARSHAL exception
// will be raised.
private:
State pd_state;
_CORBA_ULong pd_request_id;
_CORBA_Boolean pd_response_expected;
size_t pd_max_message_size;
void UnMarshallSystemException();
};
class GIOP_S : public GIOP_Basetypes, public NetBufferedStream {
public:
static void dispatcher(Strand *s);
// This is the first level dispatcher. Its task is to take GIOP
// message(s) from a strand. It will handle one or more GIOP messages
// until it receives a Request message (see below), when that happens
// it will return to the caller after the request is processed.
//
// If the message is any of these:
// LocateRequest,
// CancelRequest,
// MessageError,
// CloseConnection
// it is handled by the dispatcher.
//
// If the message is Request, the dispatcher would locate the object
// implementation and perform an upcall to the stub level dispatcher of
// that object.
//
GIOP_S(Strand *s);
~GIOP_S();
enum State { Idle,
RequestIsBeingProcessed,
WaitingForReply,
ReplyIsBeingComposed,
Zombie
};
// A GIOP_S instance operates in one of the following states:
//
// Idle - no request has been received
// RequestIsBeingProcessed - a request is being processed, arguments
// can be unmarshalled from the
// NetBufferedStream
// WaitingForReply - An upcall has been dispatched into
// the object implementation
// ReplyIsBeingComposed - a reply is being composed, results
// can be marshalled into the
// NetBufferedStream
// Zombie - the destructor has been called
//
// Calling the member functions RequestReceived(), InitialiseReply() and
// ReplyCompleted() cause the GIOP_S to change state. The state transitions
// are as follows:
//
// +------------+
// | | ~GIOP_S()
// +----+---+ |
// | Zombie |<-------+
// +--------+
// ^
// | ~GIOP_S()
// pd_response_expected && |
// ReplyCompleted() +----+---+ <dispatcher() got a valid
// +---------------->| Idle |---------------+ request>
// | +--------+ |
// | ^ V
// +-----------------------+ | +--------------------------+
// | ReplyIsBeingComposed | | | RequestIsBeingProcessed |
// +-----------------------+ | +-----------------+--------+
// ^ | !pd_response_expected && |
// | | ReplyCompleted() |
// | +--------------------+ |
// +---------| WaitingForReply |<------------------+
// InitialiseReply() +--------------------+ RequestReceived()
//
//
// The dispatcher() encapsulates the upcall to the stub level dispatcher
// with a try block that catches all system exceptions. The exception
// handlers deal with an exception according to the state of the GIOP_S
// at the time:
//
// 1. If a system exception is caught when arguments are unmarshalled or
// results are marshalled, i.e. the GIOP_S is either in
// RequestIsBeingProcessed or ReplyIsBeingComposed,
// something is seriously wrong in the marshalling or unmarshalling
// and cannot recover without destroying the strand. The destructor
// is called with the state unchanged.
//
// 2. If a system exception is caught while the strand is in
// WaitingForReply, the dispatcher() would completed internally the
// reply sequence and propagate the exception back to the client.
//
// The destructor examines the state, if it is *not* in Idle, there is
// something seriously wrong with the NetBufferedStream. Also the state
// of the strand, on which the NetBufferedStream is built, is unknown.
// For this reason, the strand is marked as dying by the destructor. The
// destructor may be called multiple times. It simply returns if the instance
// is already in Zombie state.
//
// Calling the member functions RequestReceived(), InitialiseReply() and
// ReplyCompleted() while the GIOP_S is not in the appropriate state as
// indicated above would cause a CORBA::INTERNAL() exception to be raised.
//
void RequestReceived(_CORBA_Boolean skip=0);
void InitialiseReply(const GIOP::ReplyStatusType status, size_t msgsize);
// Initialise a Reply message
// Note: <msgsize> is the size of the whole message including the
// GIOP message header and the Request message header
void ReplyCompleted();
static size_t ReplyHeaderSize();
// Return the reply header size. This includes the size of the GIOP message
// header and the Reply message header
inline size_t MaxMessageSize() const { return pd_max_message_size; }
// Returns the maximum size of a GIOP message (excluding the header) that
// can be delivered or received. This value is the smallest of two
// values: the ORB-wide limit and the transport dependent limit.
//
// If an incoming message exceeds this limit, a MessageError message
// will be sent and the CORBA::COMM_FAILURE exception will be raised. The
// connection is closed as a result.
//
// If an outgoing message exceeds this limit, the CORBA::MARSHAL exception
// will be raised.
inline const _CORBA_Octet* key() const { return pd_key.key(); }
inline int keysize() const { return pd_key.size(); }
inline const char* operation() const { return (const char*) pd_operation; }
inline _CORBA_Boolean response_expected() const {
return pd_response_expected;
}
inline void set_user_exceptions(const char*const* ues, int n) {
pd_user_exns = ues; pd_n_user_exns = n;
}
// These may only be called in the context of an operation invocation.
void SendMsgErrorMessage();
class terminateProcessing {
public:
// This exception is thrown when the processing of the current giop
// request should terminte.
inline terminateProcessing() {}
inline ~terminateProcessing() {}
};
private:
State pd_state;
_CORBA_ULong pd_request_id;
_CORBA_Boolean pd_response_expected;
size_t pd_max_message_size;
#define OMNIORB_GIOPDRIVER_GIOP_S_INLINE_BUF_SIZE 32
_CORBA_Octet* pd_operation;
_CORBA_Octet pd_op_buffer[OMNIORB_GIOPDRIVER_GIOP_S_INLINE_BUF_SIZE];
_CORBA_Octet* pd_principal;
_CORBA_Octet pd_pr_buffer[OMNIORB_GIOPDRIVER_GIOP_S_INLINE_BUF_SIZE];
omniObjKey pd_key;
// In the context of an operation invocation, this
// is the object key being invoked.
const char*const* pd_user_exns;
int pd_n_user_exns;
// A list of the user exceptions that current operation may
//
void HandleRequest(_CORBA_Boolean byteorder);
void HandleLocateRequest(_CORBA_Boolean byteorder);
void HandleCancelRequest(_CORBA_Boolean byteorder);
void HandleMessageError();
void HandleCloseConnection();
void MaybeMarshalUserException(void*);
// Okay -- the void* is a nasty hack. Its actually
// a CORBA::UserException*.
};
#endif // __GIOPDRIVER_H__
|