mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43: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:
parent
554f01ab4f
commit
00c63c1f8d
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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++
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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 += '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
181
src/jrd/jrd.cpp
181
src/jrd/jrd.cpp
@ -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,
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
static const UCHAR PWD_REQUEST[256];
|
static const UCHAR PWD_REQUEST[256];
|
||||||
static const UCHAR TPB[4];
|
static const UCHAR TPB[4];
|
||||||
|
|
||||||
Firebird::Mutex mutex;
|
Firebird::Mutex mutex;
|
||||||
|
|
||||||
ISC_STATUS_ARRAY status;
|
ISC_STATUS_ARRAY status;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
551
src/jrd/why.cpp
551
src/jrd/why.cpp
@ -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];
|
||||||
|
}
|
||||||
|
@ -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*);
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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*);
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user