From deb5c2317b40a9f47b037cc7eaecb057afdacbb4 Mon Sep 17 00:00:00 2001 From: alexpeshkoff Date: Mon, 29 Mar 2010 15:24:03 +0000 Subject: [PATCH] Fixed CORE-2948: Segfault when server is exiting --- src/remote/inet_server.cpp | 6 +- src/remote/inter_proto.h | 10 ++ src/remote/interface.cpp | 201 ++++++++++++++++++++++++++++++------- 3 files changed, 179 insertions(+), 38 deletions(-) diff --git a/src/remote/inet_server.cpp b/src/remote/inet_server.cpp index bc063b82f2..7f2bbc9b6c 100644 --- a/src/remote/inet_server.cpp +++ b/src/remote/inet_server.cpp @@ -468,9 +468,9 @@ int FB_EXPORTED server_main( int argc, char** argv) } #endif - // let shutdown thread continue operation if needed - // and get ready for normal at-exit shutdown from us - THD_yield(); + // perform atexit shutdown here when all globals in embedded library are active + // also sync with possibly already running shutdown in dedicated thread + fb_shutdown(10000, fb_shutrsn_exit_called); return FINI_OK; } diff --git a/src/remote/inter_proto.h b/src/remote/inter_proto.h index 52574ebe6c..16838161c4 100644 --- a/src/remote/inter_proto.h +++ b/src/remote/inter_proto.h @@ -136,6 +136,16 @@ ISC_STATUS REM_transaction_info(ISC_STATUS* user_status, struct Rtr** tra_handle SSHORT item_length, const UCHAR* items, SSHORT buffer_length, UCHAR* buffer); ISC_STATUS REM_unwind_request(ISC_STATUS* user_status, struct Rrq** req_handle, USHORT level); +// loopback provider +ISC_STATUS LOOP_attach_database(ISC_STATUS* user_status, FB_API_HANDLE public_handle, + const TEXT* filename, Rdb** handle, + SSHORT dpb_length, const SCHAR* dpb); +ISC_STATUS LOOP_create_database(ISC_STATUS* user_status, FB_API_HANDLE public_handle, + const TEXT* filename, Rdb** handle, + SSHORT dpb_length, const SCHAR* dpb); +ISC_STATUS LOOP_service_attach(ISC_STATUS* user_status, const TEXT* service_name, + Rdb** handle, USHORT spb_length, const UCHAR* spb); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/remote/interface.cpp b/src/remote/interface.cpp index 037f7cbb82..0263d365a6 100644 --- a/src/remote/interface.cpp +++ b/src/remote/interface.cpp @@ -125,8 +125,8 @@ namespace { static Rvnt* add_event(rem_port*); static void add_other_params(rem_port*, ClumpletWriter&, const ParametersSet&); static void add_working_directory(ClumpletWriter&, const PathName&); -static rem_port* analyze(PathName&, ISC_STATUS*, const TEXT*, bool, ClumpletReader&, PathName&); -static rem_port* analyze_service(PathName&, ISC_STATUS*, const TEXT*, bool, ClumpletReader&); +static rem_port* analyze(PathName&, ISC_STATUS*, const TEXT*, bool, ClumpletReader&, PathName&, bool); +static rem_port* analyze_service(PathName&, ISC_STATUS*, const TEXT*, bool, ClumpletReader&, bool); static bool batch_gds_receive(rem_port*, struct rmtque *, ISC_STATUS *, USHORT); static bool batch_dsql_fetch(rem_port*, struct rmtque *, ISC_STATUS *, USHORT); static bool check_response(Rdb*, PACKET *); @@ -258,12 +258,12 @@ inline bool defer_packet(rem_port* port, PACKET* packet, ISC_STATUS* status, boo #define GDS_DSQL_SQL_INFO REM_sql_info -ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, - FB_API_HANDLE /*public_handle*/, - const TEXT* filename, - Rdb** handle, - SSHORT dpb_length, - const SCHAR* dpb) +static ISC_STATUS remloop_att(ISC_STATUS* user_status, + const TEXT* filename, + Rdb** handle, + SSHORT dpb_length, + const SCHAR* dpb, + bool loopback) { /************************************** * @@ -304,7 +304,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, PathName expanded_name(filename); PathName node_name; - rem_port* port = analyze(expanded_name, user_status, us, user_verification, newDpb, node_name); + rem_port* port = analyze(expanded_name, user_status, us, user_verification, newDpb, node_name, loopback); if (!port) { return user_status[1]; @@ -338,6 +338,50 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, } +ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, + FB_API_HANDLE /*public_handle*/, + const TEXT* filename, + Rdb** handle, + SSHORT dpb_length, + const SCHAR* dpb) +{ +/************************************** + * + * g d s _ a t t a c h _ d a t a b a s e + * + ************************************** + * + * Functional description + * Connect to an old, grungy database, corrupted by user data. + * + **************************************/ + + return remloop_att(user_status, filename, handle, dpb_length, dpb, false); +} + + +ISC_STATUS LOOP_attach_database(ISC_STATUS* user_status, + FB_API_HANDLE /*public_handle*/, + const TEXT* filename, + Rdb** handle, + SSHORT dpb_length, + const SCHAR* dpb) +{ +/************************************** + * + * g d s _ a t t a c h _ d a t a b a s e + * + ************************************** + * + * Functional description + * Connect to an old, grungy database, corrupted by user data. + * + **************************************/ + + return remloop_att(user_status, filename, handle, dpb_length, dpb, true); +} + + ISC_STATUS GDS_BLOB_INFO(ISC_STATUS* user_status, Rbl** blob_handle, SSHORT item_length, @@ -786,12 +830,12 @@ ISC_STATUS GDS_CREATE_BLOB2(ISC_STATUS* user_status, } -ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, - FB_API_HANDLE /*public_handle*/, - const TEXT* filename, - Rdb** handle, - SSHORT dpb_length, - const SCHAR* dpb) +static ISC_STATUS remloop_create(ISC_STATUS* user_status, + const TEXT* filename, + Rdb** handle, + SSHORT dpb_length, + const SCHAR* dpb, + bool loopback) { /************************************** * @@ -803,6 +847,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, * Create a nice, squeeky clean database, uncorrupted by user data. * **************************************/ + ISC_STATUS* v = user_status; *v++ = isc_arg_gds; *v++ = isc_unavailable; @@ -831,7 +876,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, PathName expanded_name(filename); PathName node_name; - rem_port* port = analyze(expanded_name, user_status, us, user_verification, newDpb, node_name); + rem_port* port = analyze(expanded_name, user_status, us, user_verification, newDpb, node_name, loopback); if (!port) { return user_status[1]; } @@ -863,6 +908,50 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, } +ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, + FB_API_HANDLE /*public_handle*/, + const TEXT* filename, + Rdb** handle, + SSHORT dpb_length, + const SCHAR* dpb) +{ +/************************************** + * + * g d s _ c r e a t e _ d a t a b a s e + * + ************************************** + * + * Functional description + * Create a nice, squeeky clean database, uncorrupted by user data. + * + **************************************/ + + return remloop_create(user_status, filename, handle, dpb_length, dpb, false); +} + + +ISC_STATUS LOOP_create_database(ISC_STATUS* user_status, + FB_API_HANDLE /*public_handle*/, + const TEXT* filename, + Rdb** handle, + SSHORT dpb_length, + const SCHAR* dpb) +{ +/************************************** + * + * g d s _ c r e a t e _ d a t a b a s e + * + ************************************** + * + * Functional description + * Create a nice, squeeky clean database, uncorrupted by user data. + * + **************************************/ + + return remloop_create(user_status, filename, handle, dpb_length, dpb, true); +} + + ISC_STATUS GDS_DATABASE_INFO(ISC_STATUS* user_status, Rdb** handle, SSHORT item_length, @@ -3771,11 +3860,12 @@ ISC_STATUS GDS_SEND(ISC_STATUS* user_status, } -ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status, +static ISC_STATUS remloop_svc(ISC_STATUS* user_status, const TEXT* service_name, Rdb** handle, USHORT spb_length, - const UCHAR* spb) + const UCHAR* spb, + bool loopback) { /************************************** * @@ -3806,7 +3896,7 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status, const bool user_verification = get_new_dpb(newSpb, user_string, spbParam); const TEXT* us = user_string.hasData() ? user_string.c_str() : NULL; - rem_port* port = analyze_service(expanded_name, user_status, us, user_verification, newSpb); + rem_port* port = analyze_service(expanded_name, user_status, us, user_verification, newSpb, loopback); if (!port) { return user_status[1]; } @@ -3844,6 +3934,48 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status, } +ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status, + const TEXT* service_name, + Rdb** handle, + USHORT spb_length, + const UCHAR* spb) +{ +/************************************** + * + * g d s _ s e r v i c e _ a t t a c h + * + ************************************** + * + * Functional description + * Connect to a Firebird service. + * + **************************************/ + + return remloop_svc(user_status, service_name, handle, spb_length, spb, false); +} + + +ISC_STATUS LOOP_service_attach(ISC_STATUS* user_status, + const TEXT* service_name, + Rdb** handle, + USHORT spb_length, + const UCHAR* spb) +{ +/************************************** + * + * g d s _ s e r v i c e _ a t t a c h + * + ************************************** + * + * Functional description + * Connect to a Firebird service. + * + **************************************/ + + return remloop_svc(user_status, service_name, handle, spb_length, spb, true); +} + + ISC_STATUS GDS_SERVICE_DETACH(ISC_STATUS* user_status, Rdb** handle) { /************************************** @@ -4555,7 +4687,8 @@ static rem_port* analyze(PathName& file_name, const TEXT* user_string, bool uv_flag, ClumpletReader& dpb, - PathName& node_name) + PathName& node_name, + bool loopback) { /************************************** * @@ -4633,11 +4766,14 @@ static rem_port* analyze(PathName& file_name, } #endif + if (!loopback) + { + return port; + } + // We still have a local connection string but failed to connect so far. // If we're a pure client, attempt connect to the localhost. -#ifdef SUPERCLIENT - if (node_name.isEmpty()) { #ifdef WIN_NT @@ -4659,14 +4795,7 @@ static rem_port* analyze(PathName& file_name, } } -#endif // SUPERCLIENT - - if (port || status_vector[1]) - { - return port; - } - - return NULL; + return port; } @@ -4674,7 +4803,8 @@ static rem_port* analyze_service(PathName& service_name, ISC_STATUS* status_vector, const TEXT* user_string, bool uv_flag, - ClumpletReader& spb) + ClumpletReader& spb, + bool loopback) { /************************************** * @@ -4724,13 +4854,16 @@ static rem_port* analyze_service(PathName& service_name, node_name.c_str(), user_string, uv_flag, spb); } + if (!loopback) + { + return NULL; + } + // We have a local connection string. If we're a pure client, // attempt connect to a localhost. rem_port* port = NULL; -#ifdef SUPERCLIENT - if (node_name.isEmpty()) { #if defined(WIN_NT) @@ -4752,8 +4885,6 @@ static rem_port* analyze_service(PathName& service_name, } } -#endif // SUPERCLIENT - return port; }