"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/svc.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

svc.cpp  (Firebird-3.0.2.32703-0.tar.bz2):svc.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 138 skipping to change at line 138
namespace { namespace {
// Generic mutex to synchronize services // Generic mutex to synchronize services
GlobalPtr<Mutex> globalServicesMutex; GlobalPtr<Mutex> globalServicesMutex;
// All that we need to shutdown service threads when shutdown in progress // All that we need to shutdown service threads when shutdown in progress
typedef Array<Jrd::Service*> AllServices; typedef Array<Jrd::Service*> AllServices;
GlobalPtr<AllServices> allServices; // protected by globalServicesMut ex GlobalPtr<AllServices> allServices; // protected by globalServicesMut ex
volatile bool svcShutdown = false; volatile bool svcShutdown = false;
class ThreadCollect
{
public:
ThreadCollect(MemoryPool& p)
: threads(p)
{ }
void join()
{
// join threads to be sure they are gone when shutdown is
complete
// no need locking something cause this is expected to ru
n when services are closing
waitFor(threads);
}
void add(Thread::Handle& h)
{
// put thread into completion wait queue when it finished
running
MutexLockGuard g(threadsMutex, FB_FUNCTION);
threads.add(h);
}
void houseKeeping()
{
if (!threads.hasData())
return;
// join finished threads
AllThreads t;
{ // mutex scope
MutexLockGuard g(threadsMutex, FB_FUNCTION);
t.assign(threads);
threads.clear();
}
waitFor(t);
}
private:
typedef Array<Thread::Handle> AllThreads;
static void waitFor(AllThreads& thr)
{
while (thr.hasData())
{
Thread::Handle h(thr.pop());
Thread::waitForCompletion(h);
}
}
AllThreads threads;
Mutex threadsMutex;
};
GlobalPtr<ThreadCollect> threadCollect;
void spbVersionError() void spbVersionError()
{ {
ERR_post(Arg::Gds(isc_bad_spb_form) << ERR_post(Arg::Gds(isc_bad_spb_form) <<
Arg::Gds(isc_wrospbver)); Arg::Gds(isc_wrospbver));
} }
} // anonymous namespace } // anonymous namespace
using namespace Jrd; using namespace Jrd;
skipping to change at line 257 skipping to change at line 312
case isc_spb_command_line: case isc_spb_command_line:
spb.getString(svc_command_line); spb.getString(svc_command_line);
break; break;
case isc_spb_expected_db: case isc_spb_expected_db:
spb.getPath(svc_expected_db); spb.getPath(svc_expected_db);
break; break;
case isc_spb_address_path: case isc_spb_address_path:
spb.getString(svc_address_path); spb.getData(svc_address_path);
{ {
ClumpletReader address_stack(ClumpletReader::UnTa gged, ClumpletReader address_stack(ClumpletReader::UnTa gged,
spb.getBytes(), spb.getClumpLength()); spb.getBytes(), spb.getClumpLength());
while (!address_stack.isEof()) while (!address_stack.isEof())
{ {
if (address_stack.getClumpTag() != isc_dp b_address) if (address_stack.getClumpTag() != isc_dp b_address)
{ {
address_stack.moveNext(); address_stack.moveNext();
continue; continue;
} }
skipping to change at line 565 skipping to change at line 620
} }
unsigned int Service::getAuthBlock(const unsigned char** bytes) unsigned int Service::getAuthBlock(const unsigned char** bytes)
{ {
*bytes = svc_auth_block.hasData() ? svc_auth_block.begin() : NULL; *bytes = svc_auth_block.hasData() ? svc_auth_block.begin() : NULL;
return svc_auth_block.getCount(); return svc_auth_block.getCount();
} }
void Service::fillDpb(ClumpletWriter& dpb) void Service::fillDpb(ClumpletWriter& dpb)
{ {
const char* providers = "Providers=" CURRENT_ENGINE; dpb.insertString(isc_dpb_config, EMBEDDED_PROVIDERS, fb_strlen(EMBEDDED_P
dpb.insertString(isc_dpb_config, providers, fb_strlen(providers)); ROVIDERS));
if (svc_address_path.hasData()) if (svc_address_path.hasData())
{ {
dpb.insertString(isc_dpb_address_path, svc_address_path); dpb.insertData(isc_dpb_address_path, svc_address_path);
} }
if (svc_utf8) if (svc_utf8)
{ {
dpb.insertTag(isc_dpb_utf8_filename); dpb.insertTag(isc_dpb_utf8_filename);
} }
if (svc_crypt_callback) if (svc_crypt_callback)
{ {
// That's not DPB-related, but anyway should be done before attac h/create DB // That's not DPB-related, but anyway should be done before attac h/create DB
ISC_STATUS_ARRAY status; ISC_STATUS_ARRAY status;
if (fb_database_crypt_callback(status, svc_crypt_callback) != 0) if (fb_database_crypt_callback(status, svc_crypt_callback) != 0)
skipping to change at line 653 skipping to change at line 707
svc_resp_len(0), svc_flags(SVC_finished), svc_user_flag(0), svc_spb_versi on(0), svc_resp_len(0), svc_flags(SVC_finished), svc_user_flag(0), svc_spb_versi on(0),
svc_do_shutdown(false), svc_shutdown_in_progress(false), svc_timeout(fals e), svc_do_shutdown(false), svc_shutdown_in_progress(false), svc_timeout(fals e),
svc_username(getPool()), svc_sql_role(getPool()), svc_auth_block(getPool( )), svc_username(getPool()), svc_sql_role(getPool()), svc_auth_block(getPool( )),
svc_expected_db(getPool()), svc_trusted_role(false), svc_utf8(false), svc_expected_db(getPool()), svc_trusted_role(false), svc_utf8(false),
svc_switches(getPool()), svc_perm_sw(getPool()), svc_address_path(getPool ()), svc_switches(getPool()), svc_perm_sw(getPool()), svc_address_path(getPool ()),
svc_command_line(getPool()), svc_command_line(getPool()),
svc_network_protocol(getPool()), svc_remote_address(getPool()), svc_remot e_process(getPool()), svc_network_protocol(getPool()), svc_remote_address(getPool()), svc_remot e_process(getPool()),
svc_remote_pid(0), svc_trace_manager(NULL), svc_crypt_callback(crypt_call back), svc_remote_pid(0), svc_trace_manager(NULL), svc_crypt_callback(crypt_call back),
svc_existence(FB_NEW_POOL(*getDefaultMemoryPool()) SvcMutex(this)), svc_existence(FB_NEW_POOL(*getDefaultMemoryPool()) SvcMutex(this)),
svc_stdin_size_requested(0), svc_stdin_buffer(NULL), svc_stdin_size_prelo ad(0), svc_stdin_size_requested(0), svc_stdin_buffer(NULL), svc_stdin_size_prelo ad(0),
svc_stdin_preload_requested(0), svc_stdin_user_size(0) svc_stdin_preload_requested(0), svc_stdin_user_size(0), svc_thread(0)
#ifdef DEV_BUILD #ifdef DEV_BUILD
, svc_debug(false) , svc_debug(false)
#endif #endif
{ {
initStatus(); initStatus();
{ // scope { // scope
// Account service block in global array // Account service block in global array
MutexLockGuard guard(globalServicesMutex, FB_FUNCTION); MutexLockGuard guard(globalServicesMutex, FB_FUNCTION);
checkForShutdown(); checkForShutdown();
skipping to change at line 978 skipping to change at line 1032
{ {
globalServicesMutex->leave(); globalServicesMutex->leave();
Thread::sleep(1); Thread::sleep(1);
globalServicesMutex->enter(FB_FUNCTION); globalServicesMutex->enter(FB_FUNCTION);
pos = 0; pos = 0;
continue; continue;
} }
++pos; ++pos;
} }
threadCollect->join();
} }
ISC_STATUS Service::query2(thread_db* /*tdbb*/, ISC_STATUS Service::query2(thread_db* /*tdbb*/,
USHORT send_item_length, USHORT send_item_length,
const UCHAR* send_items, const UCHAR* send_items,
USHORT recv_item_length, USHORT recv_item_length,
const UCHAR* recv_items, const UCHAR* recv_items,
USHORT buffer_length, USHORT buffer_length,
UCHAR* info) UCHAR* info)
{ {
skipping to change at line 1117 skipping to change at line 1173
if (!ck_space_for_numeric(info, end)) if (!ck_space_for_numeric(info, end))
return 0; return 0;
*info++ = isc_spb_num_db; *info++ = isc_spb_num_db;
ADD_SPB_NUMERIC(info, num_dbs); ADD_SPB_NUMERIC(info, num_dbs);
// Move db names into the info buffer // Move db names into the info buffer
for (FB_SIZE_T i = 0; i < databases.getCount(); i ++) for (FB_SIZE_T i = 0; i < databases.getCount(); i ++)
{ {
if (!(info = INF_put_item(isc_spb_dbname, if (!(info = INF_put_item(isc_spb_dbname,
(USHORT) databases[i].length(), (USHORT) databases[i].length(),
(const UCHAR*) databases[i].c_str(), databases[i].c_str(),
info, end))) info, end)))
{ {
return 0; return 0;
} }
} }
if (info < end) if (info < end)
*info++ = isc_info_flag_end; *info++ = isc_info_flag_end;
} }
else else
skipping to change at line 1257 skipping to change at line 1313
if (svc_flags & SVC_finished) if (svc_flags & SVC_finished)
ADD_SPB_NUMERIC(info, FALSE) ADD_SPB_NUMERIC(info, FALSE)
else else
ADD_SPB_NUMERIC(info, TRUE) ADD_SPB_NUMERIC(info, TRUE)
break; break;
case isc_info_svc_server_version: case isc_info_svc_server_version:
// The version of the server engine // The version of the server engine
{ // scope { // scope
static const UCHAR* pv = reinterpret_cast<const U info = INF_put_item(item, static_cast<USHORT>(str
CHAR*>(FB_VERSION); len(FB_VERSION)), FB_VERSION, info, end);
info = INF_put_item(item, static_cast<USHORT>(str
len(FB_VERSION)), pv, info, end);
if (!info) { if (!info) {
return 0; return 0;
} }
} // scope } // scope
break; break;
case isc_info_svc_implementation: case isc_info_svc_implementation:
// The server implementation - e.g. Firebird/sun4 // The server implementation - e.g. Firebird/sun4
{ // scope { // scope
string buf2 = DbImplementation::current.implement ation(); string buf2 = DbImplementation::current.implement ation();
info = INF_put_item(item, buf2.length(), info = INF_put_item(item, buf2.length(), buf2.c_s
reinterpr tr(), info, end);
et_cast<const UCHAR*>(buf2.c_str()), info, end);
if (!info) { if (!info) {
return 0; return 0;
} }
} // scope } // scope
break; break;
case isc_info_svc_stdin: case isc_info_svc_stdin:
// Check - is stdin data required for server // Check - is stdin data required for server
if (!ck_space_for_numeric(info, end)) if (!ck_space_for_numeric(info, end))
{ {
skipping to change at line 1296 skipping to change at line 1350
stdin_request_notification = info; stdin_request_notification = info;
} }
ADD_SPB_NUMERIC(info, 0); ADD_SPB_NUMERIC(info, 0);
break; break;
case isc_info_svc_user_dbpath: case isc_info_svc_user_dbpath:
if (svc_user_flag & SVC_user_dba) if (svc_user_flag & SVC_user_dba)
{ {
// The path to the user security database (securi ty2.fdb) // The path to the user security database (securi ty2.fdb)
char* pb = reinterpret_cast<char*>(buffer);
const RefPtr<const Config> defConf(Config::getDef aultConfig()); const RefPtr<const Config> defConf(Config::getDef aultConfig());
strcpy(pb, defConf->getSecurityDatabase()); const char* secDb = defConf->getSecurityDatabase( );
if (!(info = INF_put_item(item, static_cast<USHOR T>(strlen(pb)), buffer, info, end))) if (!(info = INF_put_item(item, static_cast<USHOR T>(strlen(secDb)), secDb, info, end)))
{ {
return 0; return 0;
} }
} }
else else
need_admin_privs(status, "isc_info_svc_user_dbpat h"); need_admin_privs(status, "isc_info_svc_user_dbpat h");
break; break;
case isc_info_svc_response: case isc_info_svc_response:
svc_resp_len = 0; svc_resp_len = 0;
skipping to change at line 1648 skipping to change at line 1701
case isc_info_svc_get_env_lock: case isc_info_svc_get_env_lock:
iscPrefixLock(PathBuffer, "", false); iscPrefixLock(PathBuffer, "", false);
break; break;
case isc_info_svc_get_env_msg: case isc_info_svc_get_env_msg:
gds__prefix_msg(PathBuffer, ""); gds__prefix_msg(PathBuffer, "");
} }
// Note: it is safe to use strlen to get a length of "buffer" // Note: it is safe to use strlen to get a length of "buffer"
// because gds_prefix[_lock|_msg] return a zero-t erminated // because gds_prefix[_lock|_msg] return a zero-t erminated
// string. // string.
const UCHAR* pb = reinterpret_cast<const UCHAR*>( if (!(info = INF_put_item(item, static_cast<USHOR
PathBuffer); T>(strlen(PathBuffer)), PathBuffer, info, end)))
if (!(info = INF_put_item(item, static_cast<USHOR
T>(strlen(PathBuffer)), pb, info, end)))
return; return;
} }
// Can not return error for service v.1 => simply ignore request // Can not return error for service v.1 => simply ignore request
// else // else
// need_admin_privs(status, "isc_info_svc_get_env"); // need_admin_privs(status, "isc_info_svc_get_env");
break; break;
case isc_info_svc_dump_pool_info: case isc_info_svc_dump_pool_info:
{ {
char fname[MAXPATHLEN]; char fname[MAXPATHLEN];
skipping to change at line 1748 skipping to change at line 1800
if (!(info = INF_put_item(item, p - buffer, buffer, info, end))) if (!(info = INF_put_item(item, p - buffer, buffer, info, end)))
{ {
return; return;
} }
break; break;
case isc_info_svc_user_dbpath: case isc_info_svc_user_dbpath:
if (svc_user_flag & SVC_user_dba) if (svc_user_flag & SVC_user_dba)
{ {
// The path to the user security database (securi ty2.fdb) // The path to the user security database (securi ty2.fdb)
char* pb = reinterpret_cast<char*>(buffer);
const RefPtr<const Config> defConf(Config::getDef aultConfig()); const RefPtr<const Config> defConf(Config::getDef aultConfig());
strcpy(pb, defConf->getSecurityDatabase()); const char* secDb = defConf->getSecurityDatabase( );
if (!(info = INF_put_item(item, static_cast<USHOR T>(strlen(pb)), buffer, info, end))) if (!(info = INF_put_item(item, static_cast<USHOR T>(strlen(secDb)), secDb, info, end)))
{ {
return; return;
} }
} }
// Can not return error for service v.1 => simply ignore request // Can not return error for service v.1 => simply ignore request
// else // else
// need_admin_privs(status, "isc_info_svc_user_dbpat h"); // need_admin_privs(status, "isc_info_svc_user_dbpat h");
break; break;
case isc_info_svc_response: case isc_info_svc_response:
skipping to change at line 1903 skipping to change at line 1954
THREAD_ENTRY_DECLARE Service::run(THREAD_ENTRY_PARAM arg) THREAD_ENTRY_DECLARE Service::run(THREAD_ENTRY_PARAM arg)
{ {
int exit_code = -1; int exit_code = -1;
try try
{ {
Service* svc = (Service*)arg; Service* svc = (Service*)arg;
RefPtr<SvcMutex> ref(svc->svc_existence); RefPtr<SvcMutex> ref(svc->svc_existence);
exit_code = svc->svc_service_run->serv_thd(svc); exit_code = svc->svc_service_run->serv_thd(svc);
if (svc->svc_thread)
{
threadCollect->add(svc->svc_thread);
svc->svc_thread = 0;
}
svc->started(); svc->started();
svc->svc_sem_full.release(); svc->svc_sem_full.release();
svc->finish(SVC_finished); svc->finish(SVC_finished);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
// Not much we can do here // Not much we can do here
exit_code = -1; exit_code = -1;
iscLogException("Exception in Service::run():", ex); iscLogException("Exception in Service::run():", ex);
} }
skipping to change at line 2064 skipping to change at line 2120
// The service block can be reused hence init a status vector. // The service block can be reused hence init a status vector.
initStatus(); initStatus();
if (serv->serv_thd) if (serv->serv_thd)
{ {
svc_flags &= ~(SVC_evnt_fired | SVC_finished); svc_flags &= ~(SVC_evnt_fired | SVC_finished);
svc_stdout_head = svc_stdout_tail = 0; svc_stdout_head = svc_stdout_tail = 0;
Thread::start(run, this, THREAD_medium); Thread::start(run, this, THREAD_medium, &svc_thread);
// good time for housekeeping while new thread starts
threadCollect->houseKeeping();
// Check for the service being detached. This will prevent the th read // Check for the service being detached. This will prevent the th read
// from waiting infinitely if the client goes away. // from waiting infinitely if the client goes away.
while (!(svc_flags & SVC_detached)) while (!(svc_flags & SVC_detached))
{ {
// The semaphore will be released once the particular ser vice // The semaphore will be released once the particular ser vice
// has reached a point in which it can start to return // has reached a point in which it can start to return
// information to the client. This will allow isc_servic e_start // information to the client. This will allow isc_servic e_start
// to include in its status vector information about the service's // to include in its status vector information about the service's
// ability to start. // ability to start.
skipping to change at line 2187 skipping to change at line 2246
{ {
// Break up the command line into individual arguments. // Break up the command line into individual arguments.
parseSwitches(); parseSwitches();
if (svc_service && svc_service->serv_name) if (svc_service && svc_service->serv_name)
{ {
argv[0] = svc_service->serv_name; argv[0] = svc_service->serv_name;
} }
svc_service_run = service_run; svc_service_run = service_run;
Thread::start(run, this, THREAD_medium); Thread::start(run, this, THREAD_medium, &svc_thread);
} }
ULONG Service::add_one(ULONG i) ULONG Service::add_one(ULONG i)
{ {
return (i + 1) % SVC_STDOUT_BUFFER_SIZE; return (i + 1) % SVC_STDOUT_BUFFER_SIZE;
} }
ULONG Service::add_val(ULONG i, ULONG val) ULONG Service::add_val(ULONG i, ULONG val)
{ {
return (i + val) % SVC_STDOUT_BUFFER_SIZE; return (i + val) % SVC_STDOUT_BUFFER_SIZE;
 End of changes. 19 change blocks. 
25 lines changed or deleted 86 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)