8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 06:43:03 +01:00

Remote cleanup:

1. Avoid ALLR memory allocation routine (use new / delete).
2. Use common (TypedHandle) class to control consistency of handles.
3. Make ctors and dtors work - in most cases more work is needed to make them meaningful.
This commit is contained in:
alexpeshkoff 2008-03-24 15:28:38 +00:00
parent cd1453f109
commit 6809f624fc
15 changed files with 925 additions and 1474 deletions

View File

@ -1,199 +0,0 @@
/*
* PROGRAM: JRD Remote Interface/Server
* MODULE: allr.cpp
* DESCRIPTION: Internal block allocator
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include <stdlib.h>
#include <string.h>
#include "../remote/remote.h"
#include "gen/iberror.h"
#include "../remote/allr_proto.h"
#include "../common/classes/alloc.h"
static const struct
{
blk_t type;
USHORT typ_root_length;
USHORT typ_tail_length;
} REM_block_sizes[] =
{
{type_MIN , 0, 0},
{type_vec , sizeof(rem_vec) , sizeof(((rem_vec*) NULL)->vec_object[0])},
{type_rdb , sizeof(rdb) , 0},
{type_fmt , sizeof(rem_fmt) , sizeof(dsc/*((rem_fmt*) NULL)->fmt_desc[0]*/)},
{type_rrq , sizeof(rrq) , sizeof(((rrq*) NULL)->rrq_rpt [0])},
{type_rtr , sizeof(rtr) , 0},
{type_str , sizeof(rem_str) , 1}, // random string block
{type_rbl , sizeof(rbl) , 1},
{type_port , sizeof(rem_port) , 1},
{type_msg , sizeof(message) , 1},
{type_rsr , sizeof(rsr) , 0},
{type_rvnt , sizeof(rvnt) , 0},
{type_rpr , sizeof(rpr) , 0},
{type_rmtque , sizeof(rmtque) , 0},
{type_MAX, 0, 0}
};
//____________________________________________________________
//
// Allocate a block.
//
#ifdef DEBUG_GDS_ALLOC
UCHAR* ALLR_alloc_debug(ULONG size, const TEXT* FileName, ULONG LineNumber)
#else
UCHAR* ALLR_alloc(ULONG size)
#endif
{
UCHAR* block = (UCHAR*)
#ifdef DEBUG_GDS_ALLOC
gds__alloc_debug((SLONG)size, FileName, LineNumber);
#else
gds__alloc((SLONG) size);
#endif
if (block)
{
return block;
}
// FREE: caller must free - usually using ALLR_free.
// NOMEM: post a user level error, if we have a status vector,
// otherwise just an error return
Firebird::BadAlloc::raise();
return NULL; /* compiler silencer */
}
//____________________________________________________________
//
// Allocate a block from a given pool and initialize the block.
// This is the primary block allocation routine.
//
#ifdef DEBUG_GDS_ALLOC
BLK ALLR_block_debug(UCHAR type, ULONG count, const TEXT* FileName, ULONG LineNumber)
#else
BLK ALLR_block(UCHAR type, ULONG count)
#endif
{
if (type <= (UCHAR) type_MIN || type >= (UCHAR) type_MAX)
{
Firebird::BadAlloc::raise();
}
ULONG size = REM_block_sizes[type].typ_root_length;
ULONG tail = REM_block_sizes[type].typ_tail_length;
if (tail && count > 1) {
size += (count - 1) * tail;
}
BLK block = (BLK)
#ifdef DEBUG_GDS_ALLOC
ALLR_alloc_debug(size, FileName, LineNumber);
#else
ALLR_alloc(size);
#endif
// NOMEM: callee handled
// FREE: caller must handle - use ALLR_free
block->blk_type = type;
block->blk_length = size;
size -= sizeof(struct blk);
if (size) {
memset((char*)block + sizeof(struct blk), 0, size);
}
return block;
}
//____________________________________________________________
//
// Clone a block.
//
// Caller is responsible for free'ing the clone
//
BLK ALLR_clone(BLK block)
{
ULONG l = block->blk_length;
BLK clone = (BLK) ALLR_alloc(l);
// NOMEM: ALLR_alloc() handled
// FREE: caller must handle - use ALLR_free
memcpy(clone, block, l);
return clone;
}
//____________________________________________________________
//
// Free a block.
//
void ALLR_free( void *block)
{
gds__free(block);
}
//____________________________________________________________
//
// Allocate a vector.
//
rem_vec* ALLR_vector(rem_vec** ptr, ULONG count)
{
++count;
rem_vec* vector = *ptr;
if (!vector) {
vector = *ptr = (rem_vec*) ALLR_block(type_vec, count);
vector->vec_count = count;
return vector;
}
/* If it fits, do it */
if (count <= vector->vec_count)
return vector;
rem_vec* new_vector = *ptr = (rem_vec*) ALLR_block(type_vec, count);
new_vector->vec_count = count;
blk** p = new_vector->vec_object;
blk* const* q = vector->vec_object;
const blk* const* const end = q + (int) vector->vec_count;
while (q < end) {
*p++ = *q++;
}
ALLR_free(vector);
return new_vector;
}

View File

@ -1,45 +0,0 @@
/*
* PROGRAM: JRD Remote Interface/Server
* MODULE: allr_proto.h
* DESCRIPTION: Prototype header file for allr.cpp
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef REMOTE_ALLR_PROTO_H
#define REMOTE_ALLR_PROTO_H
struct blk;
struct rem_vec;
#ifdef DEBUG_GDS_ALLOC
#define ALLR_alloc(s) ALLR_alloc_debug((s), (TEXT*)__FILE__, (ULONG)__LINE__)
#define ALLR_block(s, sz) ALLR_block_debug((s), (sz), (TEXT*)__FILE__, (ULONG)__LINE__)
UCHAR* ALLR_alloc_debug(ULONG, const TEXT*, ULONG);
blk* ALLR_block_debug(UCHAR, ULONG, const TEXT*, ULONG);
#else //DEBUG_GDS_ALLOC
UCHAR* ALLR_alloc(ULONG);
blk* ALLR_block(UCHAR, ULONG);
#endif //DEBUG_GDS_ALLOC
blk* ALLR_clone(blk*);
void ALLR_free (void *);
rem_vec* ALLR_vector (rem_vec**, ULONG);
#endif // REMOTE_ALLR_PROTO_H

View File

@ -247,7 +247,6 @@ static rem_port* aux_request(rem_port*, PACKET*);
static int check_host(rem_port*, TEXT*, const TEXT*, const struct passwd*);
static bool check_proxy(rem_port*, TEXT*, Firebird::string&);
#endif // WIN_NT
static void cleanup_port(rem_port*);
static void disconnect(rem_port*);
static void exit_handler(void *);
@ -393,7 +392,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
/* We need to establish a connection to a remote server. Allocate the necessary
blocks and get ready to go. */
RDB rdb = (RDB) ALLR_block(type_rdb, 0);
RDB rdb = new Rdb;
PACKET* packet = &rdb->rdb_packet;
/* Pick up some user identification information */
@ -531,7 +530,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
Firebird::string temp;
temp.printf("%s/P%d", port->port_version->str_data,
port->port_protocol & FB_PROTOCOL_MASK);
ALLR_free(port->port_version);
delete port->port_version;
port->port_version = REMOTE_make_string(temp.c_str());
if (packet->p_acpt.p_acpt_architecture == ARCHITECTURE) {
@ -605,9 +604,7 @@ rem_port* INET_connect(const TEXT* name,
}
if (host.hasData()) {
if (port->port_connection) {
ALLR_free(port->port_connection);
}
delete port->port_connection;
port->port_connection = REMOTE_make_string(host.c_str());
}
else {
@ -1207,11 +1204,7 @@ static rem_port* alloc_port( rem_port* parent)
INET_initialized = true;
}
rem_port* port = (rem_port*) ALLR_block(type_port, INET_remote_buffer * 2);
port->port_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_sync->addRef();
port->port_type = port_inet;
port->port_state = state_pending;
rem_port* port = new rem_port(rem_port::INET, INET_remote_buffer * 2);
REMOTE_get_timeout_params(port, 0);
TEXT buffer[BUFFER_SMALL];
@ -1242,25 +1235,10 @@ static rem_port* alloc_port( rem_port* parent)
0,
XDR_DECODE);
#ifdef REM_SERVER
port->port_queue = FB_NEW(*getDefaultMemoryPool())
Firebird::ObjectsArray< Firebird::Array< char > >(*getDefaultMemoryPool());
port->port_qoffset = 0;
port->port_que_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_que_sync->addRef();
#endif
if (parent && !(parent->port_server_flags & SRVR_thread_per_port))
{
Firebird::MutexLockGuard guard(port_mutex);
port->port_parent = parent;
port->port_next = parent->port_clients;
port->port_handle = parent->port_handle;
port->port_server = parent->port_server;
port->port_server_flags = parent->port_server_flags;
parent->port_clients = parent->port_next = port;
port->linkParent(parent);
}
return port;
@ -1338,10 +1316,6 @@ static rem_port* aux_connect(rem_port* port, PACKET* packet, t_event_ast ast)
address.sin_family = AF_INET;
address.sin_port = ((struct sockaddr_in *)(response->p_resp_data.cstr_address))->sin_port;
int optval = 1;
setsockopt((SOCKET) port->port_handle, SOL_SOCKET, SO_KEEPALIVE,
(SCHAR*) &optval, sizeof(optval));
status = connect(n, (struct sockaddr *) &address, sizeof(address));
const int inetErrNo = INET_ERRNO;
@ -1566,12 +1540,8 @@ static bool check_proxy(rem_port* port,
&& (!strcmp(source_user, user_name.c_str())
|| !strcmp(source_user, "*")))
{
ALLR_free(port->port_user_name);
const SLONG length = strlen(target_user);
rem_str* string = (rem_str*) ALLR_block(type_str, (int) length);
port->port_user_name = string;
string->str_length = length;
strncpy(string->str_data, target_user, length);
delete port->port_user_name;
port->port_user_name = REMOTE_make_string(target_user);
user_name = target_user;
result = true;
break;
@ -1639,7 +1609,7 @@ static void disconnect( rem_port* port)
/* If this is a sub-port, unlink it from it's parent */
bool defer_cleanup = false;
port->port_state = state_disconnected;
port->port_state = rem_port::DISCONNECTED;
rem_port* parent = port->port_parent;
if (parent != NULL) {
@ -1664,7 +1634,7 @@ static void disconnect( rem_port* port)
gds__unregister_cleanup(exit_handler, (void *) port);
if (!defer_cleanup) {
cleanup_port(port);
delete port;
}
#ifdef DEBUG
@ -1685,60 +1655,6 @@ static void disconnect( rem_port* port)
}
static void cleanup_port( rem_port* port)
{
/**************************************
*
* c l e a n u p _ p o r t
*
**************************************
*
* Functional description
* Walk through the port structure freeing
* allocated memory and then free the port.
*
**************************************/
if (port->port_version)
ALLR_free(port->port_version);
if (port->port_connection)
ALLR_free(port->port_connection);
if (port->port_user_name)
ALLR_free(port->port_user_name);
if (port->port_host)
ALLR_free(port->port_host);
if (port->port_object_vector)
ALLR_free(port->port_object_vector);
if (port->port_protocol_str)
ALLR_free(port->port_protocol_str);
if (port->port_address_str)
ALLR_free(port->port_address_str);
#ifdef DEBUG_XDR_MEMORY
if (port->port_packet_vector)
ALLR_free(port->port_packet_vector);
#endif
#ifdef REM_SERVER
delete port->port_queue;
port->port_que_sync->release();
#endif
#ifdef TRUSTED_AUTH
delete port->port_trusted_auth;
#endif
port->port_sync->release();
ALLR_free(port);
return;
}
static void exit_handler( void *arg)
{
/**************************************
@ -1765,9 +1681,9 @@ static void exit_handler( void *arg)
#endif
for (rem_port* port = main_port; port; port = port->port_next)
if (port->port_state != state_broken)
if (port->port_state != rem_port::BROKEN)
{
port->port_state = state_broken;
port->port_state = rem_port::BROKEN;
shutdown((int) port->port_handle, 2);
SOCLOSE((SOCKET) port->port_handle);
}
@ -2101,7 +2017,7 @@ static rem_port* receive( rem_port* main_port, PACKET * packet)
main_port->port_flags &= ~PORT_partial_data;
if (packet->p_operation == op_exit) {
main_port->port_state = state_broken;
main_port->port_state = rem_port::BROKEN;
}
break;
}
@ -2147,9 +2063,9 @@ static rem_port* select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize
{
if (INET_shutting_down)
{
if (main_port->port_state != state_broken)
if (main_port->port_state != rem_port::BROKEN)
{
main_port->port_state = state_broken;
main_port->port_state = rem_port::BROKEN;
SOCKET s = (SOCKET) main_port->port_handle;
shutdown(s, 2);
SOCLOSE(s);
@ -2324,7 +2240,7 @@ static int select_wait( rem_port* main_port, SLCT * selct)
unhook_disconnected_ports(main_port);
for (rem_port* port = main_port; port; port = port->port_next)
{
if (port->port_state == state_pending)
if (port->port_state == rem_port::PENDING)
{
/* Adjust down the port's keepalive timer. */
@ -2592,7 +2508,7 @@ static void inet_gen_error( rem_port* port, ISC_STATUS status, ...)
* save the status vector strings in a permanent place.
*
**************************************/
port->port_state = state_broken;
port->port_state = rem_port::BROKEN;
ISC_STATUS* status_vector = NULL;
if (port->port_context != NULL) {
@ -2987,7 +2903,7 @@ static rem_port* inet_try_connect(
rem_port* port = INET_connect(node_name, packet, status_vector, FALSE, &dpb);
if (!port) {
ALLR_free(rdb);
delete rdb;
return NULL;
}
@ -2999,7 +2915,7 @@ static rem_port* inet_try_connect(
inet_error(port, "receive in try_connect", isc_net_connect_err,
INET_ERRNO);
disconnect(port);
ALLR_free(rdb);
delete rdb;
return NULL;
}
@ -3475,11 +3391,11 @@ static void unhook_disconnected_ports(rem_port* main_port)
Firebird::RefMutexEnsureUnlock portGuard(*port->port_sync);
if (portGuard.tryEnter()) {
if (port->port_state == state_disconnected) {
if (port->port_state == rem_port::DISCONNECTED) {
more = true;
unhook_port(port, port->port_parent);
portGuard.leave();
cleanup_port(port);
delete port;
break;
}
else {

View File

@ -28,78 +28,78 @@
extern "C" {
#endif
ISC_STATUS REM_attach_database(ISC_STATUS*, SSHORT, const SCHAR*, struct rdb**,
ISC_STATUS REM_attach_database(ISC_STATUS*, SSHORT, const SCHAR*, struct Rdb**,
SSHORT, const SCHAR*, const UCHAR*);
ISC_STATUS REM_attach_service(ISC_STATUS *, USHORT, TEXT *, struct rdb **, USHORT, SCHAR *);
ISC_STATUS REM_blob_info(ISC_STATUS*, struct rbl**, SSHORT, const SCHAR*,
ISC_STATUS REM_attach_service(ISC_STATUS *, USHORT, TEXT *, struct Rdb **, USHORT, SCHAR *);
ISC_STATUS REM_blob_info(ISC_STATUS*, struct Rbl**, SSHORT, const SCHAR*,
SSHORT, SCHAR*);
ISC_STATUS REM_cancel_blob(ISC_STATUS *, struct rbl **);
ISC_STATUS REM_cancel_events(ISC_STATUS *, struct rdb **, SLONG *);
ISC_STATUS REM_close_blob(ISC_STATUS *, struct rbl **);
ISC_STATUS REM_commit_transaction(ISC_STATUS *, struct rtr **);
ISC_STATUS REM_commit_retaining(ISC_STATUS *, struct rtr **);
ISC_STATUS REM_compile_request(ISC_STATUS*, struct rdb**, struct rrq**,
ISC_STATUS REM_cancel_blob(ISC_STATUS *, struct Rbl **);
ISC_STATUS REM_cancel_events(ISC_STATUS *, struct Rdb **, SLONG *);
ISC_STATUS REM_close_blob(ISC_STATUS *, struct Rbl **);
ISC_STATUS REM_commit_transaction(ISC_STATUS *, struct Rtr **);
ISC_STATUS REM_commit_retaining(ISC_STATUS *, struct Rtr **);
ISC_STATUS REM_compile_request(ISC_STATUS*, struct Rdb**, struct Rrq**,
USHORT, const UCHAR*);
ISC_STATUS REM_create_blob2(ISC_STATUS*, struct rdb**, struct rtr**,
struct rbl**, BID, USHORT, const UCHAR*);
ISC_STATUS REM_create_database(ISC_STATUS*, SSHORT, const SCHAR*, struct rdb**,
ISC_STATUS REM_create_blob2(ISC_STATUS*, struct Rdb**, struct Rtr**,
struct Rbl**, BID, USHORT, const UCHAR*);
ISC_STATUS REM_create_database(ISC_STATUS*, SSHORT, const SCHAR*, struct Rdb**,
SSHORT, const SCHAR*, SSHORT, const UCHAR*);
ISC_STATUS REM_database_info(ISC_STATUS*, struct rdb**, SSHORT, const SCHAR*,
ISC_STATUS REM_database_info(ISC_STATUS*, struct Rdb**, SSHORT, const SCHAR*,
SSHORT, SCHAR*);
ISC_STATUS REM_ddl(ISC_STATUS*, struct rdb**, struct rtr**,
ISC_STATUS REM_ddl(ISC_STATUS*, struct Rdb**, struct Rtr**,
USHORT, const UCHAR*);
ISC_STATUS REM_detach_database(ISC_STATUS *, struct rdb **);
ISC_STATUS REM_detach_service(ISC_STATUS *, struct rdb **);
ISC_STATUS REM_drop_database(ISC_STATUS *, struct rdb **);
ISC_STATUS REM_allocate_statement(ISC_STATUS *, struct rdb **, struct rsr **);
ISC_STATUS REM_execute(ISC_STATUS *, struct rtr **, struct rsr **, USHORT, UCHAR *, USHORT, USHORT, UCHAR *);
ISC_STATUS REM_execute2(ISC_STATUS *, struct rtr **, struct rsr **, USHORT, UCHAR *, USHORT, USHORT, UCHAR *, USHORT, UCHAR *, USHORT, USHORT, UCHAR *);
ISC_STATUS REM_execute_immediate(ISC_STATUS*, struct rdb**, struct rtr**,
ISC_STATUS REM_detach_database(ISC_STATUS *, struct Rdb **);
ISC_STATUS REM_detach_service(ISC_STATUS *, struct Rdb **);
ISC_STATUS REM_drop_database(ISC_STATUS *, struct Rdb **);
ISC_STATUS REM_allocate_statement(ISC_STATUS *, struct Rdb **, struct Rsr **);
ISC_STATUS REM_execute(ISC_STATUS *, struct Rtr **, struct Rsr **, USHORT, UCHAR *, USHORT, USHORT, UCHAR *);
ISC_STATUS REM_execute2(ISC_STATUS *, struct Rtr **, struct Rsr **, USHORT, UCHAR *, USHORT, USHORT, UCHAR *, USHORT, UCHAR *, USHORT, USHORT, UCHAR *);
ISC_STATUS REM_execute_immediate(ISC_STATUS*, struct Rdb**, struct Rtr**,
USHORT, const TEXT*, USHORT, USHORT, const UCHAR*, USHORT, USHORT, UCHAR*);
ISC_STATUS REM_execute_immediate2(ISC_STATUS*, struct rdb**, struct rtr**,
ISC_STATUS REM_execute_immediate2(ISC_STATUS*, struct Rdb**, struct Rtr**,
USHORT, const TEXT*, USHORT, USHORT, const UCHAR*, USHORT, USHORT, UCHAR*,
USHORT, UCHAR*, USHORT, USHORT, UCHAR*);
ISC_STATUS REM_fetch(ISC_STATUS*, struct rsr**, USHORT, const UCHAR*, USHORT,
ISC_STATUS REM_fetch(ISC_STATUS*, struct Rsr**, USHORT, const UCHAR*, USHORT,
USHORT, UCHAR*);
ISC_STATUS REM_free_statement(ISC_STATUS *, struct rsr **, USHORT);
ISC_STATUS REM_insert(ISC_STATUS *, struct rsr **, USHORT, UCHAR *, USHORT, USHORT, UCHAR *);
ISC_STATUS REM_prepare(ISC_STATUS *, struct rtr **, struct rsr **, USHORT, TEXT *, USHORT, USHORT, SCHAR *, USHORT, SCHAR *);
ISC_STATUS REM_set_cursor_name(ISC_STATUS*, struct rsr**, const TEXT*, USHORT);
ISC_STATUS REM_sql_info(ISC_STATUS*, struct rsr**, SSHORT, const SCHAR*,
ISC_STATUS REM_free_statement(ISC_STATUS *, struct Rsr **, USHORT);
ISC_STATUS REM_insert(ISC_STATUS *, struct Rsr **, USHORT, UCHAR *, USHORT, USHORT, UCHAR *);
ISC_STATUS REM_prepare(ISC_STATUS *, struct Rtr **, struct Rsr **, USHORT, TEXT *, USHORT, USHORT, SCHAR *, USHORT, SCHAR *);
ISC_STATUS REM_set_cursor_name(ISC_STATUS*, struct Rsr**, const TEXT*, USHORT);
ISC_STATUS REM_sql_info(ISC_STATUS*, struct Rsr**, SSHORT, const SCHAR*,
SSHORT, SCHAR*);
ISC_STATUS REM_get_segment(ISC_STATUS *, struct rbl **, USHORT *, USHORT, UCHAR *);
ISC_STATUS REM_get_slice(ISC_STATUS*, struct rdb**, struct rtr**, BID, USHORT,
ISC_STATUS REM_get_segment(ISC_STATUS *, struct Rbl **, USHORT *, USHORT, UCHAR *);
ISC_STATUS REM_get_slice(ISC_STATUS*, struct Rdb**, struct Rtr**, BID, USHORT,
const UCHAR*, USHORT, const UCHAR*, SLONG, UCHAR*, SLONG*);
ISC_STATUS REM_open_blob2(ISC_STATUS*, struct rdb**, struct rtr**,
struct rbl**, BID, USHORT, const UCHAR*);
ISC_STATUS REM_prepare_transaction(ISC_STATUS *, struct rtr **, USHORT, const UCHAR*);
ISC_STATUS REM_put_segment(ISC_STATUS*, struct rbl**, USHORT, const UCHAR*);
ISC_STATUS REM_put_slice(ISC_STATUS*, struct rdb**, struct rtr**, BID, USHORT,
ISC_STATUS REM_open_blob2(ISC_STATUS*, struct Rdb**, struct Rtr**,
struct Rbl**, BID, USHORT, const UCHAR*);
ISC_STATUS REM_prepare_transaction(ISC_STATUS *, struct Rtr **, USHORT, const UCHAR*);
ISC_STATUS REM_put_segment(ISC_STATUS*, struct Rbl**, USHORT, const UCHAR*);
ISC_STATUS REM_put_slice(ISC_STATUS*, struct Rdb**, struct Rtr**, BID, USHORT,
const UCHAR*, USHORT, const UCHAR*, SLONG, UCHAR*);
ISC_STATUS REM_que_events(ISC_STATUS*, struct rdb**, SLONG*, SSHORT,
ISC_STATUS REM_que_events(ISC_STATUS*, struct Rdb**, SLONG*, SSHORT,
const UCHAR*, FPTR_EVENT_CALLBACK, void*);
ISC_STATUS REM_query_service(ISC_STATUS *, struct rdb **, USHORT, SCHAR *, USHORT, SCHAR *, USHORT, SCHAR *);
ISC_STATUS REM_query_service(ISC_STATUS *, struct Rdb **, USHORT, SCHAR *, USHORT, SCHAR *, USHORT, SCHAR *);
#ifdef SCROLLABLE_CURSORS
ISC_STATUS REM_receive(ISC_STATUS*, struct rrq**, USHORT, USHORT, UCHAR*, SSHORT, USHORT, ULONG);
ISC_STATUS REM_receive(ISC_STATUS*, struct Rrq**, USHORT, USHORT, UCHAR*, SSHORT, USHORT, ULONG);
#else
ISC_STATUS REM_receive(ISC_STATUS *, struct rrq **, USHORT, USHORT, UCHAR *, SSHORT);
ISC_STATUS REM_receive(ISC_STATUS *, struct Rrq **, USHORT, USHORT, UCHAR *, SSHORT);
#endif
ISC_STATUS REM_reconnect_transaction(ISC_STATUS*, struct rdb**, struct rtr**,
ISC_STATUS REM_reconnect_transaction(ISC_STATUS*, struct Rdb**, struct Rtr**,
USHORT, const UCHAR*);
ISC_STATUS REM_release_request(ISC_STATUS *, struct rrq **);
ISC_STATUS REM_request_info(ISC_STATUS*, struct rrq**, SSHORT, SSHORT,
ISC_STATUS REM_release_request(ISC_STATUS *, struct Rrq **);
ISC_STATUS REM_request_info(ISC_STATUS*, struct Rrq**, SSHORT, SSHORT,
const UCHAR*, SSHORT, UCHAR*);
ISC_STATUS REM_rollback_transaction(ISC_STATUS *, struct rtr **);
ISC_STATUS REM_seek_blob(ISC_STATUS *, struct rbl **, SSHORT, SLONG, SLONG *);
ISC_STATUS REM_send(ISC_STATUS *, struct rrq **, USHORT, USHORT, UCHAR *, SSHORT);
ISC_STATUS REM_start_and_send(ISC_STATUS *, struct rrq **, struct rtr **, USHORT, USHORT, UCHAR *, SSHORT);
ISC_STATUS REM_start_request(ISC_STATUS *, struct rrq **, struct rtr **, USHORT);
ISC_STATUS REM_start_transaction(ISC_STATUS *, struct rtr **, SSHORT, struct rdb **, SSHORT, UCHAR *);
ISC_STATUS REM_transact_request(ISC_STATUS*, struct rdb**, struct rtr**,
ISC_STATUS REM_rollback_transaction(ISC_STATUS *, struct Rtr **);
ISC_STATUS REM_seek_blob(ISC_STATUS *, struct Rbl **, SSHORT, SLONG, SLONG *);
ISC_STATUS REM_send(ISC_STATUS *, struct Rrq **, USHORT, USHORT, UCHAR *, SSHORT);
ISC_STATUS REM_start_and_send(ISC_STATUS *, struct Rrq **, struct Rtr **, USHORT, USHORT, UCHAR *, SSHORT);
ISC_STATUS REM_start_request(ISC_STATUS *, struct Rrq **, struct Rtr **, USHORT);
ISC_STATUS REM_start_transaction(ISC_STATUS *, struct Rtr **, SSHORT, struct Rdb **, SSHORT, UCHAR *);
ISC_STATUS REM_transact_request(ISC_STATUS*, struct Rdb**, struct Rtr**,
USHORT, const UCHAR*, USHORT, UCHAR*, USHORT, UCHAR*);
ISC_STATUS REM_transaction_info(ISC_STATUS*, struct rtr**, SSHORT,
ISC_STATUS REM_transaction_info(ISC_STATUS*, struct Rtr**, SSHORT,
const UCHAR*, SSHORT, UCHAR*);
ISC_STATUS REM_unwind_request(ISC_STATUS *, struct rrq **, USHORT);
ISC_STATUS REM_unwind_request(ISC_STATUS *, struct Rrq **, USHORT);
ISC_STATUS REM_rollback_retaining(ISC_STATUS *, RTR *);
ISC_STATUS REM_service_attach(ISC_STATUS*, USHORT, const TEXT*, RDB*, USHORT,

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
#ifndef REMOTE_PARSE_PROTO_H
#define REMOTE_PARSE_PROTO_H
struct message* PARSE_messages(const UCHAR*, USHORT);
struct Message* PARSE_messages(const UCHAR*, USHORT);
const UCHAR* PARSE_prepare_messages(const UCHAR*, USHORT);
#endif // REMOTE_PARSE_PROTO_H

View File

@ -67,13 +67,13 @@ REM_MSG PARSE_messages(const UCHAR* blr, USHORT blr_length)
const USHORT msg_number = *blr++;
USHORT count = *blr++;
count += (*blr++) << 8;
rem_fmt* format = (rem_fmt*) ALLR_block(type_fmt, count);
rem_fmt* format = new rem_fmt(count);
#ifdef DEBUG_REMOTE_MEMORY
printf("PARSE_messages allocate format %x\n", format);
#endif
format->fmt_count = count;
USHORT offset = 0;
for (dsc* desc = format->fmt_desc; count; --count, ++desc) {
for (dsc* desc = format->fmt_desc.begin(); count; --count, ++desc) {
USHORT align = 4;
switch (*blr++) {
case blr_text:
@ -197,11 +197,11 @@ REM_MSG PARSE_messages(const UCHAR* blr, USHORT blr_length)
default:
fb_assert(FALSE);
ALLR_free(format);
delete format;
while (next = message) {
message = message->msg_next;
ALLR_free(next->msg_address);
ALLR_free(next);
delete next->msg_address;
delete next;
}
return (REM_MSG) - 1;
}
@ -216,7 +216,7 @@ REM_MSG PARSE_messages(const UCHAR* blr, USHORT blr_length)
}
format->fmt_length = offset;
format->fmt_net_length = net_length;
next = (REM_MSG) ALLR_block(type_msg, format->fmt_length);
next = new Message(format->fmt_length);
#ifdef DEBUG_REMOTE_MEMORY
printf("PARSE_messages allocate message %x\n", next);
#endif
@ -286,8 +286,7 @@ const UCHAR* PARSE_prepare_messages(const UCHAR* blr, USHORT blr_length)
case blr_d_float:
if (new_blr == old_blr) {
new_blr = (UCHAR *) ALLR_alloc((SLONG) blr_length);
/* NOMEM: ALLR_alloc() handled */
new_blr = FB_NEW(*getDefaultMemoryPool()) UCHAR[blr_length];
/* FREE: Never freed, blr_d_float is VMS specific */
#ifdef DEBUG_REMOTE_MEMORY
printf

View File

@ -901,12 +901,10 @@ static bool alloc_cstring(XDR* xdrs,
if (!cstring->cstr_address) {
// fb_assert(!cstring->cstr_allocated);
if (!
(cstring->cstr_address =
ALLR_alloc((SLONG) cstring->cstr_length)))
{
/* NOMEM: handled by ALLR_alloc() */
/* FREE: in realloc case above & free_cstring() */
try {
cstring->cstr_address = FB_NEW(*getDefaultMemoryPool()) UCHAR[cstring->cstr_length];
}
catch (const Firebird::BadAlloc&) {
return false;
}
@ -933,7 +931,7 @@ static void free_cstring( XDR* xdrs, CSTRING* cstring)
**************************************/
if (cstring->cstr_allocated) {
ALLR_free(cstring->cstr_address);
delete[] cstring->cstr_address;
DEBUG_XDR_FREE(xdrs, cstring, cstring->cstr_address,
cstring->cstr_allocated);
}
@ -1186,7 +1184,7 @@ static bool_t xdr_debug_packet( XDR* xdrs, enum xdr_op xop, PACKET* packet)
to start recording memory allocations for this packet. */
fb_assert(xop == XDR_ENCODE || xop == XDR_DECODE);
rem_vec* vector = ALLR_vector(&port->port_packet_vector, 0);
rem_vec* vector = A L L R _vector(&port->port_packet_vector, 0);
for (i = 0; i < vector->vec_count; i++)
{
@ -1201,7 +1199,7 @@ static bool_t xdr_debug_packet( XDR* xdrs, enum xdr_op xop, PACKET* packet)
}
if (i >= vector->vec_count)
vector = ALLR_vector(&port->port_packet_vector, i);
vector = A L L R _vector(&port->port_packet_vector, i);
vector->vec_object[i] = (BLK) packet;
}
@ -1286,7 +1284,7 @@ static bool_t xdr_message( XDR* xdrs, REM_MSG message, const rem_fmt* format)
format->fmt_length);
}
const dsc* desc = format->fmt_desc;
const dsc* desc = format->fmt_desc.begin();
for (const dsc* const end = desc + format->fmt_count; desc < end; ++desc)
{
if (!xdr_datum(xdrs, desc, message->msg_address))
@ -1363,10 +1361,10 @@ static bool_t xdr_request(
rem_port* port = (rem_port*) xdrs->x_public;
if (!port->port_objects || request_id >= port->port_object_vector->vec_count)
if (request_id >= port->port_objects.getCount())
return FALSE;
rrq* request = (rrq*) port->port_objects[request_id];
Rrq* request = port->port_objects[request_id];
if (!request)
return FALSE;
@ -1377,7 +1375,7 @@ static bool_t xdr_request(
if (message_number > request->rrq_max_msg)
return FALSE;
rrq::rrq_repeat* tail = &request->rrq_rpt[message_number];
Rrq::rrq_repeat* tail = &request->rrq_rpt[message_number];
REM_MSG message = tail->rrq_xdr;
if (!message)
@ -1424,18 +1422,16 @@ static bool_t xdr_slice(
if (slice->lstr_length > slice->lstr_allocated &&
slice->lstr_allocated)
{
ALLR_free(slice->lstr_address);
delete slice->lstr_address;
DEBUG_XDR_FREE(xdrs, slice, slice->lstr_address, slice->lstr_allocated);
slice->lstr_address = NULL;
}
if (!slice->lstr_address) {
if (!
(slice->lstr_address =
ALLR_alloc((SLONG) slice->lstr_length)))
{
/* NOMEM: handled by ALLR_alloc() */
/* FREE: in realloc case above & XDR_FREE case of this routine */
return FALSE;
try {
slice->lstr_address = FB_NEW(*getDefaultMemoryPool()) UCHAR[slice->lstr_length];
}
catch (const Firebird::BadAlloc&) {
return false;
}
slice->lstr_allocated = slice->lstr_length;
@ -1446,7 +1442,7 @@ static bool_t xdr_slice(
case XDR_FREE:
if (slice->lstr_allocated) {
ALLR_free(slice->lstr_address);
delete[] slice->lstr_address;
DEBUG_XDR_FREE(xdrs, slice, slice->lstr_address, slice->lstr_allocated);
}
slice->lstr_address = NULL;
@ -1518,16 +1514,14 @@ static bool_t xdr_sql_blr(
rem_port* port = (rem_port*) xdrs->x_public;
RSR statement;
if (statement_id >= 0) {
if (!port->port_objects)
if (static_cast<ULONG>(statement_id) >= port->port_objects.getCount())
return FALSE;
if (static_cast<ULONG>(statement_id) >= port->port_object_vector->vec_count)
return FALSE;
if (!(statement = (RSR) port->port_objects[statement_id]))
if (!(statement = port->port_objects[statement_id]))
return FALSE;
}
else {
if (!(statement = port->port_statement))
statement = port->port_statement = (RSR) ALLR_block(type_rsr, 0);
statement = port->port_statement = new Rsr;
}
if ((xdrs->x_op == XDR_ENCODE) && !direction) {
@ -1550,7 +1544,7 @@ static bool_t xdr_sql_blr(
if (*fmt_ptr
&& ((stmt_type == TYPE_IMMEDIATE) || blr->cstr_length != 0))
{
ALLR_free(*fmt_ptr);
delete *fmt_ptr;
*fmt_ptr = NULL;
}
@ -1562,7 +1556,7 @@ static bool_t xdr_sql_blr(
(REM_MSG) PARSE_messages(blr->cstr_address, blr->cstr_length);
if (temp_msg != (REM_MSG) -1) {
*fmt_ptr = (rem_fmt*) temp_msg->msg_address;
ALLR_free(temp_msg);
delete temp_msg;
}
}
}
@ -1579,8 +1573,7 @@ static bool_t xdr_sql_blr(
{
REMOTE_release_messages(message);
statement->rsr_fmt_length = statement->rsr_format->fmt_length;
statement->rsr_buffer = message =
(REM_MSG) ALLR_block(type_msg, statement->rsr_fmt_length);
statement->rsr_buffer = message = new Message(statement->rsr_fmt_length);
statement->rsr_message = message;
message->msg_next = message;
#ifdef SCROLLABLE_CURSORS
@ -1611,11 +1604,9 @@ static bool_t xdr_sql_message( XDR* xdrs, SLONG statement_id)
rem_port* port = (rem_port*) xdrs->x_public;
if (statement_id >= 0) {
if (!port->port_objects)
if (static_cast<ULONG>(statement_id) >= port->port_objects.getCount())
return FALSE;
if (static_cast<ULONG>(statement_id) >= port->port_object_vector->vec_count)
return FALSE;
statement = (RSR) port->port_objects[statement_id];
statement = port->port_objects[statement_id];
}
else
statement = port->port_statement;
@ -1744,26 +1735,18 @@ static bool_t xdr_trrq_blr( XDR* xdrs, CSTRING* blr)
rem_port* port = (rem_port*) xdrs->x_public;
RPR procedure = port->port_rpr;
if (!procedure)
procedure = port->port_rpr = (RPR) ALLR_block(type_rpr, 0);
procedure = port->port_rpr = new rpr;
/* Parse the blr describing the message. */
if (procedure->rpr_in_msg) {
ALLR_free(procedure->rpr_in_msg);
delete procedure->rpr_in_msg;
procedure->rpr_in_msg = NULL;
}
if (procedure->rpr_in_format) {
ALLR_free(procedure->rpr_in_format);
delete procedure->rpr_in_format;
procedure->rpr_in_format = NULL;
}
if (procedure->rpr_out_msg) {
ALLR_free(procedure->rpr_out_msg);
delete procedure->rpr_out_msg;
procedure->rpr_out_msg = NULL;
}
if (procedure->rpr_out_format) {
ALLR_free(procedure->rpr_out_format);
delete procedure->rpr_out_format;
procedure->rpr_out_format = NULL;
}
REM_MSG message = PARSE_messages(blr->cstr_address, blr->cstr_length);
if (message != (REM_MSG) -1) {
@ -1788,7 +1771,7 @@ static bool_t xdr_trrq_blr( XDR* xdrs, CSTRING* blr)
{
REM_MSG temp = message;
message = message->msg_next;
ALLR_free(temp);
delete temp;
}
break;
}
@ -1844,7 +1827,7 @@ static RSR get_statement( XDR * xdrs, SSHORT statement_id)
*
**************************************/
rsr* statement = NULL;
Rsr* statement = NULL;
rem_port* port = (rem_port*) xdrs->x_public;
/* if the statement ID is -1, this seems to indicate that we are
@ -1858,15 +1841,12 @@ else
fb_assert(statement_id >= -1);
if ((port->port_objects) &&
((SLONG) statement_id < (SLONG) port->port_object_vector->vec_count)
if (((ULONG) statement_id < port->port_objects.getCount())
&& (statement_id >= 0))
{
statement = (RSR) port->port_objects[(SLONG) statement_id];
statement = port->port_objects[statement_id];
}
/* Check that what we found really is a statement structure */
fb_assert(!statement || (statement->rsr_header.blk_type == type_rsr));
return statement;
}

View File

@ -654,6 +654,12 @@ typedef struct packet {
P_TRAU p_trau; /* Trusted authentication */
p_update_account p_account_update;
p_authenticate p_authenticate_user;
public:
packet()
{
memset(this, 0, sizeof(*this));
}
} PACKET;
#endif // REMOTE_PROTOCOL_H

View File

@ -24,24 +24,22 @@
#ifndef REMOTE_REMOT_PROTO_H
#define REMOTE_REMOT_PROTO_H
struct blk;
namespace Firebird
{
class ClumpletReader;
};
void REMOTE_cleanup_transaction (struct rtr *);
void REMOTE_cleanup_transaction (struct Rtr *);
ULONG REMOTE_compute_batch_size (rem_port*, USHORT, P_OP, const rem_fmt*);
void REMOTE_get_timeout_params(rem_port* port, Firebird::ClumpletReader* pb);
struct rrq* REMOTE_find_request (struct rrq *, USHORT);
struct Rrq* REMOTE_find_request (struct Rrq *, USHORT);
void REMOTE_free_packet (rem_port*, struct packet *, bool = false);
struct rem_str* REMOTE_make_string (const SCHAR*);
void REMOTE_release_messages (struct message *);
void REMOTE_release_request (struct rrq *);
void REMOTE_reset_request (struct rrq *, struct message *);
void REMOTE_reset_statement (struct rsr *);
void REMOTE_release_messages (struct Message *);
void REMOTE_release_request (struct Rrq *);
void REMOTE_reset_request (struct Rrq *, struct Message *);
void REMOTE_reset_statement (struct Rsr *);
void REMOTE_save_status_strings (ISC_STATUS *);
OBJCT REMOTE_set_object (rem_port*, blk*, OBJCT);
bool_t REMOTE_getbytes (XDR*, SCHAR*, u_int);
#endif // REMOTE_REMOT_PROTO_H

View File

@ -29,7 +29,6 @@
#include "../jrd/file_params.h"
#include "../jrd/gdsassert.h"
#include "../jrd/isc.h"
#include "../remote/allr_proto.h"
#include "../remote/proto_proto.h"
#include "../remote/remot_proto.h"
#include "../remote/xdr_proto.h"
@ -64,14 +63,14 @@ void REMOTE_cleanup_transaction( RTR transaction)
* receive while we still have something cached.
*
**************************************/
for (rrq* request = transaction->rtr_rdb->rdb_requests; request;
for (Rrq* request = transaction->rtr_rdb->rdb_requests; request;
request = request->rrq_next)
{
if (request->rrq_rtr == transaction) {
REMOTE_reset_request(request, 0);
request->rrq_rtr = NULL;
}
for (rrq* level = request->rrq_levels; level; level = level->rrq_next)
for (Rrq* level = request->rrq_levels; level; level = level->rrq_next)
if (level->rrq_rtr == transaction) {
REMOTE_reset_request(level, 0);
level->rrq_rtr = NULL;
@ -83,7 +82,7 @@ void REMOTE_cleanup_transaction( RTR transaction)
{
if (statement->rsr_rtr == transaction) {
REMOTE_reset_statement(statement);
statement->rsr_flags &= ~RSR_fetched;
statement->rsr_flags &= ~Rsr::FETCHED;
statement->rsr_rtr = NULL;
}
}
@ -220,7 +219,7 @@ const USHORT MIN_ROWS_PER_BATCH = 10; /* data rows - picked by SWAG */
}
rrq* REMOTE_find_request(rrq* request, USHORT level)
Rrq* REMOTE_find_request(Rrq* request, USHORT level)
{
/**************************************
*
@ -245,8 +244,8 @@ rrq* REMOTE_find_request(rrq* request, USHORT level)
/* This is a new level -- make up a new request block. */
request->rrq_levels = (rrq*) ALLR_clone(&request->rrq_header);
/* NOMEM: handled by ALLR_clone, FREE: REMOTE_remove_request() */
request->rrq_levels = request->clone();
/* FREE: REMOTE_remove_request() */
#ifdef DEBUG_REMOTE_MEMORY
printf("REMOTE_find_request allocate request %x\n",
request->rrq_levels);
@ -257,13 +256,13 @@ rrq* REMOTE_find_request(rrq* request, USHORT level)
/* Allocate message block for known messages */
rrq::rrq_repeat* tail = request->rrq_rpt;
const rrq::rrq_repeat* const end = tail + request->rrq_max_msg;
Rrq::rrq_repeat* tail = request->rrq_rpt.begin();
const Rrq::rrq_repeat* const end = tail + request->rrq_max_msg;
for (; tail <= end; tail++) {
const rem_fmt* format = tail->rrq_format;
if (!format)
continue;
REM_MSG msg = (REM_MSG) ALLR_block(type_msg, format->fmt_length);
REM_MSG msg = new Message(format->fmt_length);
tail->rrq_xdr = msg;
#ifdef DEBUG_REMOTE_MEMORY
printf("REMOTE_find_request allocate message %x\n", msg);
@ -373,7 +372,7 @@ rem_str* REMOTE_make_string(const SCHAR* input)
*
**************************************/
const USHORT length = strlen(input);
rem_str* string = (rem_str*) ALLR_block(type_str, length);
rem_str* string = FB_NEW_RPT(*getDefaultMemoryPool(), length) rem_str;
#ifdef DEBUG_REMOTE_MEMORY
printf("REMOTE_make_string allocate string %x\n", string);
#endif
@ -405,14 +404,14 @@ void REMOTE_release_messages( REM_MSG messages)
printf("REMOTE_release_messages free message %x\n",
temp);
#endif
ALLR_free(temp);
delete temp;
if (message == messages)
break;
}
}
void REMOTE_release_request( rrq* request)
void REMOTE_release_request( Rrq* request)
{
/**************************************
*
@ -426,7 +425,7 @@ void REMOTE_release_request( rrq* request)
**************************************/
RDB rdb = request->rrq_rdb;
for (rrq** p = &rdb->rdb_requests; *p; p = &(*p)->rrq_next)
for (Rrq** p = &rdb->rdb_requests; *p; p = &(*p)->rrq_next)
{
if (*p == request) {
*p = request->rrq_next;
@ -437,8 +436,8 @@ void REMOTE_release_request( rrq* request)
/* Get rid of request and all levels */
for (;;) {
rrq::rrq_repeat* tail = request->rrq_rpt;
const rrq::rrq_repeat* const end = tail + request->rrq_max_msg;
Rrq::rrq_repeat* tail = request->rrq_rpt.begin();
const Rrq::rrq_repeat* const end = tail + request->rrq_max_msg;
for (; tail <= end; tail++)
{
REM_MSG message = tail->rrq_message;
@ -449,23 +448,23 @@ void REMOTE_release_request( rrq* request)
("REMOTE_release_request free format %x\n",
tail->rrq_format);
#endif
ALLR_free(tail->rrq_format);
delete tail->rrq_format;
}
REMOTE_release_messages(message);
}
}
rrq* next = request->rrq_levels;
Rrq* next = request->rrq_levels;
#ifdef DEBUG_REMOTE_MEMORY
printf("REMOTE_release_request free request %x\n", request);
#endif
ALLR_free(request);
delete request;
if (!(request = next))
break;
}
}
void REMOTE_reset_request( rrq* request, REM_MSG active_message)
void REMOTE_reset_request( Rrq* request, REM_MSG active_message)
{
/**************************************
*
@ -479,8 +478,8 @@ void REMOTE_reset_request( rrq* request, REM_MSG active_message)
* some care to avoid zapping that message.
*
**************************************/
rrq::rrq_repeat* tail = request->rrq_rpt;
const rrq::rrq_repeat* const end = tail + request->rrq_max_msg;
Rrq::rrq_repeat* tail = request->rrq_rpt.begin();
const Rrq::rrq_repeat* const end = tail + request->rrq_max_msg;
for (; tail <= end; tail++) {
REM_MSG message = tail->rrq_message;
if (message != NULL && message != active_message) {
@ -619,59 +618,6 @@ void REMOTE_save_status_strings( ISC_STATUS* vector)
}
OBJCT REMOTE_set_object(rem_port* port, BLK object, OBJCT slot)
{
/**************************************
*
* R E M O T E _ s e t _ o b j e c t
*
**************************************
*
* Functional description
* Set an object into the object vector.
*
**************************************/
/* If it fits, do it */
rem_vec* vector = port->port_object_vector;
if ((vector != NULL) && slot < vector->vec_count) {
vector->vec_object[slot] = object;
return slot;
}
/* Prevent the creation of object handles that can't be
transferred by the remote protocol. */
if (slot + 10 > MAX_OBJCT_HANDLES)
return (OBJCT) NULL;
rem_vec* new_vector = (rem_vec*) ALLR_block(type_vec, slot + 10);
port->port_object_vector = new_vector;
#ifdef DEBUG_REMOTE_MEMORY
printf("REMOTE_set_object allocate vector %x\n", new_vector);
#endif
port->port_objects = new_vector->vec_object;
new_vector->vec_count = slot + 10;
if (vector) {
blk** p = new_vector->vec_object;
blk* const* q = vector->vec_object;
const blk* const* const end = q + (int) vector->vec_count;
while (q < end)
*p++ = *q++;
#ifdef DEBUG_REMOTE_MEMORY
printf("REMOTE_release_request free vector %x\n", vector);
#endif
ALLR_free(vector);
}
new_vector->vec_object[slot] = object;
return slot;
}
static void cleanup_memory( void *block)
{
/**************************************
@ -769,13 +715,13 @@ bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count)
}
rem_port* port = (rem_port*) xdrs->x_public;
Firebird::RefMutexGuard queGuard(*port->port_que_sync);
if (port->port_qoffset >= port->port_queue->getCount()) {
if (port->port_qoffset >= port->port_queue.getCount()) {
port->port_flags |= PORT_partial_data;
return FALSE;
}
xdrs->x_handy = (*port->port_queue)[port->port_qoffset].getCount();
xdrs->x_handy = port->port_queue[port->port_qoffset].getCount();
fb_assert(xdrs->x_handy <= port->port_buff_size);
memcpy(xdrs->x_base, (*port->port_queue)[port->port_qoffset].begin(), xdrs->x_handy);
memcpy(xdrs->x_base, port->port_queue[port->port_qoffset].begin(), xdrs->x_handy);
++port->port_qoffset;
xdrs->x_private = xdrs->x_base;
}

View File

@ -30,7 +30,7 @@
#define REMOTE_REMOTE_H
#include "../jrd/common.h"
#include "../remote/allr_proto.h"
#include "gen/iberror.h"
#include "../remote/remote_def.h"
#include "../jrd/ThreadData.h"
#include "../common/thd.h"
@ -75,78 +75,108 @@ DEFINE_TRACE_ROUTINE(remote_trace);
const int BLOB_LENGTH = 16384;
#include "../remote/protocol.h"
#include "fb_blk.h"
/* Block types */
struct blk;
#ifndef INCLUDE_FB_BLK
#include "../include/old_fb_blk.h"
#endif
// fwd. decl.
struct rem_port;
typedef struct rdb
typedef Firebird::AutoPtr<UCHAR, Firebird::ArrayDelete<UCHAR> > UCharArrayAutoPtr;
typedef struct Rdb : public Firebird::GlobalStorage, public TypedHandle<rem_type_rdb>
{
blk rdb_header;
USHORT rdb_id;
USHORT rdb_flags;
FB_API_HANDLE rdb_handle; /* database handle */
rem_port* rdb_port; /* communication port */
struct rtr* rdb_transactions; /* linked list of transactions */
struct rrq* rdb_requests; /* compiled requests */
struct Rtr* rdb_transactions; /* linked list of transactions */
struct Rrq* rdb_requests; /* compiled requests */
struct rvnt* rdb_events; /* known events */
struct rsr* rdb_sql_requests; /* SQL requests */
struct Rsr* rdb_sql_requests; /* SQL requests */
ISC_STATUS* rdb_status_vector;
PACKET rdb_packet; /* Communication structure */
public:
enum {
SERVICE = 1
};
public:
Rdb() :
rdb_id(0), rdb_flags(0), rdb_handle(0),
rdb_port(0), rdb_transactions(0), rdb_requests(0),
rdb_events(0), rdb_sql_requests(0), rdb_status_vector(0)
{
}
static ISC_STATUS badHandle() { return isc_bad_db_handle; }
} *RDB;
// rdb_flags
const USHORT RDB_service = 1; /* structure relates to a service */
typedef struct rtr
typedef struct Rtr : public Firebird::GlobalStorage, public TypedHandle<rem_type_rtr>
{
blk rtr_header;
rdb* rtr_rdb;
rtr* rtr_next;
struct rbl* rtr_blobs;
Rdb* rtr_rdb;
Rtr* rtr_next;
struct Rbl* rtr_blobs;
FB_API_HANDLE rtr_handle;
bool rtr_limbo;
USHORT rtr_id;
bool rtr_limbo;
public:
Rtr() :
rtr_rdb(0), rtr_next(0), rtr_blobs(0),
rtr_handle(0), rtr_id(0), rtr_limbo(0)
{ }
static ISC_STATUS badHandle() { return isc_bad_trans_handle; }
} *RTR;
typedef struct rbl
typedef struct Rbl : public Firebird::GlobalStorage, public TypedHandle<rem_type_rbl>
{
blk rbl_header;
rdb* rbl_rdb;
rtr* rbl_rtr;
rbl* rbl_next;
Firebird::HalfStaticArray<UCHAR, BLOB_LENGTH> rbl_data;
Rdb* rbl_rdb;
Rtr* rbl_rtr;
Rbl* rbl_next;
UCHAR* rbl_buffer;
UCHAR* rbl_ptr;
FB_API_HANDLE rbl_handle;
SLONG rbl_offset; /* Apparent (to user) offset in blob */
USHORT rbl_id;
USHORT rbl_flags;
UCHAR* rbl_ptr;
UCHAR* rbl_buffer;
USHORT rbl_buffer_length;
USHORT rbl_length;
USHORT rbl_fragment_length;
USHORT rbl_source_interp; /* source interp (for writing) */
USHORT rbl_target_interp; /* destination interp (for reading) */
UCHAR rbl_data[1];
public:
enum {
EOF_SET = 1,
SEGMENT = 2,
EOF_PENDING = 4,
CREATE = 8
};
public:
Rbl() :
rbl_data(getPool()), rbl_rdb(0), rbl_rtr(0), rbl_next(0),
rbl_buffer(rbl_data.getBuffer(BLOB_LENGTH)), rbl_ptr(rbl_buffer), rbl_handle(0),
rbl_offset(0), rbl_id(0), rbl_flags(0),
rbl_buffer_length(BLOB_LENGTH), rbl_length(0), rbl_fragment_length(0),
rbl_source_interp(0), rbl_target_interp(0)
{ }
static ISC_STATUS badHandle() { return isc_bad_segstr_handle; }
} *RBL;
// rbl_flags
const USHORT RBL_eof = 1;
const USHORT RBL_segment = 2;
const USHORT RBL_eof_pending= 4;
const USHORT RBL_create = 8;
typedef struct rvnt
typedef struct rvnt : public Firebird::GlobalStorage
{
blk rvnt_header;
rvnt* rvnt_next;
rdb* rvnt_rdb;
Rdb* rvnt_rdb;
FPTR_EVENT_CALLBACK rvnt_ast;
void* rvnt_arg;
SLONG rvnt_id;
@ -154,99 +184,111 @@ typedef struct rvnt
rem_port* rvnt_port; /* used to id server from whence async came */
const UCHAR* rvnt_items;
SSHORT rvnt_length;
public:
rvnt() :
rvnt_next(0), rvnt_rdb(0), rvnt_ast(0),
rvnt_arg(0), rvnt_id(0), rvnt_rid(0),
rvnt_port(0), rvnt_items(0), rvnt_length(0)
{ }
} *RVNT;
struct rem_vec
struct rem_str : public pool_alloc_rpt<SCHAR>
{
blk vec_header;
ULONG vec_count;
blk* vec_object[1];
};
//struct rem_vcl
//{
// blk vcl_header;
// ULONG vcl_count;
// SLONG vcl_long[1];
//};
/* Random string block -- jack of all kludges */
struct rem_str
{
blk str_header;
USHORT str_length;
SCHAR str_data[2];
};
/* Include definition of descriptor */
#include "../jrd/dsc.h"
struct rem_fmt
struct rem_fmt : public Firebird::GlobalStorage
{
blk fmt_header;
USHORT fmt_length;
USHORT fmt_net_length;
USHORT fmt_count;
USHORT fmt_version;
struct dsc fmt_desc[1];
Firebird::Array<dsc> fmt_desc;
public:
rem_fmt(size_t rpt) :
fmt_length(0), fmt_net_length(0), fmt_count(0),
fmt_version(0), fmt_desc(getPool(), rpt)
{
fmt_desc.grow(rpt);
}
};
/* Windows declares a msg structure, so rename the structure
to avoid overlap problems. */
typedef struct message
typedef struct Message : public Firebird::GlobalStorage
{
blk msg_header;
message* msg_next; /* Next available message */
Message* msg_next; /* Next available message */
#ifdef SCROLLABLE_CURSORS
message* msg_prior; /* Next available message */
Message* msg_prior; /* Next available message */
ULONG msg_absolute; /* Absolute record number in cursor result set */
#endif
/* Please DO NOT re-arrange the order of following two fields.
This could result in alignment problems while trying to access
'msg_buffer' as a 'long', leading to "core" drops
Sriram - 04-Jun-97 */
USHORT msg_number; /* Message number */
UCHAR* msg_address; /* Address of message */
UCHAR msg_buffer[1]; /* Allocated message */
UCharArrayAutoPtr msg_buffer; /* Allocated message */
public:
Message(size_t rpt) :
msg_next(0),
#ifdef SCROLLABLE_CURSORS
msg_prior(0), msg_absolute(0),
#endif
msg_number(0), msg_address(0), msg_buffer(FB_NEW(getPool()) UCHAR[rpt])
{
memset(msg_buffer, 0, rpt);
}
} *REM_MSG;
/* remote stored procedure request */
typedef struct rpr
// remote stored procedure request
typedef struct rpr : public Firebird::GlobalStorage
{
blk rpr_header;
rdb* rpr_rdb;
rtr* rpr_rtr;
Rdb* rpr_rdb;
Rtr* rpr_rtr;
FB_API_HANDLE rpr_handle;
message* rpr_in_msg; /* input message */
message* rpr_out_msg; /* output message */
Message* rpr_in_msg; /* input message */
Message* rpr_out_msg; /* output message */
rem_fmt* rpr_in_format; /* Format of input message */
rem_fmt* rpr_out_format; /* Format of output message */
public:
rpr() :
rpr_rdb(0), rpr_rtr(0), rpr_handle(0),
rpr_in_msg(0), rpr_out_msg(0), rpr_in_format(0), rpr_out_format(0)
{ }
//ISC_STATUS badHandle() { return ; }
} *RPR;
struct rrq
struct Rrq : public Firebird::GlobalStorage, public TypedHandle<rem_type_rrq>
{
blk rrq_header;
rdb* rrq_rdb;
rtr* rrq_rtr;
rrq* rrq_next;
rrq* rrq_levels; /* RRQ block for next level */
Rdb* rrq_rdb;
Rtr* rrq_rtr;
Rrq* rrq_next;
Rrq* rrq_levels; /* RRQ block for next level */
FB_API_HANDLE rrq_handle;
USHORT rrq_id;
USHORT rrq_max_msg;
USHORT rrq_level;
ISC_STATUS_ARRAY rrq_status_vector;
struct rrq_repeat
{
rem_fmt* rrq_format; /* format for this message */
message* rrq_message; /* beginning or end of cache, depending on whether it is client or server */
message* rrq_xdr; /* point at which cache is read or written by xdr */
Message* rrq_message; /* beginning or end of cache, depending on whether it is client or server */
Message* rrq_xdr; /* point at which cache is read or written by xdr */
#ifdef SCROLLABLE_CURSORS
message* rrq_last; /* last message returned */
Message* rrq_last; /* last message returned */
ULONG rrq_absolute; /* current offset in result set for record being read into cache */
USHORT rrq_flags;
#endif
@ -255,31 +297,52 @@ struct rrq
USHORT rrq_reorder_level; /* Reorder when rows_pending < this level */
USHORT rrq_batch_count; /* Count of batches in pipeline */
} rrq_rpt[1];
};
};
Firebird::Array<rrq_repeat> rrq_rpt;
// rrq_flags
public:
#ifdef SCROLLABLE_CURSORS
const USHORT RRQ_backward = 1; /* the cache was created in the backward direction */
const USHORT RRQ_absolute_backward = 2; /* rrq_absolute is measured from the end of the stream */
const USHORT RRQ_last_backward = 4; /* last time, the next level up asked for us to scroll in the backward direction */
enum {
BACKWARD = 1, /* the cache was created in the backward direction */
ABSOLUTE_BACKWARD = 2, /* rrq_absolute is measured from the end of the stream */
LAST_BACKWARD = 4 /* last time, the next level up asked for us to scroll in the backward direction */
};
#endif
/* remote SQL request */
public:
Rrq(size_t rpt) :
rrq_rdb(0), rrq_rtr(0), rrq_next(0), rrq_levels(0),
rrq_handle(0), rrq_id(0), rrq_max_msg(0), rrq_level(0),
rrq_rpt(getPool(), rpt)
{
memset(rrq_status_vector, 0, sizeof rrq_status_vector);
rrq_rpt.grow(rpt);
}
typedef struct rsr
Rrq* clone() const
{
Rrq* rc = new Rrq(rrq_rpt.getCount());
*rc = *this;
return rc;
}
static ISC_STATUS badHandle() { return isc_bad_req_handle; }
};
// remote SQL request
typedef struct Rsr : public Firebird::GlobalStorage, public TypedHandle<rem_type_rsr>
{
blk rsr_header;
rsr* rsr_next;
rdb* rsr_rdb;
rtr* rsr_rtr;
Rsr* rsr_next;
Rdb* rsr_rdb;
Rtr* rsr_rtr;
FB_API_HANDLE rsr_handle;
rem_fmt* rsr_bind_format; /* Format of bind message */
rem_fmt* rsr_select_format; /* Format of select message */
rem_fmt* rsr_user_select_format; /* Format of user's select message */
rem_fmt* rsr_format; /* Format of current message */
message* rsr_message; /* Next message to process */
message* rsr_buffer; /* Next buffer to use */
Message* rsr_message; /* Next message to process */
Message* rsr_buffer; /* Next buffer to use */
Firebird::StatusHolder* rsr_status; /* saved status for buffered errors */
USHORT rsr_id;
USHORT rsr_flags;
@ -289,17 +352,74 @@ typedef struct rsr
USHORT rsr_msgs_waiting; /* count of full rsr_messages */
USHORT rsr_reorder_level; /* Trigger pipelining at this level */
USHORT rsr_batch_count; /* Count of batches in pipeline */
public:
enum {
FETCHED = 1, // Cleared by execute, set by fetch
EOF_SET = 2, // End-of-stream encountered
BLOB = 4, // Statement relates to blob op
NO_BATCH = 8, // Do not batch fetch rows
STREAM_ERR = 16, // There is an error pending in the batched rows
LAZY = 32, // To be allocated at the first reference
DEFER_EXECUTE = 64, // op_execute can be deferred
PAST_EOF = 128, // EOF was returned by fetch from this statement
};
public:
Rsr() :
rsr_next(0), rsr_rdb(0), rsr_rtr(0), rsr_handle(0),
rsr_bind_format(0), rsr_select_format(0), rsr_user_select_format(0),
rsr_format(0), rsr_message(0), rsr_buffer(0), rsr_status(0),
rsr_id(0), rsr_flags(0), rsr_fmt_length(0),
rsr_rows_pending(0), rsr_msgs_waiting(0), rsr_reorder_level(0), rsr_batch_count(0)
{ }
static ISC_STATUS badHandle() { return isc_bad_req_handle; }
} *RSR;
// rsr_flags
const USHORT RSR_fetched = 1; /* Cleared by execute, set by fetch */
const USHORT RSR_eof = 2; /* End-of-stream encountered */
const USHORT RSR_blob = 4; /* Statement relates to blob op */
const USHORT RSR_no_batch = 8; /* Do not batch fetch rows */
const USHORT RSR_stream_err = 16; /* There is an error pending in the batched rows */
const USHORT RSR_lazy = 32; /* To be allocated at the first reference */
const USHORT RSR_defer_execute = 64; // op_execute can be deferred
const USHORT RSR_past_eof = 128; // EOF was returned by fetch from this statement
// Makes it possible to safely store all handles in single array
class RemoteObject
{
private:
union {
Rdb* rdb;
Rtr* rtr;
Rbl* rbl;
Rrq* rrq;
Rsr* rsr;
} ptr;
public:
template <typename R>
R* get(R* r)
{
if (! r->checkHandle())
{
Firebird::status_exception::raise(R::badHandle(), isc_arg_end);
}
return r;
}
public:
void operator=(Rdb* v) { ptr.rdb = v; }
void operator=(Rtr* v) { ptr.rtr = v; }
void operator=(Rbl* v) { ptr.rbl = v; }
void operator=(Rrq* v) { ptr.rrq = v; }
void operator=(Rsr* v) { ptr.rsr = v; }
public:
operator Rdb*() { return get(ptr.rdb); }
operator Rtr*() { return get(ptr.rtr); }
operator Rbl*() { return get(ptr.rbl); }
operator Rrq*() { return get(ptr.rrq); }
operator Rsr*() { return get(ptr.rsr); }
bool isMissing() { return ptr.rdb == NULL; }
void release() { ptr.rdb = 0; }
};
// will be methods of remote statement class
inline void stmt_save_exception(RSR statement, const ISC_STATUS* status, bool overwrite)
@ -339,47 +459,11 @@ inline void stmt_release_exception(RSR statement)
}
}
enum blk_t
{
type_MIN = 0,
type_vec,
type_rdb,
type_fmt,
type_rrq,
type_rtr,
type_str,
type_rbl,
type_port,
type_msg,
type_rsr,
type_rvnt,
type_rpr,
type_rmtque,
type_MAX
};
#include "../remote/xdr.h"
/* Generalized port definition. */
enum rem_port_t
{
port_inet, /* Internet (TCP/IP) */
port_pipe, /* Windows NT named pipe connection */
port_xnet /* Windows NT shared memory connection */
};
enum state_t
{
state_closed, /* no connection */
state_pending, /* connection is pending */
state_broken, /* connection is broken */
state_disconnected /* port is disconnected */
};
#ifndef WIN_NT
typedef int HANDLE;
#endif /* WIN_NT */
@ -402,7 +486,7 @@ typedef Firebird::Array<rem_que_packet> PacketQueue;
#ifdef TRUSTED_AUTH
// delayed authentication block for trusted auth callback
class ServerAuth
class ServerAuth : public Firebird::GlobalStorage
{
public:
typedef void Part2(rem_port*, P_OP, const char* fName, int fLen, const UCHAR* pb, int pbLen, PACKET*);
@ -417,6 +501,20 @@ public:
};
#endif // TRUSTED_AUTH
// port_flags
const USHORT PORT_symmetric = 0x0001; // Server/client archiectures are symmetic
const USHORT PORT_rpc = 0x0002; // Protocol is remote procedure call
const USHORT PORT_async = 0x0004; // Port is asynchronous channel for events
const USHORT PORT_no_oob = 0x0008; // Don't send out of band data
const USHORT PORT_disconnect = 0x0010; // Disconnect is in progress
// This is set only in inet.cpp but never tested
const USHORT PORT_not_trusted = 0x0020; // Connection is from an untrusted node
const USHORT PORT_dummy_pckt_set= 0x0040; // A dummy packet interval is set
const USHORT PORT_partial_data = 0x0080; // Physical packet doesn't contain all API packet
const USHORT PORT_lazy = 0x0100; // Deferred operations are allowed
const USHORT PORT_server = 0x0200; // Server (not client) port
/* Port itself */
class port_interface
@ -429,11 +527,30 @@ public:
typedef void (*t_event_ast)(rem_port*);
typedef rem_port* (*t_port_connect)(rem_port*, PACKET*, t_event_ast);
struct rem_port
struct rem_port : public Firebird::GlobalStorage
{
blk port_header;
enum rem_port_t port_type; /* type of port */
enum state_t port_state; /* state of port */
/* port function pointers (C "emulation" of virtual functions) */
int (*port_accept)(rem_port*, p_cnct*);
void (*port_disconnect)(rem_port*);
rem_port* (*port_receive_packet)(rem_port*, PACKET*);
XDR_INT (*port_send_packet)(rem_port*, PACKET*);
XDR_INT (*port_send_partial)(rem_port*, PACKET*);
t_port_connect port_connect; /* Establish secondary connection */
rem_port* (*port_request)(rem_port*, PACKET*); /* Request to establish secondary connection */
rem_port* (*port_select_multi)(rem_port*, UCHAR*, SSHORT, SSHORT*); // get packet from active port
enum rem_port_t {
INET, /* Internet (TCP/IP) */
PIPE, /* Windows NT named pipe connection */
XNET /* Windows NT shared memory connection */
} port_type;
enum state_t {
CLOSED, /* no connection */
PENDING, /* connection is pending */
BROKEN, /* connection is broken */
DISCONNECTED /* port is disconnected */
} port_state;
P_ARCH port_client_arch; /* so we can tell arch of client */
rem_port* port_clients; /* client ports */
rem_port* port_next; /* next client port */
@ -451,26 +568,14 @@ struct rem_port
HANDLE port_handle; /* handle for connection (from by OS) */
int port_channel; /* handle for connection (from by OS) */
struct linger port_linger; /* linger value as defined by SO_LINGER */
/* port function pointers (C "emulation" of virtual functions) */
int (*port_accept)(rem_port*, p_cnct*);
void (*port_disconnect)(rem_port*);
rem_port* (*port_receive_packet)(rem_port*, PACKET*);
XDR_INT (*port_send_packet)(rem_port*, PACKET*);
XDR_INT (*port_send_partial)(rem_port*, PACKET*);
t_port_connect port_connect; /* Establish secondary connection */
rem_port* (*port_request)(rem_port*, PACKET*); /* Request to establish secondary connection */
rem_port* (*port_select_multi)(rem_port*, UCHAR*, SSHORT, SSHORT*); // get packet from active port
rdb* port_context;
Rdb* port_context;
t_event_ast port_ast; /* AST for events */
XDR port_receive;
XDR port_send;
#ifdef DEBUG_XDR_MEMORY
rem_vec* port_packet_vector; /* Vector of send/receive packets */
r e m _ v e c* port_packet_vector; /* Vector of send/receive packets */
#endif
rem_vec* port_object_vector;
BLK* port_objects;
Firebird::Array<RemoteObject> port_objects;
rem_str* port_version;
rem_str* port_host; /* Our name */
rem_str* port_connection; /* Name of connection */
@ -479,23 +584,155 @@ struct rem_port
rem_str* port_protocol_str; // String containing protocol name for this port
rem_str* port_address_str; // Protocol-specific address string for the port
rpr* port_rpr; /* port stored procedure reference */
rsr* port_statement; /* Statement for execute immediate */
Rsr* port_statement; /* Statement for execute immediate */
rmtque* port_receive_rmtque; /* for client, responses waiting */
USHORT port_requests_queued; /* requests currently queued */
void* port_xcc; /* interprocess structure */
PacketQueue* port_deferred_packets; /* queue of deferred packets */
OBJCT port_last_object_id; /* cached last id */
#ifdef REM_SERVER
Firebird::ObjectsArray< Firebird::Array<char> >* port_queue;
Firebird::ObjectsArray< Firebird::Array<char> > port_queue;
size_t port_qoffset; // current packet in the queue
Firebird::RefMutex* port_que_sync;
Firebird::RefMutex* const port_que_sync;
#endif
#ifdef TRUSTED_AUTH
ServerAuth* port_trusted_auth;
#endif
Firebird::RefMutex* port_sync;
UCHAR port_buffer[1];
Firebird::RefMutex* const port_sync;
UCharArrayAutoPtr port_buffer;
public:
rem_port(rem_port_t t, size_t rpt) :
port_accept(0), port_disconnect(0), port_receive_packet(0), port_send_packet(0),
port_send_partial(0), port_connect(0), port_request(0), port_select_multi(0),
port_type(t), port_state(PENDING),
port_client_arch(arch_generic), port_clients(0), port_next(0), port_parent(0), port_async(0),
port_server(0), port_server_flags(0), port_protocol(0), port_buff_size(0),
port_flags(0), port_connect_timeout(0), port_dummy_packet_interval(0),
port_dummy_timeout(0), port_status_vector(0), port_handle(0), port_channel(0),
port_context(0), port_ast(0),
#ifdef DEBUG_XDR_MEMORY
port_packet_vector(0),
#endif
port_objects(getPool()), port_version(0), port_host(0),
port_connection(0), port_user_name(0), port_passwd(0), port_protocol_str(0),
port_address_str(0), port_rpr(0), port_statement(0), port_receive_rmtque(0),
port_requests_queued(0), port_xcc(0), port_deferred_packets(0), port_last_object_id(0),
#ifdef REM_SERVER
port_queue(getPool()), port_qoffset(0),
port_que_sync(FB_NEW(getPool()) Firebird::RefMutex()),
#endif
#ifdef TRUSTED_AUTH
port_trusted_auth(0),
#endif
port_sync(FB_NEW(getPool()) Firebird::RefMutex()),
port_buffer(FB_NEW(getPool()) UCHAR[rpt])
{
memset (port_buffer, 0, rpt);
port_sync->addRef();
#ifdef REM_SERVER
port_que_sync->addRef();
#endif
}
~rem_port()
{
delete port_version;
delete port_connection;
delete port_user_name;
delete port_host;
delete port_protocol_str;
delete port_address_str;
#ifdef DEBUG_XDR_MEMORY
delete port_packet_vector;
#endif
#ifdef REM_SERVER
port_que_sync->release();
#endif
#ifdef TRUSTED_AUTH
delete port_trusted_auth;
#endif
port_sync->release();
}
void linkParent(rem_port* parent)
{
port_parent = parent;
port_next = parent->port_clients;
port_handle = parent->port_handle;
port_server = parent->port_server;
port_server_flags = parent->port_server_flags;
parent->port_clients = parent->port_next = this;
}
template <typename T>
void getHandle(T*& blk, OBJCT id)
{
if ((port_flags & PORT_lazy) && (id == INVALID_OBJECT))
{
id = port_last_object_id;
}
if (id >= port_objects.getCount() || port_objects[id].isMissing())
{
Firebird::status_exception::raise(T::badHandle(), isc_arg_end);
}
blk = port_objects[id];
}
template <typename T>
OBJCT setHandle(T* const object, const OBJCT id)
{
if (id >= port_objects.getCount())
{
/* Prevent the creation of object handles that can't be
transferred by the remote protocol. */
if (id > MAX_OBJCT_HANDLES)
{
return (OBJCT)0;
}
port_objects.grow(id + 1);
}
port_objects[id] = object;
return id;
}
// Allocate an object slot for an object.
template <typename T>
OBJCT get_id(T* object)
{
// Reserve slot 0 so we can distinguish something from nothing.
// NOTE: prior to server version 4.5.0 id==0 COULD be used - so
// only the server side can now depend on id==0 meaning "invalid id"
unsigned int i = 1;
for (; i < port_objects.getCount(); ++i)
{
if (port_objects[i].isMissing())
{
break;
}
}
port_last_object_id = setHandle(object, static_cast<OBJCT>(i));
return port_last_object_id;
}
void releaseObject(OBJCT id)
{
if (id != INVALID_OBJECT)
{
port_objects[id].release();
}
}
public:
/* TMN: Beginning of C++ port */
/* TMN: ugly, but at least a start */
int accept(p_cnct* cnct);
@ -511,15 +748,13 @@ struct rem_port
bool haveRecvData() const
{
Firebird::RefMutexGuard queGuard(*port_que_sync);
return (port_receive.x_handy > 0 ||
port_queue && (port_qoffset < port_queue->getCount()));
return ((port_receive.x_handy > 0) || (port_qoffset < port_queue.getCount()));
}
void clearRecvQue()
{
Firebird::RefMutexGuard queGuard(*port_que_sync);
if (port_queue)
port_queue->clear();
port_queue.clear();
port_qoffset = 0;
port_receive.x_private = port_receive.x_base;
}
@ -548,7 +783,7 @@ struct rem_port
{
if (rs.save_qoffset > 0 && (rs.save_qoffset != port_qoffset))
{
Firebird::Array<char>& q = (*port_queue)[rs.save_qoffset - 1];
Firebird::Array<char>& q = port_queue[rs.save_qoffset - 1];
memcpy(port_receive.x_base, q.begin(), q.getCount());
}
port_qoffset = rs.save_qoffset;
@ -575,7 +810,6 @@ struct rem_port
ISC_STATUS execute_statement(P_OP, P_SQLDATA*, PACKET*);
ISC_STATUS fetch(P_SQLDATA*, PACKET*);
ISC_STATUS fetch_blob(P_SQLDATA*, PACKET*);
OBJCT get_id(BLK);
ISC_STATUS get_segment(P_SGMT*, PACKET*);
ISC_STATUS get_slice(P_SLC*, PACKET*);
ISC_STATUS info(P_OP, P_INFO*, PACKET*);
@ -601,34 +835,26 @@ struct rem_port
ISC_STATUS transact_request(P_TRRQ *, PACKET*);
};
// port_flags
const USHORT PORT_symmetric = 0x0001; // Server/client archiectures are symmetic
const USHORT PORT_rpc = 0x0002; // Protocol is remote procedure call
const USHORT PORT_async = 0x0004; // Port is asynchronous channel for events
const USHORT PORT_no_oob = 0x0008; // Don't send out of band data
const USHORT PORT_disconnect = 0x0010; // Disconnect is in progress
// This is set only in inet.cpp but never tested
const USHORT PORT_not_trusted = 0x0020; // Connection is from an untrusted node
const USHORT PORT_dummy_pckt_set= 0x0040; // A dummy packet interval is set
const USHORT PORT_partial_data = 0x0080; // Physical packet doesn't contain all API packet
const USHORT PORT_lazy = 0x0100; // Deferred operations are allowed
const USHORT PORT_server = 0x0200; // Server (not client) port
/* Queuing structure for Client batch fetches */
typedef bool (*t_rmtque_fn)(rem_port*, rmtque*, ISC_STATUS*, USHORT);
typedef struct rmtque
typedef struct rmtque : public Firebird::GlobalStorage
{
blk rmtque_header; // Memory allocator header
rmtque* rmtque_next; // Next entry in queue
void* rmtque_parm; // What request has response in queue
rrq::rrq_repeat* rmtque_message; // What message is pending
rdb* rmtque_rdb; // What database has pending msg
Rrq::rrq_repeat* rmtque_message; // What message is pending
Rdb* rmtque_rdb; // What database has pending msg
/* Fn that receives queued entry */
t_rmtque_fn rmtque_function;
public:
rmtque() :
rmtque_next(0), rmtque_parm(0), rmtque_message(0), rmtque_rdb(0), rmtque_function(0)
{ }
} *RMTQUE;
#endif // REMOTE_REMOTE_H

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,6 @@
#include "../remote/remote.h"
#include "../remote/xdr.h"
#include "../jrd/common.h"
#include "../remote/allr_proto.h"
#include "../remote/proto_proto.h"
#include "../remote/xdr_proto.h"
#include "../jrd/gds_proto.h"

View File

@ -73,6 +73,11 @@ typedef struct xdr_t
caddr_t x_private; /* pointer to private data */
caddr_t x_base; /* private used for position info */
int x_handy; /* extra private word */
public:
xdr_t() :
x_op(XDR_ENCODE), x_ops(0), x_public(0), x_private(0), x_base(0), x_handy(0)
{ }
} XDR;
/* Descriminated union crud */