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

1. Make signals handling in yValve MT safe.

2. Introduce new private API calls, fb__shutdown() and fb__shutdown_callback().
3. Introduce fb_smp_server - binary to run superclassic on posix.
4. Various cleanups.
This commit is contained in:
alexpeshkoff 2008-02-28 18:42:30 +00:00
parent 554f01ab4f
commit 00c63c1f8d
41 changed files with 527 additions and 937 deletions

View File

@ -70,23 +70,19 @@
fi fi
# Create log # Update ownership and SUID bits for files.
touch firebird.log
# Update ownership and SUID bits for programs.
chown -R $RunUser:$RunUser $FBRootDir
fixFilePermissions fixFilePermissions
# Create libgds.so links
createLinksForBackCompatibility createLinksForBackCompatibility
# Prepare for uninstall
buildUninstallFile buildUninstallFile
# Update the /etc/inetd.conf or xinetd entry # Update the /etc/inetd.conf or xinetd entry
updateInetdServiceEntry updateInetdServiceEntry
# Get inetd to reread new init files. # Get inetd to reread new init files.
resetInetdServer resetInetdServer

View File

@ -13,6 +13,7 @@ DefaultLibrary=libfbembed
fixFilePermissions() { fixFilePermissions() {
cd $FBRootDir
chown -R $RunUser:$RunGroup $FBRootDir chown -R $RunUser:$RunGroup $FBRootDir
# Turn other access off. # Turn other access off.
@ -42,18 +43,6 @@ fixFilePermissions() {
chmod a=rx isql chmod a=rx isql
chmod a=rx qli chmod a=rx qli
# Root SUID is still needed for group direct access.
# General users cannot run though.
for i in fb_lock_mgr
do
if [ -f $i ]
then
chown root $i
chmod ug=rx,o= $i
chmod ug+s $i
fi
done
# set up libraries # set up libraries
cd $FBRootDir cd $FBRootDir
cd lib cd lib
@ -70,11 +59,14 @@ fixFilePermissions() {
do do
FileName=$i.`hostname` FileName=$i.`hostname`
touch $FileName touch $FileName
chown $RunUser:$RunGroup $FileName
chmod ug=rw,o= $FileName chmod ug=rw,o= $FileName
done done
# Create log
touch firebird.log
# Fix the rest # Fix the rest
touch firebird.log
chmod ug=rw,o= firebird.log chmod ug=rw,o= firebird.log
chmod a=r aliases.conf chmod a=r aliases.conf
chmod a=r firebird.conf chmod a=r firebird.conf

View File

@ -404,6 +404,8 @@ buildUninstallFile() {
cp -r scripts $FBRootDir/misc/ cp -r scripts $FBRootDir/misc/
cp scripts/tarMainUninstall.sh $FBRootDir/bin/uninstall.sh cp scripts/tarMainUninstall.sh $FBRootDir/bin/uninstall.sh
cd $FBRootDir
} }
@ -447,6 +449,7 @@ createLinksForBackCompatibility() {
# to ensure it loads the fb equivalent. Eventually these should be # to ensure it loads the fb equivalent. Eventually these should be
# optional and in a seperate rpm install. MOD 7-Nov-2002. # optional and in a seperate rpm install. MOD 7-Nov-2002.
cd $FBRootDir
if [ "$1" ] if [ "$1" ]
then then
# Use library name from parameter # Use library name from parameter

View File

@ -327,10 +327,10 @@ otherfiles: misc_files
#_ Embedded Firebird Targets (Classic)_______________________________________ #_ Embedded Firebird Targets (Classic)_______________________________________
.PHONY: libfbembed inet_server embed_gfix embed_gbak embed_isql .PHONY: libfbembed inet_server fb_smp_server embed_gfix embed_gbak embed_isql
.PHONY: embed_gpre embed_util .PHONY: embed_gpre embed_util
classic_targets: $(PLAT_CLASSIC_PRE_TARGET) libfbembed inet_server embed_gfix embed_gbak embed_isql \ classic_targets: $(PLAT_CLASSIC_PRE_TARGET) libfbembed inet_server fb_smp_server embed_gfix embed_gbak embed_isql \
embed_gpre embed_util embed_gdef embed_qli embed_fbudf libfbclient $(PLAT_CLASSIC_POST_TARGET) embed_gpre embed_util embed_gdef embed_qli embed_fbudf libfbclient $(PLAT_CLASSIC_POST_TARGET)
libfbembed: libfbembed:
@ -339,6 +339,9 @@ libfbembed:
inet_server: inet_server:
$(MAKE) -f $(GEN_ROOT)/Makefile.inet_server $(MAKE) -f $(GEN_ROOT)/Makefile.inet_server
fb_smp_server:
$(MAKE) -f $(GEN_ROOT)/Makefile.smp_server
embed_gfix: embed_gfix:
$(MAKE) -f $(GEN_ROOT)/Makefile.embed.gfix $(MAKE) -f $(GEN_ROOT)/Makefile.embed.gfix

View File

@ -36,6 +36,7 @@ global:
gds__blob_size; gds__blob_size;
gds__cancel_blob; gds__cancel_blob;
gds__cancel_events; gds__cancel_events;
gds__cancel_operation;
gds__close; gds__close;
gds__close_blob; gds__close_blob;
gds__commit_retaining; gds__commit_retaining;
@ -71,6 +72,7 @@ global:
gds__get_prefix; gds__get_prefix;
gds__get_segment; gds__get_segment;
gds__get_slice; gds__get_slice;
gds__handle_cleanup;
gds__interprete; gds__interprete;
gds__log; gds__log;
gds__log_status; gds__log_status;
@ -133,6 +135,9 @@ global:
gds_alloc_flag_unfreed; gds_alloc_flag_unfreed;
gds_alloc_report; gds_alloc_report;
fb__shutdown;
fb__shutdown_callback;
perf_format; perf_format;
perf_get_info; perf_get_info;
perf_report; perf_report;

View File

@ -273,6 +273,7 @@ FBEMBED_LINK= -L$(LIB) -lfbembed
FB_SUPER_SERVER = $(BIN)/fbserver$(EXEC_EXT) FB_SUPER_SERVER = $(BIN)/fbserver$(EXEC_EXT)
FB_CLASSIC_SERVER = $(BIN)/fb_inet_server$(EXEC_EXT) FB_CLASSIC_SERVER = $(BIN)/fb_inet_server$(EXEC_EXT)
FB_DAEMON = $(BIN)/fb_smp_server$(EXEC_EXT)
STATIC_CXXSUPPORT_LIB = -lsupc++ STATIC_CXXSUPPORT_LIB = -lsupc++

View File

@ -1152,6 +1152,7 @@ gen/Makefile.static.gbak:${MAKE_SRC_DIR}/Makefile.in.static.gbak
gen/Makefile.static.isql:${MAKE_SRC_DIR}/Makefile.in.static.isql gen/Makefile.static.isql:${MAKE_SRC_DIR}/Makefile.in.static.isql
gen/Makefile.refDatabases:${MAKE_SRC_DIR}/Makefile.in.refDatabases gen/Makefile.refDatabases:${MAKE_SRC_DIR}/Makefile.in.refDatabases
gen/Makefile.fbserver:${MAKE_SRC_DIR}/Makefile.in.fbserver gen/Makefile.fbserver:${MAKE_SRC_DIR}/Makefile.in.fbserver
gen/Makefile.smp_server:${MAKE_SRC_DIR}/Makefile.in.smp_server
gen/Makefile.libfbclient:${MAKE_SRC_DIR}/Makefile.in.libfbclient gen/Makefile.libfbclient:${MAKE_SRC_DIR}/Makefile.in.libfbclient
gen/Makefile.client.fbudf:${MAKE_SRC_DIR}/Makefile.in.client.fbudf gen/Makefile.client.fbudf:${MAKE_SRC_DIR}/Makefile.in.client.fbudf
gen/Makefile.client.gbak:${MAKE_SRC_DIR}/Makefile.in.client.gbak gen/Makefile.client.gbak:${MAKE_SRC_DIR}/Makefile.in.client.gbak

View File

@ -43,6 +43,9 @@
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../jrd/constants.h" #include "../jrd/constants.h"
#ifdef WIN_NT
#include <direct.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -662,4 +665,17 @@ SLONG genReadOnlyId()
return ++cnt; return ++cnt;
} }
void getCwd(Firebird::PathName& pn)
{
char *buffer = pn.getBuffer(MAXPATHLEN);
#if defined(WIN_NT)
_getcwd(buffer, MAXPATHLEN);
#elif defined(HAVE_GETCWD)
getcwd(buffer, MAXPATHLEN);
#else
getwd(buffer);
#endif
pn.recalculate_length();
}
} // namespace fb_utils } // namespace fb_utils

View File

@ -95,6 +95,8 @@ namespace fb_utils
Firebird::PathName get_process_name(); Firebird::PathName get_process_name();
SLONG genReadOnlyId(); SLONG genReadOnlyId();
void getCwd(Firebird::PathName& pn);
} // namespace fb_utils } // namespace fb_utils
#endif // INCLUDE_UTILS_PROTO_H #endif // INCLUDE_UTILS_PROTO_H

View File

@ -25,10 +25,7 @@
#include "../jrd/common.h" #include "../jrd/common.h"
#include "../dsql/dsql.h" #include "../dsql/dsql.h"
#include "../dsql/node.h"
namespace Dsql {
enum nod_t;
}
namespace Jrd { namespace Jrd {

View File

@ -301,8 +301,8 @@ public:
SSHORT udf_character_set_id; SSHORT udf_character_set_id;
USHORT udf_character_length; USHORT udf_character_length;
USHORT udf_flags; USHORT udf_flags;
Firebird::Array<dsc> udf_arguments;
Firebird::MetaName udf_name; Firebird::MetaName udf_name;
Firebird::Array<dsc> udf_arguments;
}; };
// udf_flags bits // udf_flags bits
@ -433,8 +433,8 @@ public:
DsqlContextStack req_dt_context; //!< Save contexts for views of derived tables DsqlContextStack req_dt_context; //!< Save contexts for views of derived tables
dsql_sym* req_name; //!< Name of request dsql_sym* req_name; //!< Name of request
dsql_sym* req_cursor; //!< Cursor symbol, if any dsql_sym* req_cursor; //!< Cursor symbol, if any
dsql_dbb* req_dbb; //!< DSQL attachment dsql_dbb* req_dbb; //!< DSQL attachment
jrd_tra* req_transaction; //!< JRD transaction jrd_tra* req_transaction; //!< JRD transaction
dsql_nod* req_ddl_node; //!< Store metadata request dsql_nod* req_ddl_node; //!< Store metadata request
dsql_nod* req_blk_node; //!< exec_block node dsql_nod* req_blk_node; //!< exec_block node
class dsql_blb* req_blob; //!< Blob info for blob requests class dsql_blb* req_blob; //!< Blob info for blob requests

View File

@ -27,18 +27,25 @@
#define DSQL_MAKE_PROTO_H #define DSQL_MAKE_PROTO_H
#include "../dsql/sym.h" #include "../dsql/sym.h"
#include "../dsql/node.h"
namespace Jrd { namespace Jrd {
class dsql_nod; class dsql_nod;
class dsql_fld; class dsql_fld;
class dsql_req; class dsql_req;
enum dsql_constant_type;
enum sym_type; // Parameters to MAKE_constant
enum dsql_constant_type {
CONSTANT_STRING = 0, // stored as a string
// CONSTANT_SLONG = 1, // stored as a SLONG
CONSTANT_DOUBLE = 2, // stored as a string
CONSTANT_DATE = 3, // stored as a SLONG
CONSTANT_TIME = 4, // stored as a ULONG
CONSTANT_TIMESTAMP = 5, // stored as a QUAD
CONSTANT_SINT64 = 6 // stored as a SINT64
};
}; };
namespace Dsql {
enum nod_t;
}
Jrd::dsql_nod* MAKE_const_slong(SLONG); Jrd::dsql_nod* MAKE_const_slong(SLONG);
Jrd::dsql_nod* MAKE_constant(Jrd::dsql_str*, Jrd::dsql_constant_type); Jrd::dsql_nod* MAKE_constant(Jrd::dsql_str*, Jrd::dsql_constant_type);

View File

@ -1064,17 +1064,6 @@ enum nod_flags_vals {
NOD_SPECIAL_SYNTAX = 1 // nod_sys_function NOD_SPECIAL_SYNTAX = 1 // nod_sys_function
}; };
// Parameters to MAKE_constant
enum dsql_constant_type {
CONSTANT_STRING = 0, // stored as a string
// CONSTANT_SLONG = 1, // stored as a SLONG
CONSTANT_DOUBLE = 2, // stored as a string
CONSTANT_DATE = 3, // stored as a SLONG
CONSTANT_TIME = 4, // stored as a ULONG
CONSTANT_TIMESTAMP = 5, // stored as a QUAD
CONSTANT_SINT64 = 6 // stored as a SINT64
};
}; // namespace }; // namespace
#endif // DSQL_NODE_H #endif // DSQL_NODE_H

View File

@ -112,6 +112,7 @@ enum literal_string_type
#include "../isql/show_proto.h" #include "../isql/show_proto.h"
#include "../jrd/perf_proto.h" #include "../jrd/perf_proto.h"
#include "../jrd/utl_proto.h" #include "../jrd/utl_proto.h"
#include "../jrd/why_proto.h"
#include "../jrd/gdsassert.h" #include "../jrd/gdsassert.h"
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
@ -353,7 +354,7 @@ static int process_statement(const TEXT*, XSQLDA**);
#ifdef WIN_NT #ifdef WIN_NT
static BOOL CALLBACK query_abort(DWORD); static BOOL CALLBACK query_abort(DWORD);
#else #else
static void CLIB_ROUTINE query_abort(int); static int API_ROUTINE query_abort();
#endif #endif
static bool stdin_redirected(); static bool stdin_redirected();
static void strip_quotes(const TEXT*, TEXT*); static void strip_quotes(const TEXT*, TEXT*);
@ -4037,14 +4038,7 @@ static void do_isql()
#ifdef WIN_NT #ifdef WIN_NT
SetConsoleCtrlHandler(query_abort, TRUE); SetConsoleCtrlHandler(query_abort, TRUE);
#elif defined(HAVE_SIGACTION) #elif defined(HAVE_SIGACTION)
struct sigaction sig_action; fb__shutdown_callback(0, query_abort, FB_SHUT_PREPROVIDERS);
if (sigaction(SIGINT, NULL, &sig_action) == 0) {
sig_action.sa_handler = query_abort;
sig_action.sa_flags |= SA_RESTART;
sigaction(SIGINT, &sig_action, NULL);
}
#else
signal(SIGINT, query_abort);
#endif #endif
// Open database and start tansaction // Open database and start tansaction
@ -8545,7 +8539,7 @@ static int process_statement(const TEXT* string,
#ifdef WIN_NT #ifdef WIN_NT
static BOOL CALLBACK query_abort(DWORD dwCtrlType) static BOOL CALLBACK query_abort(DWORD dwCtrlType)
#else #else
static void CLIB_ROUTINE query_abort(int) static int API_ROUTINE query_abort()
#endif #endif
{ {
/************************************** /**************************************
@ -8559,18 +8553,31 @@ static void CLIB_ROUTINE query_abort(int)
* *
**************************************/ **************************************/
bool flag = true;
#ifdef WIN_NT #ifdef WIN_NT
if (dwCtrlType != CTRL_C_EVENT) if (dwCtrlType != CTRL_C_EVENT)
return FALSE; return FALSE;
#else
if (DB)
{
ISC_STATUS_ARRAY status;
flag = (gds__cancel_operation(status, &DB, CANCEL_raise) == FB_SUCCESS);
}
#endif #endif
if (Interactive) if (flag)
Interrupt_flag = true; {
else if (Interactive)
Abort_flag = true; Interrupt_flag = true;
else
Abort_flag = true;
}
#ifdef WIN_NT #ifdef WIN_NT
return TRUE; return TRUE;
#else
return 1; // we do not want to proceed with shutdown
#endif #endif
} }

View File

@ -59,7 +59,6 @@
namespace { namespace {
TLS_DECLARE (void*, tSpecific);
TLS_DECLARE (ThreadData*, tData); TLS_DECLARE (ThreadData*, tData);
} }
@ -82,23 +81,6 @@ ThreadData* ThreadData::getSpecific(void)
} }
void ThreadData::getSpecificData(void **t_data)
{
/**************************************
*
* T H D _ g e t s p e c i f i c _ d a t a
*
**************************************
*
* Functional description
* return the previously stored t_data.
*
**************************************/
*t_data = TLS_GET(tSpecific);
}
void ThreadData::putSpecific() void ThreadData::putSpecific()
{ {
/************************************** /**************************************
@ -116,23 +98,6 @@ void ThreadData::putSpecific()
} }
void ThreadData::putSpecificData(void *t_data)
{
/**************************************
*
* T H D _ p u t s p e c i f i c _ d a t a
*
**************************************
*
* Functional description
* Store the passed t_data
*
**************************************/
TLS_SET(tSpecific, t_data);
}
void ThreadData::restoreSpecific() void ThreadData::restoreSpecific()
{ {
/************************************** /**************************************

View File

@ -68,9 +68,6 @@ public:
static ThreadData* getSpecific(void); static ThreadData* getSpecific(void);
void putSpecific(); void putSpecific();
static void restoreSpecific(void); static void restoreSpecific(void);
static void getSpecificData(void** t_data);
static void putSpecificData(void* t_data);
}; };
// Thread entry point definitions might much better look in ThreadStart.h, // Thread entry point definitions might much better look in ThreadStart.h,

View File

@ -23,17 +23,8 @@
/* /*
Order of battle in ENTRY macro: Order of battle in ENTRY macro:
generic name
current local access method entrypoint current local access method entrypoint
prior local access method (bridge) entrypoint
remote entrypoint remote entrypoint
OS2 remote name
Central server interface
RDB interface entrypoint
Pipe server interface
Bridge pipe server interface
Windows local access method entrypoint
Win95 interprocess interface
*/ */
/***************************************************** /*****************************************************
@ -226,4 +217,7 @@ ENTRYPOINT( jrd8_dsql_cache,
ENTRYPOINT( jrd8_internal_compile_request, ENTRYPOINT( jrd8_internal_compile_request,
/* REM_internal_compile_request */ no_entrypoint) /* REM_internal_compile_request */ no_entrypoint)
ENTRYPOINT( jrd8_shutdown_all,
/* REM_shutdown_all */ no_entrypoint)
#undef ENTRYPOINT #undef ENTRYPOINT

View File

@ -55,6 +55,7 @@
#include "../common/config/config.h" #include "../common/config/config.h"
#include "../common/config/dir_list.h" #include "../common/config/dir_list.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../common/utils_proto.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_IPC_H #ifdef HAVE_SYS_IPC_H
@ -75,12 +76,6 @@
const char INET_FLAG = ':'; const char INET_FLAG = ':';
#ifdef SUPERSERVER
#define GETWD(buf) JRD_getdir(buf)
#else
#define GETWD(buf) fb_getcwd(buf)
#endif /* SUPERSERVER */
#ifdef DARWIN #ifdef DARWIN
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>
@ -859,8 +854,9 @@ bool ISC_expand_filename(tstring& file_name, bool expand_mounts)
// Expand the file name // Expand the file name
#ifdef SUPERSERVER #ifdef SUPERSERVER
if ((!fully_qualified_path) && JRD_getdir(file_name)) if (!fully_qualified_path)
{ {
fb_utils::getCwd(file_name);
if (device.hasData() && device[0] == file_name[0]) { if (device.hasData() && device[0] == file_name[0]) {
// case where temp is of the form "c:foo.fdb" and // case where temp is of the form "c:foo.fdb" and
// expanded_name is "c:\x\y". // expanded_name is "c:\x\y".
@ -888,8 +884,7 @@ bool ISC_expand_filename(tstring& file_name, bool expand_mounts)
else else
#endif #endif
{ {
// Here we get "." and ".." translated by the API, but ONLY IF we are using // Here we get "." and ".." translated by the API.
// local conection, because in that case, JRD_getdir() returns false.
if (!get_full_path(temp, file_name)) if (!get_full_path(temp, file_name))
{ {
file_name = temp; file_name = temp;
@ -1100,10 +1095,7 @@ static void expand_filename2(tstring& buff, bool expand_mounts)
// If the file is local, expand partial pathnames with default directory // If the file is local, expand partial pathnames with default directory
if (*from && *from != '/') if (*from && *from != '/')
{ {
if (! GETWD(buff)) fb_utils::getCwd(buff);
{
buff = "";
}
buff += '/'; buff += '/';
} }

View File

@ -129,6 +129,7 @@
#include "../jrd/IntlManager.h" #include "../jrd/IntlManager.h"
#include "../common/classes/fb_tls.h" #include "../common/classes/fb_tls.h"
#include "../common/classes/ClumpletReader.h" #include "../common/classes/ClumpletReader.h"
#include "../common/utils_proto.h"
#include "../jrd/DebugInterface.h" #include "../jrd/DebugInterface.h"
#include "../dsql/dsql.h" #include "../dsql/dsql.h"
@ -464,6 +465,7 @@ static void shutdown_database(Database*, const bool);
static void strip_quotes(Firebird::string&); static void strip_quotes(Firebird::string&);
static void purge_attachment(thread_db*, ISC_STATUS*, Attachment*, const bool); static void purge_attachment(thread_db*, ISC_STATUS*, Attachment*, const bool);
static void getUserInfo(UserId&, const DatabaseOptions&); static void getUserInfo(UserId&, const DatabaseOptions&);
static bool shutdown_all();
//____________________________________________________________ //____________________________________________________________
// //
@ -542,6 +544,7 @@ const int BUFFER_LENGTH128 = 128;
#define GDS_TRANSACT_REQUEST jrd8_transact_request #define GDS_TRANSACT_REQUEST jrd8_transact_request
#define GDS_TRANSACTION_INFO jrd8_transaction_info #define GDS_TRANSACTION_INFO jrd8_transaction_info
#define GDS_UNWIND jrd8_unwind_request #define GDS_UNWIND jrd8_unwind_request
#define GDS_SHUTDOWN jrd8_shutdown_all
#define GDS_DSQL_ALLOCATE jrd8_allocate_statement #define GDS_DSQL_ALLOCATE jrd8_allocate_statement
#define GDS_DSQL_EXECUTE jrd8_execute #define GDS_DSQL_EXECUTE jrd8_execute
@ -3378,6 +3381,35 @@ ISC_STATUS GDS_START(ISC_STATUS * user_status,
} }
ISC_STATUS GDS_SHUTDOWN(ISC_STATUS * user_status)
{
/**************************************
*
* G D S _ S H U T D O W N
*
**************************************
*
* Functional description
* Rollback every transaction, release
* every attachment, and shutdown every
* database.
*
**************************************/
ISC_STATUS *s = user_status;
*s++ = isc_arg_gds;
*s = isc_arg_end;
if (!shutdown_all())
{
*s++ = isc_random;
*s++ = isc_arg_string;
*s++ = (ISC_STATUS)("Forced server shutdown - not all databases closed");
}
return user_status[1];
}
ISC_STATUS GDS_START_MULTIPLE(ISC_STATUS * user_status, ISC_STATUS GDS_START_MULTIPLE(ISC_STATUS * user_status,
jrd_tra** tra_handle, jrd_tra** tra_handle,
USHORT count, USHORT count,
@ -3998,82 +4030,6 @@ ISC_STATUS GDS_DSQL_SQL_INFO(ISC_STATUS* user_status,
} }
#ifdef SUPERSERVER
bool JRD_getdir(Firebird::PathName& buf)
{
/**************************************
*
* J R D _ g e t d i r
*
**************************************
*
* Functional description
* Current working directory is cached in the attachment
* block. Get it out. This function could be called before
* an attachment is created. In such a case thread specific
* data (t_data) will hold the user name which will be used
* to get the users home directory.
*
**************************************/
char* t_data = NULL;
char b[MAXPATHLEN];
ThreadData::getSpecificData((void**) &t_data);
if (t_data) {
#ifdef WIN_NT
GetCurrentDirectory(MAXPATHLEN, b);
buf = b;
#else
const struct passwd* pwd;
strcpy(b, t_data);
pwd = getpwnam(b);
if (pwd)
buf = pwd->pw_dir;
else // No home dir for this users here. Default to server dir
return fb_getcwd(buf);
#endif
}
else
{
thread_db* tdbb = JRD_get_thread_data();
/** If the server has not done a JRD_set_thread_data prior to this call
(which will be the case when connecting via IPC), thread_db will
be NULL so do not attempt to get the attachment handle from
thread_db. Just return false as described below.
NOTE: The only time
this code is entered via IPC is if the database name = "".
**/
/** In case of backup/restore APIs, JRD_set_thread_data has been done but
the thread's context is a 'gbak' specific, so don't try extract
attachment from there.
**/
Attachment* attachment;
if (tdbb && (tdbb->getType() == ThreadData::tddDBB))
attachment = tdbb->getAttachment();
else
return false;
/**
An older version of client will not be sending isc_dpb_working directory
so in all probabilities attachment->att_working_directory will be null.
return false so that ISC_expand_filename will create the file in fbserver's dir
**/
if (!attachment || attachment->att_working_directory.empty())
{
return false;
}
buf = attachment->att_working_directory;
}
return true;
}
#endif // SUPERSERVER
#ifdef DEBUG_PROCS #ifdef DEBUG_PROCS
void JRD_print_procedure_info(thread_db* tdbb, const char* mesg) void JRD_print_procedure_info(thread_db* tdbb, const char* mesg)
{ {
@ -4698,38 +4654,7 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
switch (rdr.getClumpTag()) switch (rdr.getClumpTag())
{ {
case isc_dpb_working_directory: case isc_dpb_working_directory:
{ rdr.getPath(dpb_working_directory);
rdr.getPath(dpb_working_directory);
// CLASSIC have no thread data. Init to zero.
char* t_data = 0;
ThreadData::getSpecificData((void **) &t_data);
// Null value for working_directory implies remote database. So get
// the users HOME directory
#ifndef WIN_NT
if (dpb_working_directory.isEmpty()) {
struct passwd *passwd = NULL;
if (t_data)
passwd = getpwnam(t_data);
if (passwd)
{
dpb_working_directory = passwd->pw_dir;
}
else { // No home dir for this users here. Default to server dir
fb_getcwd(dpb_working_directory);
}
}
#endif
if (t_data)
{
free(t_data);
t_data = NULL;
}
// Null out the thread local data so that further references will fail
ThreadData::putSpecificData(0);
}
break; break;
case isc_dpb_set_page_buffers: case isc_dpb_set_page_buffers:
@ -6006,46 +5931,6 @@ void JRD_shutdown_all(bool asyncMode)
} }
void JRD_shutdown_attachment(Attachment** handle, Attachment** released)
{
/**************************************
*
* J R D _ s h u t d o w n _ a t t a c h m e n t
*
**************************************
*
* Functional description
* Release attachment.
*
**************************************/
ISC_STATUS_ARRAY temp_status;
ThreadContextHolder tdbb(temp_status);
try
{
Firebird::MutexLockGuard guard(databases_mutex);
Attachment* attachment = *handle;
validateHandle(tdbb, attachment);
DatabaseContextHolder dbbHolder(tdbb);
purge_attachment(tdbb, temp_status, attachment, true);
if (released)
{
*released++ = attachment;
}
}
catch (const Firebird::Exception&)
{} // no-op
if (released)
{
*released = NULL;
}
}
static unsigned int purge_transactions(thread_db* tdbb, static unsigned int purge_transactions(thread_db* tdbb,
Attachment* attachment, Attachment* attachment,
const bool force_flag, const bool force_flag,

View File

@ -143,7 +143,7 @@ ISC_STATUS jrd8_transact_request(ISC_STATUS*, Jrd::Attachment**,
USHORT, SCHAR*, USHORT, USHORT, SCHAR*, USHORT,
SCHAR*); SCHAR*);
ISC_STATUS jrd8_unwind_request(ISC_STATUS *, Jrd::jrd_req**, SSHORT); ISC_STATUS jrd8_unwind_request(ISC_STATUS *, Jrd::jrd_req**, SSHORT);
ISC_STATUS jrd8_shutdown_all(ISC_STATUS *);
ISC_STATUS jrd8_allocate_statement(ISC_STATUS*, ISC_STATUS jrd8_allocate_statement(ISC_STATUS*,
Jrd::Attachment**, Jrd::Attachment**,
Jrd::dsql_req**); Jrd::dsql_req**);
@ -209,42 +209,15 @@ enum JRD_info_tag
UCHAR* JRD_num_attachments(UCHAR* const, USHORT, JRD_info_tag, ULONG*, ULONG*); UCHAR* JRD_num_attachments(UCHAR* const, USHORT, JRD_info_tag, ULONG*, ULONG*);
void JRD_shutdown_all(bool); void JRD_shutdown_all(bool);
void JRD_shutdown_attachment(Jrd::Attachment**, Jrd::Attachment**);
bool JRD_reschedule(Jrd::thread_db*, SLONG, bool); bool JRD_reschedule(Jrd::thread_db*, SLONG, bool);
// Call this function from the debugger if desired // Call this function from the debugger if desired
void JRD_print_pools(const char* filename); void JRD_print_pools(const char* filename);
#ifdef SUPERSERVER
bool JRD_getdir(Firebird::PathName&);
#endif
#ifdef DEBUG_PROCS #ifdef DEBUG_PROCS
void JRD_print_procedure_info(Jrd::thread_db*, const char*); void JRD_print_procedure_info(Jrd::thread_db*, const char*);
#endif #endif
#ifdef WIN_NT
#include <direct.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
inline bool fb_getcwd(Firebird::PathName& pn)
{
char buffer[MAXPATHLEN];
#if defined(WIN_NT)
_getcwd(buffer, MAXPATHLEN);
#elif defined(HAVE_GETCWD)
getcwd(buffer, MAXPATHLEN);
#else
getwd(buffer);
#endif
pn = buffer;
return bool(buffer);
}
#endif /* JRD_JRD_PROTO_H */ #endif /* JRD_JRD_PROTO_H */

View File

@ -336,7 +336,7 @@ static bool isc_signal2(
/* Que up the new ISC signal handler routine */ /* Que up the new ISC signal handler routine */
que_signal(signal_number, handler, arg, flags, old_sig_w_siginfo); que_signal(signal_number, handler, arg, flags, false);
return rc; return rc;
} }

View File

@ -599,6 +599,7 @@ jrd_file* PIO_open(Database* dbb,
* Open a database file. * Open a database file.
* *
**************************************/ **************************************/
bool readOnly = false;
const TEXT* const ptr = (string.hasData() ? string : file_name).c_str(); const TEXT* const ptr = (string.hasData() ? string : file_name).c_str();
int desc = openFile(ptr, false, false, false); int desc = openFile(ptr, false, false, false);
@ -613,16 +614,15 @@ jrd_file* PIO_open(Database* dbb,
isc_arg_cstring, file_name.length(), ERR_cstring(file_name), isc_arg_cstring, file_name.length(), ERR_cstring(file_name),
isc_arg_gds, isc_io_open_err, isc_arg_unix, errno, 0); isc_arg_gds, isc_io_open_err, isc_arg_unix, errno, 0);
} }
else { /* If this is the primary file, set Database flag to indicate that it is
/* If this is the primary file, set Database flag to indicate that it is * being opened ReadOnly. This flag will be used later to compare with
* being opened ReadOnly. This flag will be used later to compare with * the Header Page flag setting to make sure that the database is set
* the Header Page flag setting to make sure that the database is set * ReadOnly.
* ReadOnly. */
*/ PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); if (!pageSpace->file)
if (!pageSpace->file) dbb->dbb_flags |= DBB_being_opened_read_only;
dbb->dbb_flags |= DBB_being_opened_read_only; readOnly = true;
}
} }
// posix_fadvise(desc, 0, 0, POSIX_FADV_RANDOM); // posix_fadvise(desc, 0, 0, POSIX_FADV_RANDOM);
@ -647,6 +647,8 @@ jrd_file* PIO_open(Database* dbb,
jrd_file *file; jrd_file *file;
try { try {
file = setup_file(dbb, string, desc); file = setup_file(dbb, string, desc);
if (readOnly)
file->fil_flags |= FIL_readonly;
} }
catch (const Firebird::Exception&) { catch (const Firebird::Exception&) {
close(desc); close(desc);

View File

@ -25,7 +25,7 @@
#include <windows.h> #include <windows.h>
#include "../jrd/common.h" #include "../jrd/common.h"
#include "../../utilities/install/registry.h" #include "../../utilities/install/registry.h"
#include "../jrd/jrd_proto.h" #include "../jrd/why_proto.h"
#include "../jrd/thread_proto.h" #include "../jrd/thread_proto.h"
@ -35,7 +35,7 @@ BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID reserved)
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
#ifdef EMBEDDED #ifdef EMBEDDED
JRD_shutdown_all(false); fb__shutdown(0);
#endif #endif
break; break;

View File

@ -136,7 +136,7 @@ namespace {
}; };
const size_t MAX_CONCURRENT_FAILURES = 16; const size_t MAX_CONCURRENT_FAILURES = 16;
const int MAX_FAILED_ATTEMPTS = 2; //4; const int MAX_FAILED_ATTEMPTS = 4;
const int FAILURE_DELAY = 8; // seconds const int FAILURE_DELAY = 8; // seconds
class FailedLogins : private Firebird::SortedObjectsArray<FailedLogin, class FailedLogins : private Firebird::SortedObjectsArray<FailedLogin,

View File

@ -440,8 +440,8 @@ RELATION(nam_mon_rec_stats, rel_mon_rec_stats, ODS_11_1, rel_virtual)
FIELD(f_mon_rec_expunges, nam_mon_rec_expunges, fld_counter, 0, 0, 0, 0) FIELD(f_mon_rec_expunges, nam_mon_rec_expunges, fld_counter, 0, 0, 0, 0)
END_RELATION END_RELATION
RELATION(nam_mon_ctx_vars, rel_mon_ctx_vars, ODS_11_2, rel_virtual) RELATION(nam_mon_ctx_vars, rel_mon_ctx_vars, ODS_11_2, rel_virtual)
FIELD(f_mon_ctx_vars_att_id, nam_mon_att_id, fld_att_id, 0, 0, 0, 0) FIELD(f_mon_ctx_var_att_id, nam_mon_att_id, fld_att_id, 0, 0, 0, 0)
FIELD(f_mon_ctx_vars_tra_id, nam_mon_tra_id, fld_trans_id, 0, 0, 0, 0) FIELD(f_mon_ctx_var_tra_id, nam_mon_tra_id, fld_trans_id, 0, 0, 0, 0)
FIELD(f_mon_ctx_vars_name, nam_mon_var_name, fld_ctx_var_name, 0, 0, 0, 0) FIELD(f_mon_ctx_var_name, nam_mon_var_name, fld_ctx_var_name, 0, 0, 0, 0)
FIELD(f_mon_ctx_vars_value, nam_mon_var_value, fld_ctx_var_value, 0, 0, 0, 0) FIELD(f_mon_ctx_var_value, nam_mon_var_value, fld_ctx_var_value, 0, 0, 0, 0)
END_RELATION END_RELATION

View File

@ -100,8 +100,8 @@ public:
tra_blobs(p), tra_blobs(p),
tra_resources(*p), tra_resources(*p),
tra_context_vars(*p), tra_context_vars(*p),
tra_open_cursors(*p), tra_lock_timeout(DEFAULT_LOCK_TIMEOUT),
tra_lock_timeout(DEFAULT_LOCK_TIMEOUT) tra_open_cursors(*p)
{} {}
~jrd_tra() ~jrd_tra()

View File

@ -88,20 +88,14 @@
#include "../common/classes/rwlock.h" #include "../common/classes/rwlock.h"
#include "../common/classes/auto.h" #include "../common/classes/auto.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../common/classes/semaphore.h"
#include "../jrd/constants.h" #include "../jrd/constants.h"
#include "../jrd/thread_proto.h"
#include "../jrd/ThreadStart.h"
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
#include "../jrd/blr.h" #include "../jrd/blr.h"
#endif #endif
#if !defined(SUPERCLIENT)
#define CANCEL_disable 1
#define CANCEL_enable 2
#define CANCEL_raise 3
//extern "C" ISC_STATUS jrd8_cancel_operation(ISC_STATUS *, Jrd::Attachment**, USHORT);
void JRD_shutdown_all(bool);
void JRD_shutdown_attachment(Jrd::Attachment**, Jrd::Attachment**);
#endif
using namespace YValve; using namespace YValve;
// In 2.0 it's hard to include ibase.h in why.cpp due to API declaration conflicts. // In 2.0 it's hard to include ibase.h in why.cpp due to API declaration conflicts.
@ -166,7 +160,7 @@ inline void nullCheck(const FB_API_HANDLE* ptr, ISC_STATUS code)
{ {
// this function is called for incoming API handlers, // this function is called for incoming API handlers,
// proposed to be created by the call // proposed to be created by the call
if (*ptr) if ((!ptr) || (*ptr))
{ {
bad_handle(code); bad_handle(code);
} }
@ -207,7 +201,56 @@ namespace
Firebird::GlobalPtr<Firebird::RWLock> handleMappingLock; Firebird::GlobalPtr<Firebird::RWLock> handleMappingLock;
Firebird::InitInstance<Firebird::SortedArray<Attachment*> > attachments; Firebird::InitInstance<Firebird::SortedArray<Attachment*> > attachments;
Firebird::GlobalPtr<Firebird::Mutex> attachmentsMutex; Firebird::GlobalPtr<Firebird::Mutex> attachmentsMutex, shutdownMutex;
class ShutChain : public Firebird::GlobalStorage
{
private:
ShutChain(ShutChain* link, FPTR_INT cb, const int m)
: next(link), callBack(cb), mask(m) { }
~ShutChain() { }
private:
static ShutChain* list;
ShutChain* next;
FPTR_INT callBack;
int mask;
public:
static void add(FPTR_INT cb, const int m)
{
Firebird::MutexLockGuard guard(shutdownMutex);
for (ShutChain* chain = list; chain; chain = chain->next)
{
if (chain->callBack == cb && chain->mask == m)
{
return;
}
}
list = new ShutChain(list, cb, m);
}
static int run(const int m)
{
int rc = 0;
Firebird::MutexLockGuard guard(shutdownMutex);
for (ShutChain* chain = list; chain; chain = chain->next)
{
if (chain->mask & m && chain->callBack())
{
rc = 1;
}
}
return rc;
}
};
ShutChain* ShutChain::list = 0;
}; };
namespace YValve namespace YValve
@ -220,7 +263,6 @@ namespace YValve
{ // scope for write lock on handleMappingLock { // scope for write lock on handleMappingLock
Firebird::WriteLockGuard sync(handleMappingLock); Firebird::WriteLockGuard sync(handleMappingLock);
fb_assert(handleMapping);
// Loop until we find an empty handle slot. // Loop until we find an empty handle slot.
// This is to care of case when counter rolls over // This is to care of case when counter rolls over
do { do {
@ -246,7 +288,6 @@ namespace YValve
{ {
Firebird::ReadLockGuard sync(handleMappingLock); Firebird::ReadLockGuard sync(handleMappingLock);
fb_assert(handleMapping);
HandleMapping::Accessor accessor(&handleMapping); HandleMapping::Accessor accessor(&handleMapping);
if (accessor.locate(handle)) if (accessor.locate(handle))
{ {
@ -268,15 +309,6 @@ namespace YValve
return parent ? parent->handle : 0; return parent ? parent->handle : 0;
} }
void BaseHandle::cancel()
{
if (!parent)
{
return;
}
parent->cancel2();
}
BaseHandle::~BaseHandle() BaseHandle::~BaseHandle()
{ {
if (user_handle) if (user_handle)
@ -287,7 +319,6 @@ namespace YValve
Firebird::WriteLockGuard sync(handleMappingLock); Firebird::WriteLockGuard sync(handleMappingLock);
// Silently ignore bad handles for PROD_BUILD // Silently ignore bad handles for PROD_BUILD
fb_assert(handleMapping);
if (handleMapping->locate(public_handle)) if (handleMapping->locate(public_handle))
{ {
handleMapping->fastRemove(); handleMapping->fastRemove();
@ -411,22 +442,12 @@ const USHORT DESCRIBE_BUFFER_SIZE = 1024; // size of buffer used in isc_dsql_de
namespace namespace
{ {
/* // Status: Provides correct status vector for operation and init() it.
* class YEntry:
* 1. Provides correct status vector for operation and init() it.
* 2. Tracks subsystem_enter/exit() calls.
* For single-threaded systems:
* 3. Knows location of primary handle and detachs database when
* cancel / shutdown takes place.
* In some cases (primarily - attach/create) specific handle may
* be missing.
*/
class Status class Status
{ {
public: public:
Status(ISC_STATUS* v) throw() Status(ISC_STATUS* v) throw()
: local_vector(v ? v : local_status), doExit(true) : local_vector(v ? v : local_status)
{ {
init_status(local_vector); init_status(local_vector);
} }
@ -436,275 +457,156 @@ namespace
return local_vector; return local_vector;
} }
// don't exit on missing user_status
// That feature is suspicious: on windows after
// printf() and exit() will happen silent exit. AP-2007.
void ok()
{
doExit = false;
}
~Status() ~Status()
{ {
#ifdef DEV_BUILD #ifdef DEV_BUILD
check_status_vector(local_vector); check_status_vector(local_vector);
#endif #endif
#ifndef SUPERSERVER
if (local_vector == local_status &&
local_vector[0] == isc_arg_gds &&
local_vector[1] != FB_SUCCESS &&
doExit)
{
// user did not specify status, but error took place:
// should better specify it next time :-(
gds__print_status(local_vector);
exit((int) local_vector[1]);
}
#endif
} }
private: private:
ISC_STATUS_ARRAY local_status; ISC_STATUS_ARRAY local_status;
ISC_STATUS* local_vector; ISC_STATUS* local_vector;
bool doExit;
}; };
#ifndef SERVER_SHUTDOWN // appears this macro has now nothing with shutdown #ifdef UNIX
int killed;
bool procInt, procTerm;
template <typename Array> Firebird::GlobalPtr<Firebird::SignalSafeSemaphore> shutdownSemaphore;
void markHandlesShutdown(Array handles)
THREAD_ENTRY_DECLARE shutdownThread(THREAD_ENTRY_PARAM)
{ {
for (size_t n = 0; n < handles.getCount(); ++n) for(;;)
{ {
handles[n]->flags |= HANDLE_shutdown; killed = 0;
} try {
} shutdownSemaphore->enter();
}
void markShutdown(Attachment* attach) catch (Firebird::status_exception& e)
{
Firebird::MutexLockGuard guard(attach->mutex);
attach->flags |= HANDLE_shutdown;
markHandlesShutdown(attach->transactions);
markHandlesShutdown(attach->statements);
markHandlesShutdown(attach->requests);
markHandlesShutdown(attach->blobs);
}
// should be called with locked attachmentsMutex
void markShutdown(Jrd::Attachment** list)
{
while (Jrd::Attachment* ja = *list++)
{
for (size_t n = 0; n < attachments().getCount(); ++n)
{ {
if (attachments()[n]->handle == ja) TEXT buffer[1024];
const ISC_STATUS* vector = e.value();
if (! (vector && fb_interpret(buffer, sizeof(buffer), &vector)))
{ {
markShutdown(attachments()[n]); strcpy(buffer, "Unknown failure in shutdown thread in shutSem:enter()");
break;
} }
gds__log(buffer, 0);
exit(0);
}
if (! killed)
{
break;
}
// perform shutdown
ISC_STATUS_ARRAY status;
fb__shutdown(status);
if (status[0] == 1 && status[1] != 0)
{
char buffer[256];
const ISC_STATUS *vector = status;
if (!fb_interpret(buffer, sizeof(buffer), &vector))
{
strcpy(buffer, "Unknown failure in shutdown thread in fb__shutdown()");
}
gds__log(buffer, 0);
} }
} }
return 0;
} }
void handler(int sig)
{
if (killed)
{
return;
}
killed = sig;
#if !defined (SUPERCLIENT)
shutdown_flag = true;
#endif
shutdownSemaphore->release();
}
void handlerInt(void*)
{
handler(SIGINT);
}
void handlerTerm(void*)
{
handler(SIGTERM);
}
class CtrlCHandler
{
public:
CtrlCHandler(Firebird::MemoryPool&)
{
gds__thread_start(shutdownThread, 0, 0, 0, 0);
procInt = ISC_signal(SIGINT, handlerInt, 0);
procTerm = ISC_signal(SIGTERM, handlerTerm, 0);
}
~CtrlCHandler()
{
ISC_signal_cancel(SIGINT, handlerInt, 0);
ISC_signal_cancel(SIGTERM, handlerTerm, 0);
if (! killed)
{
// must be done to let shutdownThread close
shutdownSemaphore->release();
THREAD_YIELD();
}
}
};
#endif //UNIX
// YEntry: Tracks subsystem_enter/exit() calls.
// Accounts activity per different attachments.
class YEntry : public Status class YEntry : public Status
{ {
public: public:
YEntry(ISC_STATUS* v) throw() YEntry(ISC_STATUS* v) throw()
: Status(v), recursive(false) : Status(v), att(0)
{ {
subsystem_enter(); subsystem_enter();
#ifdef UNIX
if (handle || killed) { static Firebird::GlobalPtr<CtrlCHandler> ctrlCHandler;
recursive = true; #endif //UNIX
return;
}
handle = 0;
vector = (ISC_STATUS*)(*this);
inside = true;
if (!init)
{
init = true;
installCtrlCHandler();
}
} }
void setPrimaryHandle(BaseHandle* h) void setPrimaryHandle(BaseHandle* primary)
{ {
handle = h; if (primary && primary->parent && (!att))
{
att = primary->parent;
Firebird::MutexLockGuard guard(att->enterMutex);
att->enterCount++;
}
} }
~YEntry() ~YEntry()
{ {
if (att)
{
Firebird::MutexLockGuard guard(att->enterMutex);
att->enterCount--;
}
subsystem_exit(); subsystem_exit();
if (recursive)
{
return;
}
if (killed)
{
#if !defined (SUPERCLIENT)
JRD_shutdown_all(false);
#endif
propagateKill();
}
if (fatal())
{
if (handle)
{
Jrd::Attachment* attach = handle->getAttachmentHandle();
Firebird::HalfStaticArray<Jrd::Attachment*, 2> releasedBuffer;
Firebird::MutexLockGuard guard(attachmentsMutex);
Jrd::Attachment** released =
releasedBuffer.getBuffer(attachments().getCount() + 1);
*released = 0;
#if !defined (SUPERCLIENT)
JRD_shutdown_attachment(&attach, released);
#endif
markShutdown(released);
}
}
inside = false;
handle = 0;
} }
private: private:
YEntry(const YEntry&); // prohibit copy constructor YEntry(const YEntry&); // prohibit copy constructor
Attachment* att;
bool recursive; // loopback call from ExecState, Udf, etc.
static bool inside;
static BaseHandle* handle;
static ISC_STATUS* vector;
static bool init;
static int killed;
static bool proc2, proc15;
static void installCtrlCHandler() throw()
{
try
{
proc2 = ISC_signal(SIGINT, Handler2, 0);
proc15 = ISC_signal(SIGTERM, Handler15, 0);
}
catch (...)
{
gds__log("Failure setting ctrl-C handlers");
}
}
static void propagateKill()
{
ISC_signal_cancel(SIGINT, Handler2, 0);
ISC_signal_cancel(SIGTERM, Handler15, 0);
// if signal is not processed by someone else, exit now
if (!(killed == 2 ? proc2 : proc15))
{
exit(0);
}
// Someone else watches signals - let him shutdown gracefully
// Using recursive mutex in signal handler routine -
// relatively safe cause we need read-only access.
// With correctly implemented insert / remove methods in array
// and memcpy/memmove copying data with at least sizeof(void*)
// portions, this code is really safe.
Firebird::MutexLockGuard guard(attachmentsMutex);
for (size_t n = 0; n < attachments().getCount(); ++n)
{
markShutdown(attachments()[n]);
}
}
static void Handler2(void*)
{
if (killed)
{
return; // do nothing - already killed
}
killed = 2;
Handler();
}
static void Handler15(void*)
{
if (killed)
{
return; // do nothing - already killed
}
killed = 15;
Handler();
}
static void Handler()
{
#if !defined (SUPERCLIENT)
shutdown_flag = true;
#endif
if (inside)
{
if (handle)
{
handle->cancel();
}
}
else
{
// this function must in theory use only signal-safe code
// but as long as we have not entered engine,
// any call to it should be safe
#if !defined (SUPERCLIENT)
JRD_shutdown_all(false);
#endif
propagateKill();
}
}
bool fatal() const
{
return (vector[0] == isc_arg_gds && vector[1] == isc_shutdown);
}
}; };
bool YEntry::init = false;
bool YEntry::inside = false;
BaseHandle* YEntry::handle = 0;
ISC_STATUS* YEntry::vector = 0;
int YEntry::killed = 0;
bool YEntry::proc2 = false;
bool YEntry::proc15 = false;
#else
class YEntry : public Status
{
public:
YEntry(ISC_STATUS* v) : Status(v)
{
subsystem_enter();
}
void setPrimaryHandle(BaseHandle* h)
{
}
~YEntry()
{
subsystem_exit();
}
private:
YEntry(const YEntry&); //prohibit copy constructor
};
#endif
} // anonymous namespace } // anonymous namespace
@ -863,7 +765,9 @@ const int PROC_INTL_FUNCTION = 54; // internal call
const int PROC_DSQL_CACHE = 55; // internal call const int PROC_DSQL_CACHE = 55; // internal call
const int PROC_INTERNAL_COMPILE = 56; // internal call const int PROC_INTERNAL_COMPILE = 56; // internal call
const int PROC_count = 57; const int PROC_SHUTDOWN = 57;
const int PROC_count = 58;
/* Define complicated table for multi-subsystem world */ /* Define complicated table for multi-subsystem world */
@ -988,18 +892,6 @@ static const SCHAR sql_prepare_info2[] =
}; };
namespace YValve
{
void Attachment::cancel2()
{
#if !defined (SUPERCLIENT) && !defined(SERVER_SHUTDOWN)
ISC_STATUS_ARRAY local;
jrd8_cancel_operation(local, &handle, CANCEL_raise);
#endif
}
}
ISC_STATUS API_ROUTINE GDS_ATTACH_DATABASE(ISC_STATUS* user_status, ISC_STATUS API_ROUTINE GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
SSHORT file_length, SSHORT file_length,
const TEXT* file_name, const TEXT* file_name,
@ -1282,10 +1174,18 @@ ISC_STATUS API_ROUTINE GDS_CANCEL_OPERATION(ISC_STATUS * user_status,
try try
{ {
Attachment* attachment = translate<Attachment>(handle); Attachment* attachment = translate<Attachment>(handle);
status.setPrimaryHandle(attachment); // mutex will be locked here for a really long time
CALL(PROC_CANCEL_OPERATION, attachment->implementation) (status, Firebird::MutexLockGuard guard(attachment->enterMutex);
&attachment->handle, if (attachment->enterCount)
option); {
CALL(PROC_CANCEL_OPERATION, attachment->implementation) (status,
&attachment->handle,
option);
}
else
{
Firebird::status_exception::raise(isc_random, isc_arg_string, "Nothing to cancel", 0);
}
} }
catch (const Firebird::Exception& e) catch (const Firebird::Exception& e)
{ {
@ -2495,7 +2395,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_EXEC_IMMED2(ISC_STATUS* user_status,
dasup.dasup_clauses[DASUP_CLAUSE_select].dasup_blr, dasup.dasup_clauses[DASUP_CLAUSE_select].dasup_blr,
out_msg_type, out_msg_length, out_msg_type, out_msg_length,
dasup.dasup_clauses[DASUP_CLAUSE_select].dasup_msg); dasup.dasup_clauses[DASUP_CLAUSE_select].dasup_msg);
status.ok();
if (!s) if (!s)
{ {
s = UTLD_parse_sqlda(status, &dasup, NULL, NULL, NULL, dialect, s = UTLD_parse_sqlda(status, &dasup, NULL, NULL, NULL, dialect,
@ -2803,7 +2702,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_FETCH(ISC_STATUS* user_status,
dasup.dasup_clauses[DASUP_CLAUSE_select].dasup_msg); dasup.dasup_clauses[DASUP_CLAUSE_select].dasup_msg);
if (s && s != 101) if (s && s != 101)
{ {
status.ok();
return s; return s;
} }
@ -2812,7 +2710,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_FETCH(ISC_STATUS* user_status,
{ {
return status[1]; return status[1];
} }
status.ok();
} }
catch (const Firebird::Exception& e) catch (const Firebird::Exception& e)
{ {
@ -2870,7 +2767,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_FETCH2(ISC_STATUS* user_status,
direction, offset); direction, offset);
if (s && s != 101) if (s && s != 101)
{ {
status.ok();
return s; return s;
} }
@ -2879,7 +2775,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_FETCH2(ISC_STATUS* user_status,
{ {
return status[1]; return status[1];
} }
status.ok();
} }
catch (const Firebird::Exception& e) catch (const Firebird::Exception& e)
{ {
@ -2931,7 +2826,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_FETCH_M(ISC_STATUS* user_status,
if (s == 100 || s == 101) if (s == 100 || s == 101)
{ {
status.ok();
return s; return s;
} }
} }
@ -2984,7 +2878,6 @@ ISC_STATUS API_ROUTINE GDS_DSQL_FETCH2_M(ISC_STATUS* user_status,
if (s == 100 || s == 101) if (s == 100 || s == 101)
{ {
status.ok();
return s; return s;
} }
} }
@ -3625,7 +3518,6 @@ ISC_STATUS API_ROUTINE GDS_GET_SEGMENT(ISC_STATUS * user_status,
if (code == isc_segstr_eof || code == isc_segment) if (code == isc_segstr_eof || code == isc_segment)
{ {
status.ok();
return code; return code;
} }
} }
@ -3686,8 +3578,8 @@ ISC_STATUS API_ROUTINE GDS_GET_SLICE(ISC_STATUS* user_status,
} }
ISC_STATUS gds__handle_cleanup(ISC_STATUS * user_status, ISC_STATUS API_ROUTINE gds__handle_cleanup(ISC_STATUS * user_status,
FB_API_HANDLE * user_handle) FB_API_HANDLE * user_handle)
{ {
/************************************** /**************************************
* *
@ -4810,7 +4702,6 @@ ISC_STATUS API_ROUTINE_VARARG GDS_START_TRANSACTION(ISC_STATUS * user_status,
va_end(ptr); va_end(ptr);
GDS_START_MULTIPLE(user_status, tra_handle, count, teb); GDS_START_MULTIPLE(user_status, tra_handle, count, teb);
status.ok();
} }
catch (const Firebird::Exception& e) catch (const Firebird::Exception& e)
{ {
@ -5378,7 +5269,6 @@ static ISC_STATUS get_transaction_info(ISC_STATUS* user_status,
{ {
TEXT buffer[16]; TEXT buffer[16];
TEXT* p = *ptr; TEXT* p = *ptr;
status.ok();
if (CALL(PROC_TRANSACTION_INFO, transaction->implementation) (status, if (CALL(PROC_TRANSACTION_INFO, transaction->implementation) (status,
&transaction-> &transaction->
@ -5573,7 +5463,6 @@ static ISC_STATUS prepare(ISC_STATUS* user_status,
* *
**************************************/ **************************************/
Status status(user_status); Status status(user_status);
status.ok();
Transaction* sub; Transaction* sub;
TEXT tdr_buffer[1024]; TEXT tdr_buffer[1024];
@ -5918,3 +5807,75 @@ bool WHY_get_shutdown()
return shutdown_flag; return shutdown_flag;
} }
#endif // !SUPERCLIENT #endif // !SUPERCLIENT
ISC_STATUS API_ROUTINE fb__shutdown(ISC_STATUS * user_status)
{
/**************************************
*
* f b _ s h u t d o w n
*
**************************************
*
* Functional description
* Shutdown firebird.
*
**************************************/
YEntry status(user_status);
try
{
// Shutdown clients before providers
if (ShutChain::run(FB_SHUT_PREPROVIDERS) == 0)
{
// Shutdown providers
for (int n=0; n<SUBSYSTEMS; ++n)
{
PTR entry = get_entrypoint(PROC_SHUTDOWN, n);
if (entry != no_entrypoint)
{
if (entry(status) != 0)
break;
}
}
// Shutdown clients after providers
if (ShutChain::run(FB_SHUT_POSTPROVIDERS) == 0)
{
// All clients are ready to exit
exit(0);
}
}
}
catch (const Firebird::Exception& e)
{
e.stuff_exception(status);
}
return status[1];
}
ISC_STATUS API_ROUTINE fb__shutdown_callback(ISC_STATUS * user_status, FPTR_INT callBack, const int mask)
{
/**************************************
*
* f b _ s h u t d o w n _ c a l l b a c k
*
**************************************
*
* Functional description
* Register client callback to be called when FB is going down.
*
**************************************/
YEntry status(user_status);
try
{
ShutChain::add(callBack, mask);
}
catch (const Firebird::Exception& e)
{
e.stuff_exception(status);
}
return status[1];
}

View File

@ -255,6 +255,11 @@ SLONG API_ROUTINE isc_reset_fpe(USHORT);
#define CANCEL_enable 2 #define CANCEL_enable 2
#define CANCEL_raise 3 #define CANCEL_raise 3
ISC_STATUS API_ROUTINE gds__cancel_operation(ISC_STATUS*, FB_API_HANDLE*, USHORT); ISC_STATUS API_ROUTINE gds__cancel_operation(ISC_STATUS*, FB_API_HANDLE*, USHORT);
ISC_STATUS API_ROUTINE gds__handle_cleanup(ISC_STATUS*, FB_API_HANDLE*);
ISC_STATUS API_ROUTINE fb__shutdown(ISC_STATUS* user_status);
const int FB_SHUT_PREPROVIDERS = 1;
const int FB_SHUT_POSTPROVIDERS = 2;
ISC_STATUS API_ROUTINE fb__shutdown_callback(ISC_STATUS* user_status, FPTR_INT callBack, const int mask);
typedef void AttachmentCleanupRoutine(FB_API_HANDLE*, void*); typedef void AttachmentCleanupRoutine(FB_API_HANDLE*, void*);
typedef void TransactionCleanupRoutine(FB_API_HANDLE, void*); typedef void TransactionCleanupRoutine(FB_API_HANDLE, void*);
@ -264,8 +269,6 @@ ISC_STATUS API_ROUTINE isc_database_cleanup(ISC_STATUS*, FB_API_HANDLE*,
int API_ROUTINE gds__disable_subsystem(TEXT*); int API_ROUTINE gds__disable_subsystem(TEXT*);
int API_ROUTINE gds__enable_subsystem(TEXT*); int API_ROUTINE gds__enable_subsystem(TEXT*);
ISC_STATUS gds__handle_cleanup(ISC_STATUS*, FB_API_HANDLE*);
#define INTL_FUNCTION_CHAR_LENGTH 1 #define INTL_FUNCTION_CHAR_LENGTH 1
#define INTL_FUNCTION_CONV_TO_METADATA 2 #define INTL_FUNCTION_CONV_TO_METADATA 2
ISC_STATUS API_ROUTINE gds__intl_function(ISC_STATUS*, FB_API_HANDLE*, USHORT, UCHAR, USHORT, const UCHAR*, void*); ISC_STATUS API_ROUTINE gds__intl_function(ISC_STATUS*, FB_API_HANDLE*, USHORT, UCHAR, USHORT, const UCHAR*, void*);

View File

@ -130,11 +130,11 @@ namespace YValve
public: public:
static BaseHandle* translate(FB_API_HANDLE); static BaseHandle* translate(FB_API_HANDLE);
Jrd::Attachment* getAttachmentHandle(); Jrd::Attachment* getAttachmentHandle();
void cancel();
~BaseHandle(); ~BaseHandle();
// required to put pointers to it into the tree // required to put pointers to it into the tree
static const FB_API_HANDLE& generate(const void* sender, BaseHandle* value) { static const FB_API_HANDLE& generate(const void* sender, BaseHandle* value)
{
return value->public_handle; return value->public_handle;
} }
}; };
@ -193,6 +193,9 @@ namespace YValve
// of collision is so slow here, that I prefer to save resources, using single mutex. // of collision is so slow here, that I prefer to save resources, using single mutex.
Firebird::Mutex mutex; Firebird::Mutex mutex;
int enterCount;
Firebird::Mutex enterMutex;
Clean<AttachmentCleanupRoutine, FB_API_HANDLE*> cleanup; Clean<AttachmentCleanupRoutine, FB_API_HANDLE*> cleanup;
StoredAtt* handle; StoredAtt* handle;
Firebird::PathName db_path; Firebird::PathName db_path;
@ -211,7 +214,6 @@ namespace YValve
public: public:
Attachment(StoredAtt*, FB_API_HANDLE*, USHORT); Attachment(StoredAtt*, FB_API_HANDLE*, USHORT);
void cancel2();
~Attachment(); ~Attachment();
}; };

View File

@ -51,6 +51,7 @@
#include "../qli/meta_proto.h" #include "../qli/meta_proto.h"
#include "../qli/parse_proto.h" #include "../qli/parse_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/why_proto.h"
#include "../jrd/perf_proto.h" #include "../jrd/perf_proto.h"
#include "../include/fb_exception.h" #include "../include/fb_exception.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
@ -60,18 +61,13 @@ using MsgFormat::SafeArg;
const char* STARTUP_FILE = "HOME"; // Assume its Unix const char* STARTUP_FILE = "HOME"; // Assume its Unix
#ifndef SIGQUIT
#define SIGQUIT SIGINT
#define SIGPIPE SIGINT
#endif
extern TEXT *QLI_prompt; extern TEXT *QLI_prompt;
static void enable_signals(void); static void enable_signals(void);
static bool process_statement(bool); static bool process_statement(bool);
static void CLIB_ROUTINE signal_arith_excp(USHORT, USHORT, USHORT); static void CLIB_ROUTINE signal_arith_excp(USHORT, USHORT, USHORT);
static void CLIB_ROUTINE signal_quit(int); static int CLIB_ROUTINE async_quit();
static bool yes_no(USHORT, const TEXT*); static bool yes_no(USHORT, const TEXT*);
struct answer_t { struct answer_t {
@ -299,9 +295,13 @@ static void enable_signals(void)
**************************************/ **************************************/
typedef void (*new_handler) (int); typedef void (*new_handler) (int);
signal(SIGQUIT, signal_quit); #ifdef SIGQUIT
signal(SIGINT, signal_quit); signal(SIGQUIT, SIG_IGN);
signal(SIGPIPE, signal_quit); #endif
fb__shutdown_callback(0, async_quit, FB_SHUT_PREPROVIDERS);
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
signal(SIGFPE, (new_handler) signal_arith_excp); signal(SIGFPE, (new_handler) signal_arith_excp);
} }
@ -559,7 +559,7 @@ static void CLIB_ROUTINE signal_arith_excp(USHORT sig, USHORT code, USHORT scp)
} }
static void CLIB_ROUTINE signal_quit(int) static int CLIB_ROUTINE async_quit()
{ {
/************************************** /**************************************
* *
@ -571,12 +571,8 @@ static void CLIB_ROUTINE signal_quit(int)
* Stop whatever we happened to be doing. * Stop whatever we happened to be doing.
* *
**************************************/ **************************************/
//void (*prev_handler) ();
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
EXEC_abort(); EXEC_abort();
return 1;
} }

View File

@ -26,6 +26,8 @@
#include <setjmp.h> #include <setjmp.h>
#include "../jrd/ibase.h" #include "../jrd/ibase.h"
#include "../jrd/common.h"
#include "../jrd/why_proto.h"
#include "../qli/dtr.h" #include "../qli/dtr.h"
#include "../qli/exe.h" #include "../qli/exe.h"
#include "../qli/all_proto.h" #include "../qli/all_proto.h"
@ -102,13 +104,17 @@ void EXEC_abort(void)
**************************************/ **************************************/
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
for (qli_req* request = QLI_requests; request; request = request->req_next) for (DBB database = QLI_databases; database; database = database->dbb_next)
{ {
if (request->req_handle) if (database->dbb_handle)
isc_unwind_request(status_vector, &request->req_handle, 0); {
if (gds__cancel_operation(status_vector, &database->dbb_handle, CANCEL_raise) == 0)
{
QLI_abort = true;
}
}
} }
QLI_abort = true;
} }

View File

@ -301,8 +301,7 @@ static rem_port* inet_try_connect( PACKET*,
Firebird::PathName&, Firebird::PathName&,
const TEXT*, const TEXT*,
ISC_STATUS*, ISC_STATUS*,
const UCHAR*, Firebird::ClumpletReader &);
USHORT);
static bool_t inet_write(XDR *, int); static bool_t inet_write(XDR *, int);
#if !(defined WIN_NT) #if !(defined WIN_NT)
static int parse_hosts(const TEXT*, const TEXT*, const TEXT*); static int parse_hosts(const TEXT*, const TEXT*, const TEXT*);
@ -406,8 +405,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
const TEXT* node_name, const TEXT* node_name,
const TEXT* user_string, const TEXT* user_string,
bool uv_flag, bool uv_flag,
const UCHAR* dpb, Firebird::ClumpletReader &dpb)
USHORT dpb_length)
{ {
/************************************** /**************************************
* *
@ -489,7 +487,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
/* Try connection using first set of protocols. punt if error */ /* Try connection using first set of protocols. punt if error */
rem_port* port = inet_try_connect(packet, rdb, file_name, rem_port* port = inet_try_connect(packet, rdb, file_name,
node_name, status_vector, dpb, dpb_length); node_name, status_vector, dpb);
if (!port) { if (!port) {
return NULL; return NULL;
} }
@ -516,7 +514,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
cnct->p_cnct_count); cnct->p_cnct_count);
port = inet_try_connect(packet, rdb, file_name, port = inet_try_connect(packet, rdb, file_name,
node_name, status_vector, dpb, dpb_length); node_name, status_vector, dpb);
if (!port) { if (!port) {
return NULL; return NULL;
} }
@ -544,7 +542,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
cnct->p_cnct_count); cnct->p_cnct_count);
port = inet_try_connect(packet, rdb, file_name, port = inet_try_connect(packet, rdb, file_name,
node_name, status_vector, dpb, dpb_length); node_name, status_vector, dpb);
if (!port) { if (!port) {
return NULL; return NULL;
} }
@ -591,7 +589,7 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
rem_port* INET_connect(const TEXT* name, rem_port* INET_connect(const TEXT* name,
PACKET* packet, PACKET* packet,
ISC_STATUS* status_vector, ISC_STATUS* status_vector,
USHORT flag, const UCHAR* dpb, USHORT dpb_length) USHORT flag, Firebird::ClumpletReader* dpb)
{ {
/************************************** /**************************************
* *
@ -622,7 +620,7 @@ rem_port* INET_connect(const TEXT* name,
rem_port* port = alloc_port(0); rem_port* port = alloc_port(0);
port->port_status_vector = status_vector; port->port_status_vector = status_vector;
REMOTE_get_timeout_params(port, dpb, dpb_length); REMOTE_get_timeout_params(port, dpb);
status_vector[0] = isc_arg_gds; status_vector[0] = isc_arg_gds;
status_vector[1] = 0; status_vector[1] = 0;
status_vector[2] = isc_arg_end; status_vector[2] = isc_arg_end;
@ -1258,7 +1256,7 @@ static rem_port* alloc_port( rem_port* parent)
rem_port* port = (rem_port*) ALLR_block(type_port, INET_remote_buffer * 2); rem_port* port = (rem_port*) ALLR_block(type_port, INET_remote_buffer * 2);
port->port_type = port_inet; port->port_type = port_inet;
port->port_state = state_pending; port->port_state = state_pending;
REMOTE_get_timeout_params(port, 0, 0); REMOTE_get_timeout_params(port, 0);
gethostname(buffer, sizeof(buffer)); gethostname(buffer, sizeof(buffer));
port->port_host = REMOTE_make_string(buffer); port->port_host = REMOTE_make_string(buffer);
@ -3095,8 +3093,7 @@ static rem_port* inet_try_connect(
Firebird::PathName& file_name, Firebird::PathName& file_name,
const TEXT* node_name, const TEXT* node_name,
ISC_STATUS* status_vector, ISC_STATUS* status_vector,
const UCHAR* dpb, Firebird::ClumpletReader& dpb)
USHORT dpb_length)
{ {
/************************************** /**************************************
* *
@ -3124,9 +3121,7 @@ static rem_port* inet_try_connect(
/* If we can't talk to a server, punt. Let somebody else generate /* If we can't talk to a server, punt. Let somebody else generate
an error. status_vector will have the network error info. */ an error. status_vector will have the network error info. */
rem_port* port = rem_port* port = INET_connect(node_name, packet, status_vector, FALSE, &dpb);
INET_connect(node_name, packet, status_vector, FALSE, dpb,
dpb_length);
if (!port) { if (!port) {
ALLR_free(rdb); ALLR_free(rdb);
return NULL; return NULL;

View File

@ -26,10 +26,15 @@
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
namespace Firebird
{
class ClumpletReader;
};
rem_port* INET_analyze(Firebird::PathName&, ISC_STATUS*, const TEXT*, const TEXT*, rem_port* INET_analyze(Firebird::PathName&, ISC_STATUS*, const TEXT*, const TEXT*,
bool, const UCHAR*, USHORT); bool, Firebird::ClumpletReader&);
rem_port* INET_connect(const TEXT*, struct packet*, ISC_STATUS*, USHORT, rem_port* INET_connect(const TEXT*, struct packet*, ISC_STATUS*, USHORT,
const UCHAR*, USHORT); Firebird::ClumpletReader*);
rem_port* INET_reconnect(HANDLE, ISC_STATUS*); rem_port* INET_reconnect(HANDLE, ISC_STATUS*);
rem_port* INET_server(int); rem_port* INET_server(int);
void INET_set_clients(int); void INET_set_clients(int);

View File

@ -37,10 +37,12 @@
#include "../jrd/common.h" #include "../jrd/common.h"
#include "../jrd/isc_proto.h" #include "../jrd/isc_proto.h"
#include "../jrd/divorce.h" #include "../jrd/divorce.h"
#include "../jrd/jrd_proto.h" #include "../jrd/ibase.h"
#include "../jrd/why_proto.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../common/config/config.h" #include "../common/config/config.h"
#include <sys/param.h> #include <sys/param.h>
//#include "../jrd/os/isc_i_proto.h"
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
@ -69,15 +71,12 @@
#include <string.h> #include <string.h>
#endif #endif
#ifdef SUPERSERVER
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <errno.h> #include <errno.h>
#include "../jrd/ibase.h" #include "../jrd/ibase.h"
#include "../jrd/jrd_pwd.h" #include "../jrd/jrd_pwd.h"
#endif
#include "../remote/remote.h" #include "../remote/remote.h"
#include "../jrd/license.h" #include "../jrd/license.h"
@ -103,11 +102,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#if (defined SUPERSERVER && defined UNIX && defined SERVER_SHUTDOWN)
#include "../common/classes/semaphore.h" #include "../common/classes/semaphore.h"
#define SHUTDOWN_THREAD
#include "../jrd/ThreadStart.h"
#endif
#ifdef UNIX #ifdef UNIX
const char* TEMP_DIR = "/tmp"; const char* TEMP_DIR = "/tmp";
@ -124,17 +119,9 @@ const char* FIREBIRD_USER_NAME = "firebird";
static void set_signal(int, void (*)(int)); static void set_signal(int, void (*)(int));
static void signal_handler(int); static void signal_handler(int);
#if (defined SUPERSERVER && defined UNIX ) static int shutdownInetServer();
//static void signal_sigpipe_handler(int); static void shutdownInit();
#endif
#ifdef SHUTDOWN_THREAD
static THREAD_ENTRY_DECLARE shutdown_thread(THREAD_ENTRY_PARAM arg);
static void signal_term(int);
static void shutdown_init();
static void shutdown_fini();
static void tryStopMainThread(); static void tryStopMainThread();
#endif
static TEXT protocol[128]; static TEXT protocol[128];
static int INET_SERVER_start = 0; static int INET_SERVER_start = 0;
@ -272,8 +259,7 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
// activate paths set with -e family of switches // activate paths set with -e family of switches
ISC_set_prefix(0, 0); ISC_set_prefix(0, 0);
#if (defined SUPERSERVER && defined UNIX ) #ifdef UNIX
/* set_signal(SIGPIPE, signal_sigpipe_handler); */
set_signal(SIGPIPE, signal_handler); set_signal(SIGPIPE, signal_handler);
set_signal(SIGUSR1, signal_handler); set_signal(SIGUSR1, signal_handler);
set_signal(SIGUSR2, signal_handler); set_signal(SIGUSR2, signal_handler);
@ -314,7 +300,9 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
#ifndef SUPERSERVER #ifndef SUPERSERVER
if (multi_client && !debug) { if (multi_client && !debug) {
#ifdef UNIX
set_signal(SIGUSR1, signal_handler); set_signal(SIGUSR1, signal_handler);
#endif
int child; int child;
for (int n = 0; n < 100; n++) { for (int n = 0; n < 100; n++) {
INET_SERVER_start = 0; INET_SERVER_start = 0;
@ -327,7 +315,9 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
} }
gds__log("INET_SERVER/main: gds_inet_server restarted"); gds__log("INET_SERVER/main: gds_inet_server restarted");
} }
#ifdef UNIX
set_signal(SIGUSR1, SIG_DFL); set_signal(SIGUSR1, SIG_DFL);
#endif
} }
#endif #endif
@ -370,8 +360,7 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
{ // scope block { // scope block
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
THREAD_ENTER(); THREAD_ENTER();
port = INET_connect(protocol, 0, status_vector, INET_SERVER_flag, port = INET_connect(protocol, 0, status_vector, INET_SERVER_flag, 0);
0, 0);
THREAD_EXIT(); THREAD_EXIT();
if (!port) { if (!port) {
gds__print_status(status_vector); gds__print_status(status_vector);
@ -390,7 +379,6 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
} }
#ifdef SUPERSERVER #ifdef SUPERSERVER
/* before starting the superserver stuff change directory to tmp */ /* before starting the superserver stuff change directory to tmp */
if (CHANGE_DIR(TEMP_DIR)) { if (CHANGE_DIR(TEMP_DIR)) {
/* error on changing the directory */ /* error on changing the directory */
@ -424,10 +412,7 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
} }
} }
#endif shutdownInit();
#ifdef SHUTDOWN_THREAD
shutdown_init();
#endif #endif
if (multi_threaded) if (multi_threaded)
@ -435,10 +420,6 @@ int CLIB_ROUTINE server_main( int argc, char** argv)
else else
SRVR_main(port, INET_SERVER_flag); SRVR_main(port, INET_SERVER_flag);
#ifdef SHUTDOWN_THREAD
shutdown_fini();
#endif
#ifdef DEBUG_GDS_ALLOC #ifdef DEBUG_GDS_ALLOC
/* In Debug mode - this will report all server-side memory leaks /* In Debug mode - this will report all server-side memory leaks
* due to remote access * due to remote access
@ -472,12 +453,14 @@ static void set_signal( int signal_number, void (*handler) (int))
* Establish signal handler. * Establish signal handler.
* *
**************************************/ **************************************/
#ifdef UNIX
struct sigaction vec, old_vec; struct sigaction vec, old_vec;
vec.sa_handler = handler; vec.sa_handler = handler;
sigemptyset(&vec.sa_mask); sigemptyset(&vec.sa_mask);
vec.sa_flags = 0; vec.sa_flags = 0;
sigaction(signal_number, &vec, &old_vec); sigaction(signal_number, &vec, &old_vec);
#endif
} }
@ -497,38 +480,16 @@ static void signal_handler(int)
++INET_SERVER_start; ++INET_SERVER_start;
} }
#ifdef NOT_USED_OR_REPLACED
#if (defined SUPERSERVER && defined UNIX )
static void signal_sigpipe_handler(int)
{
/****************************************************
*
* s i g n a l _ s i g p i p e _ h a n d l e r
*
****************************************************
*
* Functional description
* Dummy signal handler.
*
**************************************/
++INET_SERVER_start;
gds__log
("Super Server/main: Bad client socket, send() resulted in SIGPIPE, caught by server\n client exited improperly or crashed ????");
}
#endif //SUPERSERVER && UNIX
#endif
#ifdef SHUTDOWN_THREAD
static Firebird::GlobalPtr<Firebird::SignalSafeSemaphore> shutSem;
static Firebird::GlobalPtr<Firebird::Semaphore> mainThreadStopSem; static Firebird::GlobalPtr<Firebird::Semaphore> mainThreadStopSem;
static bool alreadyClosing = false; static bool serverClosing = false;
static THREAD_ENTRY_DECLARE shutdown_thread(THREAD_ENTRY_PARAM arg)
static int shutdownInetServer()
{ {
/**************************************************** /****************************************************
* *
* s h u t d o w n _ t h r e a d * s h u t d o w n I n e t S e r v e r
* *
**************************************************** ****************************************************
* *
@ -537,85 +498,38 @@ static THREAD_ENTRY_DECLARE shutdown_thread(THREAD_ENTRY_PARAM arg)
* which received SIGTERM, run in separate thread. * which received SIGTERM, run in separate thread.
* *
**************************************/ **************************************/
try {
shutSem->enter(); serverClosing = true;
}
catch (Firebird::status_exception& e) // shutdown worker threads
{ SRVR_shutdown();
TEXT buffer[1024];
const ISC_STATUS* vector = e.value(); // shutdown main thread - send self-signal to close select()
if (! (vector && fb_interpret(buffer, sizeof(buffer), &vector))) // in main thread and wait for it to get into safe state
{ #ifdef UNIX
strcpy(buffer, "Unknown failure in shutdown thread in shutSem:enter()"); kill(getpid(), SIGUSR1);
} #else
gds__log(buffer, 0); need a way to interrupt select in main listener thread in windows
exit(0); #endif
}
if (! alreadyClosing) mainThreadStopSem->enter();
{
alreadyClosing = true; // Ready to die
// shutdown databases return 0;
JRD_shutdown_all(false);
// shutdown worker threads
SRVR_shutdown();
// shutdown main thread - send self-signal to close select()
// in main thread and wait for it to get into safe state
kill(getpid(), SIGTERM);
mainThreadStopSem->enter();
// ready
exit(0);
}
return 0; //make compilers happy
} }
static void signal_term(int) static void shutdownInit()
{ {
/****************************************************
*
* s i g n a l _ t e r m
*
****************************************************
*
* Functional description
* Handle ^C and kill.
*
**************************************/
if (alreadyClosing)
{
return;
}
try
{
shutSem->release();
}
catch (Firebird::status_exception& e)
{
TEXT buffer[1024];
const ISC_STATUS* vector = e.value();
if (! (vector && fb_interpret(buffer, sizeof(buffer), &vector)))
{
strcpy(buffer, "Unknown failure in semaphore::release()");
}
gds__log(buffer, 0);
exit(0);
}
}
static void shutdown_init()
{
gds__thread_start(shutdown_thread, 0, THREAD_medium, 0, 0);
// process signals 2 & 15 in order to exit gracefully
set_signal(SIGINT, signal_term);
set_signal(SIGTERM, signal_term);
setStopMainThread(tryStopMainThread); setStopMainThread(tryStopMainThread);
}
static void shutdown_fini() ISC_STATUS_ARRAY status;
{ fb__shutdown_callback(status, shutdownInetServer, FB_SHUT_POSTPROVIDERS);
set_signal(SIGINT, SIG_IGN); if (status[0] == 1 && status[1] > 0)
set_signal(SIGTERM, SIG_IGN); {
alreadyClosing = true; gds__log_status("shutdownInit", status);
shutSem->release(); isc_print_status(status);
exit(STARTUP_ERROR);
}
} }
static void tryStopMainThread() static void tryStopMainThread()
@ -631,7 +545,7 @@ static void tryStopMainThread()
* In that case release semaphore and wait indefinitely. * In that case release semaphore and wait indefinitely.
* *
**************************************/ **************************************/
if (alreadyClosing) if (serverClosing)
{ {
mainThreadStopSem->release(); mainThreadStopSem->release();
for (;;) for (;;)
@ -640,4 +554,3 @@ static void tryStopMainThread()
} }
} }
} }
#endif //SHUTDOWN_THREAD

View File

@ -86,9 +86,6 @@
#ifdef WIN_NT #ifdef WIN_NT
#define sleep(seconds) Sleep ((seconds) * 1000) #define sleep(seconds) Sleep ((seconds) * 1000)
#include <direct.h> // getcwd
#endif // WIN_NT #endif // WIN_NT
const char* ISC_USER = "ISC_USER"; const char* ISC_USER = "ISC_USER";
@ -130,9 +127,9 @@ static RVNT add_event(rem_port*);
static void add_other_params(rem_port*, Firebird::ClumpletWriter&, const ParametersSet&); static void add_other_params(rem_port*, Firebird::ClumpletWriter&, const ParametersSet&);
static void add_working_directory(Firebird::ClumpletWriter&, const Firebird::PathName&); static void add_working_directory(Firebird::ClumpletWriter&, const Firebird::PathName&);
static rem_port* analyze(Firebird::PathName&, ISC_STATUS*, const TEXT*, static rem_port* analyze(Firebird::PathName&, ISC_STATUS*, const TEXT*,
bool, const UCHAR*, USHORT, Firebird::PathName&); bool, Firebird::ClumpletReader&, Firebird::PathName&);
static rem_port* analyze_service(Firebird::PathName&, ISC_STATUS*, const TEXT*, static rem_port* analyze_service(Firebird::PathName&, ISC_STATUS*, const TEXT*,
bool, const UCHAR*, USHORT); bool, Firebird::ClumpletReader&);
static bool batch_gds_receive(rem_port*, struct rmtque *, static bool batch_gds_receive(rem_port*, struct rmtque *,
ISC_STATUS *, USHORT); ISC_STATUS *, USHORT);
static bool batch_dsql_fetch(rem_port*, struct rmtque *, static bool batch_dsql_fetch(rem_port*, struct rmtque *,
@ -326,8 +323,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
Firebird::PathName expanded_name(expanded_filename); Firebird::PathName expanded_name(expanded_filename);
Firebird::PathName node_name; Firebird::PathName node_name;
rem_port* port = analyze(expanded_name, user_status, us, user_verification, rem_port* port = analyze(expanded_name, user_status, us, user_verification,
newDpb.getBuffer(), newDpb, node_name);
newDpb.getBufferLength(), node_name);
if (!port) if (!port)
{ {
return user_status[1]; return user_status[1];
@ -852,8 +848,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
Firebird::PathName expanded_name(expanded_filename); Firebird::PathName expanded_name(expanded_filename);
Firebird::PathName node_name; Firebird::PathName node_name;
const UCHAR* dpb2 = reinterpret_cast<const UCHAR*>(dpb); const UCHAR* dpb2 = reinterpret_cast<const UCHAR*>(dpb);
rem_port* port = analyze(expanded_name, user_status, us, rem_port* port = analyze(expanded_name, user_status, us, user_verification, newDpb, node_name);
user_verification, dpb2, dpb_length, node_name);
if (!port) { if (!port) {
return user_status[1]; return user_status[1];
} }
@ -3835,9 +3830,8 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
const bool user_verification = get_new_dpb(newSpb, user_string, spbParam); const bool user_verification = get_new_dpb(newSpb, user_string, spbParam);
const TEXT* us = (user_string.hasData()) ? user_string.c_str() : 0; const TEXT* us = (user_string.hasData()) ? user_string.c_str() : 0;
const UCHAR* spb2 = reinterpret_cast<const UCHAR*>(spb);
rem_port* port = analyze_service(expanded_name, user_status, us, rem_port* port = analyze_service(expanded_name, user_status, us,
user_verification, spb2, spb_length); user_verification, newSpb);
if (!port) { if (!port) {
return user_status[1]; return user_status[1];
} }
@ -4536,7 +4530,7 @@ static void add_working_directory(Firebird::ClumpletWriter& dpb,
// for WNet local node_name should be compared with "\\\\." ? // for WNet local node_name should be compared with "\\\\." ?
if (node_name == "localhost") if (node_name == "localhost")
{ {
fb_getcwd(cwd); fb_utils::getCwd(cwd);
} }
dpb.insertPath(isc_dpb_working_directory, cwd); dpb.insertPath(isc_dpb_working_directory, cwd);
} }
@ -4546,8 +4540,7 @@ static rem_port* analyze(Firebird::PathName& file_name,
ISC_STATUS* status_vector, ISC_STATUS* status_vector,
const TEXT* user_string, const TEXT* user_string,
bool uv_flag, bool uv_flag,
const UCHAR* dpb, Firebird::ClumpletReader& dpb,
USHORT dpb_length,
Firebird::PathName& node_name) Firebird::PathName& node_name)
{ {
/************************************** /**************************************
@ -4588,16 +4581,14 @@ static rem_port* analyze(Firebird::PathName& file_name,
if (ISC_analyze_tcp(file_name, node_name)) if (ISC_analyze_tcp(file_name, node_name))
{ {
port = INET_analyze(file_name, status_vector, port = INET_analyze(file_name, status_vector,
node_name.c_str(), user_string, uv_flag, dpb, node_name.c_str(), user_string, uv_flag, dpb);
dpb_length);
if (!port) if (!port)
{ {
/* retry in case multiclient inet server not forked yet */ /* retry in case multiclient inet server not forked yet */
sleep(2); sleep(2);
port = INET_analyze(file_name, status_vector, port = INET_analyze(file_name, status_vector,
node_name.c_str(), user_string, uv_flag, dpb, node_name.c_str(), user_string, uv_flag, dpb);
dpb_length);
} }
} }
else else
@ -4608,8 +4599,7 @@ static rem_port* analyze(Firebird::PathName& file_name,
if (ISC_analyze_nfs(file_name, node_name)) if (ISC_analyze_nfs(file_name, node_name))
{ {
port = INET_analyze(file_name, status_vector, port = INET_analyze(file_name, status_vector,
node_name.c_str(), user_string, uv_flag, dpb, node_name.c_str(), user_string, uv_flag, dpb);
dpb_length);
if (!port) if (!port)
{ {
/* retry in case multiclient inet server not forked yet */ /* retry in case multiclient inet server not forked yet */
@ -4618,8 +4608,7 @@ static rem_port* analyze(Firebird::PathName& file_name,
port = port =
INET_analyze(file_name, INET_analyze(file_name,
status_vector, node_name.c_str(), status_vector, node_name.c_str(),
user_string, uv_flag, dpb, user_string, uv_flag, dpb);
dpb_length);
} }
} }
} }
@ -4668,8 +4657,7 @@ static rem_port* analyze(Firebird::PathName& file_name,
node_name.c_str(), node_name.c_str(),
user_string, user_string,
uv_flag, uv_flag,
dpb, dpb);
dpb_length);
} }
} }
@ -4690,8 +4678,7 @@ static rem_port* analyze_service(Firebird::PathName& service_name,
ISC_STATUS* status_vector, ISC_STATUS* status_vector,
const TEXT* user_string, const TEXT* user_string,
bool uv_flag, bool uv_flag,
const UCHAR* dpb, Firebird::ClumpletReader& spb)
USHORT dpb_length)
{ {
/************************************** /**************************************
* *
@ -4723,8 +4710,7 @@ static rem_port* analyze_service(Firebird::PathName& service_name,
if (!port) { if (!port) {
if (ISC_analyze_tcp(service_name, node_name)) { if (ISC_analyze_tcp(service_name, node_name)) {
port = INET_analyze(service_name, status_vector, port = INET_analyze(service_name, status_vector,
node_name.c_str(), user_string, uv_flag, dpb, node_name.c_str(), user_string, uv_flag, spb);
dpb_length);
} }
} }
@ -4751,8 +4737,7 @@ static rem_port* analyze_service(Firebird::PathName& service_name,
node_name.c_str(), node_name.c_str(),
user_string, user_string,
uv_flag, uv_flag,
dpb, spb);
dpb_length);
} }
} }
#endif /* UNIX */ #endif /* UNIX */

View File

@ -337,7 +337,7 @@ static THREAD_ENTRY_DECLARE cleanup_thread(THREAD_ENTRY_PARAM)
if (new_ptr != return_buffer) if (new_ptr != return_buffer)
gds__free(new_ptr); gds__free(new_ptr);
JRD_shutdown_all(false); fb__shutdown(0);
SRVR_shutdown(); SRVR_shutdown();
return 0; return 0;
} }

View File

@ -343,7 +343,7 @@ static THREAD_ENTRY_DECLARE inet_connect_wait_thread(THREAD_ENTRY_PARAM)
{ {
THREAD_ENTER(); THREAD_ENTER();
rem_port* port = rem_port* port =
INET_connect(protocol_inet, NULL, status_vector, server_flag, 0, 0); INET_connect(protocol_inet, NULL, status_vector, server_flag, 0);
THREAD_EXIT(); THREAD_EXIT();
if (!port) { if (!port) {
gds__log_status(0, status_vector); gds__log_status(0, status_vector);

View File

@ -25,10 +25,14 @@
#define REMOTE_REMOT_PROTO_H #define REMOTE_REMOT_PROTO_H
struct blk; 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*); ULONG REMOTE_compute_batch_size (rem_port*, USHORT, P_OP, const rem_fmt*);
void REMOTE_get_timeout_params (rem_port*, const UCHAR*, USHORT); 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); void REMOTE_free_packet (rem_port*, struct packet *, bool = false);
struct rem_str* REMOTE_make_string (const SCHAR*); struct rem_str* REMOTE_make_string (const SCHAR*);

View File

@ -48,7 +48,6 @@ static TEXT* attach_failures = NULL;
static TEXT* attach_failures_ptr; static TEXT* attach_failures_ptr;
static void cleanup_memory(void*); static void cleanup_memory(void*);
static SLONG get_parameter(const UCHAR**);
void REMOTE_cleanup_transaction( RTR transaction) void REMOTE_cleanup_transaction( RTR transaction)
@ -322,9 +321,7 @@ void REMOTE_free_packet( rem_port* port, PACKET * packet, bool partial)
} }
void REMOTE_get_timeout_params( void REMOTE_get_timeout_params(rem_port* port, Firebird::ClumpletReader* pb)
rem_port* port,
const UCHAR* dpb, USHORT dpb_length)
{ {
/************************************** /**************************************
* *
@ -341,99 +338,19 @@ void REMOTE_get_timeout_params(
* *
**************************************/ **************************************/
bool got_dpb_connect_timeout = false; bool got_dpb_connect_timeout = false;
bool got_dpb_dummy_packet_interval = false;
fb_assert(isc_dpb_connect_timeout == isc_spb_connect_timeout); fb_assert(isc_dpb_connect_timeout == isc_spb_connect_timeout);
fb_assert(isc_dpb_dummy_packet_interval == isc_spb_dummy_packet_interval);
port->port_flags &= ~PORT_dummy_pckt_set; port->port_connect_timeout = pb && pb->find(isc_dpb_connect_timeout) ?
pb->getInt() : Config::getConnectionTimeout();
if (dpb && dpb_length) {
const UCHAR* p = dpb;
const UCHAR* const end = p + dpb_length;
if (*p++ == isc_dpb_version1) {
while (p < end)
switch (*p++) {
case isc_dpb_connect_timeout:
port->port_connect_timeout = get_parameter(&p);
got_dpb_connect_timeout = true;
break;
// 22 Aug 2003. Do not receive this parameter from the client as dummy packets
// either kill idle client process or cause unexpected disconnections.
// This applies to all IB/FB versions.
// case isc_dpb_dummy_packet_interval:
// port->port_dummy_packet_interval = get_parameter(&p);
// got_dpb_dummy_packet_interval = true;
// port->port_flags |= PORT_dummy_pckt_set;
// break;
case isc_dpb_sys_user_name:
/** Store the user name in thread specific storage.
We need this later while expanding filename to
get the users home directory.
Normally the working directory is stored in
the attachment but in this case the attachment is
not yet created.
Also note that the thread performing this task
has already called THREAD_ENTER
**/
{
char* t_data;
int i = 0;
int l = *(p++);
if (l) {
t_data = (char *) malloc(l + 1);
do {
t_data[i] = *p;
if (t_data[i] == '.')
t_data[i] = 0;
i++;
p++;
} while (--l);
}
else
t_data = (char *) malloc(1);
t_data[i] = 0;
ThreadData::putSpecificData((void *) t_data);
}
break;
default:
{
// Skip over this parameter - not important to us
const USHORT len = *p++;
p += len;
break;
}
}
}
}
if (!got_dpb_connect_timeout || !got_dpb_dummy_packet_interval) {
/* Didn't find all parameters in the dpb, fetch configuration
information from the configuration file and set the missing
values */
if (!got_dpb_connect_timeout)
port->port_connect_timeout = Config::getConnectionTimeout();
if (!got_dpb_dummy_packet_interval) {
port->port_flags |= PORT_dummy_pckt_set;
port->port_dummy_packet_interval = Config::getDummyPacketInterval();
}
}
/* Insure a meaningful keepalive interval has been set. Otherwise, too
many keepalive packets will drain network performance. */
port->port_flags |= PORT_dummy_pckt_set;
port->port_dummy_packet_interval = Config::getDummyPacketInterval();
if (port->port_dummy_packet_interval < 0) if (port->port_dummy_packet_interval < 0)
port->port_dummy_packet_interval = DUMMY_INTERVAL; port->port_dummy_packet_interval = DUMMY_INTERVAL;
port->port_dummy_timeout = port->port_dummy_packet_interval; port->port_dummy_timeout = port->port_dummy_packet_interval;
#ifdef DEBUG #ifdef DEBUG
printf("REMOTE_get_timeout dummy = %lu conn = %lu\n", printf("REMOTE_get_timeout dummy = %lu conn = %lu\n",
port->port_dummy_packet_interval, port->port_connect_timeout); port->port_dummy_packet_interval, port->port_connect_timeout);
@ -776,29 +693,6 @@ static void cleanup_memory( void *block)
} }
static SLONG get_parameter(const UCHAR** ptr)
{
/**************************************
*
* g e t _ p a r a m e t e r
*
**************************************
*
* Functional description
* Pick up a VAX format parameter from a parameter block, including the
* length byte.
* This is a clone of jrd/jrd.c:get_parameter()
*
**************************************/
const SSHORT l = *(*ptr)++;
const SLONG parameter = gds__vax_integer(*ptr, l);
*ptr += l;
return parameter;
}
// TMN: Beginning of C++ port - ugly but a start // TMN: Beginning of C++ port - ugly but a start
int rem_port::accept(p_cnct* cnct) int rem_port::accept(p_cnct* cnct)

View File

@ -848,7 +848,6 @@ static void addClumplets(Firebird::ClumpletWriter& dpb_buffer,
* *
* Functional description * Functional description
* Insert remote endpoint data into DPB address stack * Insert remote endpoint data into DPB address stack
* If configured, insert remote_attachment into dpb
* *
**************************************/ **************************************/
Firebird::ClumpletWriter address_stack_buffer(Firebird::ClumpletReader::UnTagged, MAX_UCHAR - 2); Firebird::ClumpletWriter address_stack_buffer(Firebird::ClumpletReader::UnTagged, MAX_UCHAR - 2);
@ -1028,12 +1027,12 @@ static void attach_database2(rem_port* port,
dpb_buffer.deleteWithTag(isc_dpb_gsec_attach); dpb_buffer.deleteWithTag(isc_dpb_gsec_attach);
dpb_buffer.deleteWithTag(isc_dpb_sec_attach); dpb_buffer.deleteWithTag(isc_dpb_sec_attach);
dpb = dpb_buffer.getBuffer();
dl = dpb_buffer.getBufferLength();
/* See if user has specified parameters relevant to the connection, /* See if user has specified parameters relevant to the connection,
they will be stuffed in the DPB if so. */ they will be stuffed in the DPB if so. */
REMOTE_get_timeout_params(port, dpb, dl); REMOTE_get_timeout_params(port, &dpb_buffer);
dpb = dpb_buffer.getBuffer();
dl = dpb_buffer.getBufferLength();
THREAD_EXIT(); THREAD_EXIT();
if (operation == op_attach) if (operation == op_attach)
@ -4948,7 +4947,7 @@ ISC_STATUS rem_port::service_attach(const char* service_name,
/* See if user has specified parameters relevent to the connection, /* See if user has specified parameters relevent to the connection,
they will be stuffed in the SPB if so. */ they will be stuffed in the SPB if so. */
REMOTE_get_timeout_params(this, spb.getBuffer(), spb.getBufferLength()); REMOTE_get_timeout_params(this, &spb);
THREAD_EXIT(); THREAD_EXIT();
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;