diff --git a/src/include/firebird/UdrCppEngine.h b/src/include/firebird/UdrCppEngine.h index fc08919679..d0127cd7f8 100644 --- a/src/include/firebird/UdrCppEngine.h +++ b/src/include/firebird/UdrCppEngine.h @@ -622,7 +622,7 @@ public: fbUdrRegFunction(name, this); } - virtual void setup(IStatus* status, ExternalContext* /*context*/, + virtual void FB_CARG setup(IStatus* status, ExternalContext* /*context*/, const IRoutineMetadata* /*metadata*/, IMetadataBuilder* in, IMetadataBuilder* out) { T::InMessage::setup(status, in); @@ -647,7 +647,7 @@ public: fbUdrRegProcedure(name, this); } - virtual void setup(IStatus* status, ExternalContext* /*context*/, + virtual void FB_CARG setup(IStatus* status, ExternalContext* /*context*/, const IRoutineMetadata* /*metadata*/, IMetadataBuilder* in, IMetadataBuilder* out) { T::InMessage::setup(status, in); @@ -672,7 +672,7 @@ public: fbUdrRegTrigger(name, this); } - virtual void setup(IStatus* status, ExternalContext* /*context*/, + virtual void FB_CARG setup(IStatus* status, ExternalContext* /*context*/, const IRoutineMetadata* /*metadata*/, IMetadataBuilder* fields) { T::FieldsMessage::setup(status, fields); diff --git a/src/include/firebird/UdrEngine.h b/src/include/firebird/UdrEngine.h index 9dca264a81..bf07c0c6f8 100644 --- a/src/include/firebird/UdrEngine.h +++ b/src/include/firebird/UdrEngine.h @@ -39,7 +39,7 @@ namespace Firebird class FunctionFactory { public: - virtual void setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata, + virtual void FB_CARG setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) = 0; virtual ExternalFunction* FB_CARG newItem(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata) = 0; @@ -48,7 +48,7 @@ public: class ProcedureFactory { public: - virtual void setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata, + virtual void FB_CARG setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) = 0; virtual ExternalProcedure* FB_CARG newItem(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata) = 0; @@ -57,7 +57,7 @@ public: class TriggerFactory { public: - virtual void setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata, + virtual void FB_CARG setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder) = 0; virtual ExternalTrigger* FB_CARG newItem(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata) = 0; diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp index d6e20019d8..33e6305af9 100644 --- a/src/jrd/cch.cpp +++ b/src/jrd/cch.cpp @@ -77,7 +77,6 @@ using namespace Firebird; IMPLEMENT_TRACE_ROUTINE(cch_trace, "CCH") #endif - #ifdef SUPERSERVER_V2 #define CACHE_READER #endif @@ -2045,7 +2044,7 @@ void CCH_release(thread_db* tdbb, WIN* window, const bool release_tail) // hvlad: we want to make it least recently used, not most recently used //recentlyUsed(bdb); - if ((bcb->bcb_flags & BCB_cache_writer) && + if ((bcb->bcb_flags & BCB_cache_writer) && (bdb->bdb_flags & (BDB_dirty | BDB_db_dirty)) ) { //if (bdb->bdb_dirty.que_forward != &bdb->bdb_dirty) @@ -3889,7 +3888,7 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s } #endif - if ((bcb->bcb_flags & BCB_cache_writer) && + if ((bcb->bcb_flags & BCB_cache_writer) && (oldest->bdb_flags & (BDB_dirty | BDB_db_dirty)) ) { bcb->bcb_flags |= BCB_free_pending; diff --git a/src/jrd/dpm.epp b/src/jrd/dpm.epp index cfbad8803a..5c515c7b21 100644 --- a/src/jrd/dpm.epp +++ b/src/jrd/dpm.epp @@ -745,14 +745,16 @@ void DPM_delete( thread_db* tdbb, record_param* rpb, ULONG prior_page) if (count && (page->dpg_header.pag_flags & dpg_full)) { // hvlad: delay clearing of page_full flag until page have at least 25% - // of free space. It saves few costly mark_full() calls when space is + // of free space. It saves few costly mark_full() calls when space is // actively allocated and reclaimed in highly concurrent environment // and reduces PP contention. int used = HIGH_WATER(page->dpg_count); for (int i = 0; i < count; i++) + { if (page->dpg_rpt[i].dpg_offset) used += ROUNDUP(page->dpg_rpt[i].dpg_length, ODS_ALIGNMENT); + } if (used >= (dbb->dbb_page_size * 3 / 4)) { diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 4f0c2ad093..eb01184a9b 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -3090,6 +3090,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags) } procedure->getStatement()->procedure = procedure; + for (size_t i = 0; i < csb->csb_rpt.getCount(); i++) { MessageNode* node = csb->csb_rpt[i].csb_message; @@ -3102,6 +3103,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags) } ***/ } + delete csb; } else diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 35454230f8..1daa560261 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -917,6 +917,46 @@ void Blob::cancel(IStatus* status) } +void Blob::close(IStatus* status) +{ +/************************************** + * + * g d s _ c l o s e _ b l o b + * + ************************************** + * + * Functional description + * Close a completed blob. + * + **************************************/ + try + { + reset(status); + + CHECK_HANDLE(blob, isc_bad_segstr_handle); + + Rdb* rdb = blob->rbl_rdb; + CHECK_HANDLE(rdb, isc_bad_db_handle); + rem_port* port = rdb->rdb_port; + RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); + + if ((blob->rbl_flags & Rbl::CREATE) && blob->rbl_ptr != blob->rbl_buffer) + { + send_blob(status, blob, 0, NULL); + } + + release_object(status, rdb, op_close_blob, blob->rbl_id); + release_blob(blob); + blob = NULL; + release(); + } + catch (const Exception& ex) + { + ex.stuffException(status); + } +} + + void Events::freeClientData(IStatus* status, bool force) { /************************************** @@ -975,46 +1015,6 @@ void Events::cancel(IStatus* status) } -void Blob::close(IStatus* status) -{ -/************************************** - * - * g d s _ c l o s e _ b l o b - * - ************************************** - * - * Functional description - * Close a completed blob. - * - **************************************/ - try - { - reset(status); - - CHECK_HANDLE(blob, isc_bad_segstr_handle); - - Rdb* rdb = blob->rbl_rdb; - CHECK_HANDLE(rdb, isc_bad_db_handle); - rem_port* port = rdb->rdb_port; - RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); - - if ((blob->rbl_flags & Rbl::CREATE) && blob->rbl_ptr != blob->rbl_buffer) - { - send_blob(status, blob, 0, NULL); - } - - release_object(status, rdb, op_close_blob, blob->rbl_id); - release_blob(blob); - blob = NULL; - release(); - } - catch (const Exception& ex) - { - ex.stuffException(status); - } -} - - void Transaction::commit(IStatus* status) { /************************************** diff --git a/src/remote/server/os/posix/inet_server.cpp b/src/remote/server/os/posix/inet_server.cpp index 8c1fa87408..553c1f7533 100644 --- a/src/remote/server/os/posix/inet_server.cpp +++ b/src/remote/server/os/posix/inet_server.cpp @@ -157,9 +157,9 @@ int CLIB_ROUTINE main( int argc, char** argv) * Run the server with apollo mailboxes. * **************************************/ - try - { - RemPortPtr port; + try + { + RemPortPtr port; // 01 Sept 2003, Nickolay Samofatov // In GCC version 3.1-3.3 we need to install special error handler @@ -169,286 +169,289 @@ int CLIB_ROUTINE main( int argc, char** argv) // std::set_terminate (__gnu_cxx::__verbose_terminate_handler); //#endif - // We should support 3 modes: - // 1. Standalone single-process listener (like SS). - // 2. Standalone listener, forking on each packet accepted (look -s switch in CS). - // 3. Process spawned by (x)inetd (like CS). - bool classic = false; - bool standaloneClassic = false; - bool super = false; + // We should support 3 modes: + // 1. Standalone single-process listener (like SS). + // 2. Standalone listener, forking on each packet accepted (look -s switch in CS). + // 3. Process spawned by (x)inetd (like CS). + bool classic = false; + bool standaloneClassic = false; + bool super = false; - // It's very easy to detect that we are spawned - just check fd 0 to be a socket. - const int channel = 0; - struct stat stat0; - if (fstat(channel, &stat0) == 0 && S_ISSOCK(stat0.st_mode)) - { - // classic server mode - classic = true; - } + // It's very easy to detect that we are spawned - just check fd 0 to be a socket. + const int channel = 0; + struct stat stat0; + if (fstat(channel, &stat0) == 0 && S_ISSOCK(stat0.st_mode)) + { + // classic server mode + classic = true; + } - const TEXT* const* const end = argc + argv; - argv++; - bool debug = false; - USHORT INET_SERVER_flag = 0; - protocol[0] = 0; + const TEXT* const* const end = argc + argv; + argv++; + bool debug = false; + USHORT INET_SERVER_flag = 0; + protocol[0] = 0; - bool done = false; + bool done = false; - while (argv < end) - { - TEXT c; - const TEXT* p = *argv++; - if (*p++ == '-') - while (c = *p++) + while (argv < end) + { + TEXT c; + const TEXT* p = *argv++; + + if (*p++ == '-') { - switch (UPPER(c)) + while (c = *p++) { - case 'D': - debug = true; - break; + switch (UPPER(c)) + { + case 'D': + debug = true; + break; - case 'S': - if (!classic) - { - standaloneClassic = true; - } - break; - - case 'I': - if (!classic) - { - standaloneClassic = false; - } - break; - - case 'E': - if (argv < end) - { - if (ISC_set_prefix(p, *argv) == -1) - printf("Invalid argument Ignored\n"); - else - argv++; // do not skip next argument if this one is invalid - } - else - { - printf("Missing argument, switch -E ignored\n"); - } - done = true; - break; - - case 'P': - if (argv < end) - { + case 'S': if (!classic) { - fb_utils::snprintf(protocol, sizeof(protocol), "/%s", *argv++); + standaloneClassic = true; + } + break; + + case 'I': + if (!classic) + { + standaloneClassic = false; + } + break; + + case 'E': + if (argv < end) + { + if (ISC_set_prefix(p, *argv) == -1) + printf("Invalid argument Ignored\n"); + else + argv++; // do not skip next argument if this one is invalid } else { - gds__log("Switch -P ignored in CS mode\n"); + printf("Missing argument, switch -E ignored\n"); } + done = true; + break; + + case 'P': + if (argv < end) + { + if (!classic) + { + fb_utils::snprintf(protocol, sizeof(protocol), "/%s", *argv++); + } + else + { + gds__log("Switch -P ignored in CS mode\n"); + } + } + else + { + printf("Missing argument, switch -P ignored\n"); + } + break; + + case 'H': + case '?': + printf("Firebird TCP/IP server options are:\n"); + printf(" -d : debug on\n"); + printf(" -s : standalone - true\n"); + printf(" -i : standalone - false\n"); + printf(" -p : specify port to listen on\n"); + printf(" -z : print version and exit\n"); + printf(" -h|? : print this help\n"); + printf("\n"); + printf(" (The following -e options used to be -h options)\n"); + printf(" -e : set firebird_root path\n"); + printf(" -el : set runtime firebird_lock dir\n"); + printf(" -em : set firebird_msg dir path\n"); + + exit(FINI_OK); + + case 'Z': + printf("Firebird TCP/IP server version %s\n", FB_VERSION); + exit(FINI_OK); + + default: + printf("Unknown switch '%c', ignored\n", c); + break; } - else - { - printf("Missing argument, switch -P ignored\n"); - } - break; - - case 'H': - case '?': - printf("Firebird TCP/IP server options are:\n"); - printf(" -d : debug on\n"); - printf(" -s : standalone - true\n"); - printf(" -i : standalone - false\n"); - printf(" -p : specify port to listen on\n"); - printf(" -z : print version and exit\n"); - printf(" -h|? : print this help\n"); - printf("\n"); - printf(" (The following -e options used to be -h options)\n"); - printf(" -e : set firebird_root path\n"); - printf(" -el : set runtime firebird_lock dir\n"); - printf(" -em : set firebird_msg dir path\n"); - - exit(FINI_OK); - - case 'Z': - printf("Firebird TCP/IP server version %s\n", FB_VERSION); - exit(FINI_OK); - - default: - printf("Unknown switch '%c', ignored\n", c); - break; + if (done) + break; } - if (done) - break; } - } + } - if (!(classic || standaloneClassic)) - { - INET_SERVER_flag |= SRVR_multi_client; - super = true; - } - if (debug) - { - INET_SERVER_flag |= SRVR_debug; - } + if (!(classic || standaloneClassic)) + { + INET_SERVER_flag |= SRVR_multi_client; + super = true; + } + if (debug) + { + INET_SERVER_flag |= SRVR_debug; + } - // activate paths set with -e family of switches - ISC_set_prefix(0, 0); + // activate paths set with -e family of switches + ISC_set_prefix(0, 0); - // ignore some signals - set_signal(SIGPIPE, signal_handler); - set_signal(SIGUSR1, signal_handler); - set_signal(SIGUSR2, signal_handler); + // ignore some signals + set_signal(SIGPIPE, signal_handler); + set_signal(SIGUSR1, signal_handler); + set_signal(SIGUSR2, signal_handler); - // First of all change directory to tmp - if (chdir(TEMP_DIR)) - { - // error on changing the directory - gds__log("Could not change directory to %s due to errno %d", TEMP_DIR, errno); - } + // First of all change directory to tmp + if (chdir(TEMP_DIR)) + { + // error on changing the directory + gds__log("Could not change directory to %s due to errno %d", TEMP_DIR, errno); + } #ifdef FB_RAISE_LIMITS #ifdef RLIMIT_NPROC - raiseLimit(RLIMIT_NPROC); + raiseLimit(RLIMIT_NPROC); #endif #if !(defined(DEV_BUILD)) - if (Config::getBugcheckAbort()) + if (Config::getBugcheckAbort()) #endif - { - // try to force core files creation - raiseLimit(RLIMIT_CORE); - } + { + // try to force core files creation + raiseLimit(RLIMIT_CORE); + } #if (defined SOLARIS || defined HPUX || defined LINUX) - if (super) - { - // Increase max open files to hard limit for Unix - // platforms which are known to have low soft limits. + if (super) + { + // Increase max open files to hard limit for Unix + // platforms which are known to have low soft limits. - raiseLimit(RLIMIT_NOFILE); - } + raiseLimit(RLIMIT_NOFILE); + } #endif // Unix platforms #endif // FB_RAISE_LIMITS - if (!(debug || classic)) - { - int mask = 0; // FD_ZERO(&mask); - mask |= 1 << 2; // FD_SET(2, &mask); - divorce_terminal(mask); - } - - // check firebird.conf presence - must be for server - if (Config::missFirebirdConf()) - { - Firebird::Syslog::Record(Firebird::Syslog::Error, "Missing master config file firebird.conf"); - exit(STARTUP_ERROR); - } - - if (super || standaloneClassic) - { - try + if (!(debug || classic)) { - port = INET_connect(protocol, 0, INET_SERVER_flag, 0); + int mask = 0; // FD_ZERO(&mask); + mask |= 1 << 2; // FD_SET(2, &mask); + divorce_terminal(mask); } - catch (const Firebird::Exception& ex) + + // check firebird.conf presence - must be for server + if (Config::missFirebirdConf()) { - iscLogException("startup:INET_connect:", ex); - ISC_STATUS_ARRAY status_vector; - ex.stuff_exception(status_vector); - gds__print_status(status_vector); + Firebird::Syslog::Record(Firebird::Syslog::Error, "Missing master config file firebird.conf"); exit(STARTUP_ERROR); } - } - if (classic) - { - port = INET_server(channel); - if (!port) + if (super || standaloneClassic) { - fprintf(stderr, "fbserver: Unable to start INET_server\n"); - exit(STARTUP_ERROR); + try + { + port = INET_connect(protocol, 0, INET_SERVER_flag, 0); + } + catch (const Firebird::Exception& ex) + { + iscLogException("startup:INET_connect:", ex); + ISC_STATUS_ARRAY status_vector; + ex.stuff_exception(status_vector); + gds__print_status(status_vector); + exit(STARTUP_ERROR); + } } - } - { // scope for interface ptr - Firebird::PluginManagerInterfacePtr pi; - Auth::registerLegacyServer(pi); - Auth::registerSrpServer(pi); + if (classic) + { + port = INET_server(channel); + if (!port) + { + fprintf(stderr, "fbserver: Unable to start INET_server\n"); + exit(STARTUP_ERROR); + } + } + + { // scope for interface ptr + Firebird::PluginManagerInterfacePtr pi; + Auth::registerLegacyServer(pi); + Auth::registerSrpServer(pi); #ifdef TRUSTED_AUTH - Auth::registerTrustedServer(pi); + Auth::registerTrustedServer(pi); #endif - } - - if (super) - { - // Server tries to attach to security2.fdb to make sure everything is OK - // This code fixes bug# 8429 + all other bug of that kind - from - // now on the server exits if it cannot attach to the database - // (wrong or no license, not enough memory, etc. - - ISC_STATUS_ARRAY status; - isc_db_handle db_handle = 0L; - - const Firebird::RefPtr defConf(Config::getDefaultConfig()); - const char* path = defConf->getSecurityDatabase(); - const char dpb[] = {isc_dpb_version1, isc_dpb_gsec_attach, 1, 1, isc_dpb_address_path, 0}; - - isc_attach_database(status, strlen(path), path, &db_handle, sizeof dpb, dpb); - if (status[0] == 1 && status[1] > 0) - { - logSecurityDatabaseError(path, status); } - isc_detach_database(status, &db_handle); - if (status[0] == 1 && status[1] > 0) + if (super) { - logSecurityDatabaseError(path, status); - } - } // end scope + // Server tries to attach to security2.fdb to make sure everything is OK + // This code fixes bug# 8429 + all other bug of that kind - from + // now on the server exits if it cannot attach to the database + // (wrong or no license, not enough memory, etc. - fb_shutdown_callback(NULL, closePort, fb_shut_exit, port); + ISC_STATUS_ARRAY status; + isc_db_handle db_handle = 0L; - SRVR_multi_thread(port, INET_SERVER_flag); + const Firebird::RefPtr defConf(Config::getDefaultConfig()); + const char* path = defConf->getSecurityDatabase(); + const char dpb[] = {isc_dpb_version1, isc_dpb_gsec_attach, 1, 1, isc_dpb_address_path, 0}; + + isc_attach_database(status, strlen(path), path, &db_handle, sizeof dpb, dpb); + if (status[0] == 1 && status[1] > 0) + { + logSecurityDatabaseError(path, status); + } + + isc_detach_database(status, &db_handle); + if (status[0] == 1 && status[1] > 0) + { + logSecurityDatabaseError(path, status); + } + } // end scope + + fb_shutdown_callback(NULL, closePort, fb_shut_exit, port); + + SRVR_multi_thread(port, INET_SERVER_flag); #ifdef DEBUG_GDS_ALLOC - // In Debug mode - this will report all server-side memory leaks due to remote access + // In Debug mode - this will report all server-side memory leaks due to remote access - //gds_alloc_report(0, __FILE__, __LINE__); - Firebird::PathName name = fb_utils::getPrefix(fb_utils::FB_DIR_LOG, "memdebug.log"); - FILE* file = fopen(name.c_str(), "w+t"); - if (file) - { - fprintf(file, "Global memory pool allocated objects\n"); - getDefaultMemoryPool()->print_contents(file); - fclose(file); - } + //gds_alloc_report(0, __FILE__, __LINE__); + Firebird::PathName name = fb_utils::getPrefix(fb_utils::FB_DIR_LOG, "memdebug.log"); + FILE* file = fopen(name.c_str(), "w+t"); + if (file) + { + fprintf(file, "Global memory pool allocated objects\n"); + getDefaultMemoryPool()->print_contents(file); + fclose(file); + } #endif - // 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); + // 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; - } - catch(const Firebird::Exception& ex) - { - ISC_STATUS_ARRAY status; - ex.stuff_exception(status); + return FINI_OK; + } + catch (const Firebird::Exception& ex) + { + ISC_STATUS_ARRAY status; + ex.stuff_exception(status); - char s[100]; - const ISC_STATUS* st = status; - fb_interpret(s, sizeof(s), &st); + char s[100]; + const ISC_STATUS* st = status; + fb_interpret(s, sizeof(s), &st); - Firebird::Syslog::Record(Firebird::Syslog::Error, "Firebird startup error"); - Firebird::Syslog::Record(Firebird::Syslog::Error, s); + Firebird::Syslog::Record(Firebird::Syslog::Error, "Firebird startup error"); + Firebird::Syslog::Record(Firebird::Syslog::Error, s); - exit(STARTUP_ERROR); - } + exit(STARTUP_ERROR); + } } } // extern "C" diff --git a/src/remote/server/os/win32/srvr_w32.cpp b/src/remote/server/os/win32/srvr_w32.cpp index 16a4170cd1..a2664a5bc0 100644 --- a/src/remote/server/os/win32/srvr_w32.cpp +++ b/src/remote/server/os/win32/srvr_w32.cpp @@ -503,7 +503,7 @@ static THREAD_ENTRY_DECLARE xnet_connect_wait_thread(THREAD_ENTRY_PARAM) iscLogException("XNET_connect", ex); } - if (port) + if (port) { try {