/******************************************************************************/ /* */ /* X r d C l i e n t E n v . c c */ /* */ /* Author: Fabrizio Furano (INFN Padova, 2004) */ /* Adapted from TXNetFile (root.cern.ch) originally done by */ /* Alvise Dorigo, Fabrizio Furano */ /* INFN Padova, 2003 */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // Singleton used to handle the default parameter values // // // ////////////////////////////////////////////////////////////////////////// #include "XrdSys/XrdSysHeaders.hh" #include "XrdClient/XrdClientConst.hh" #include "XrdClient/XrdClientEnv.hh" #include "XrdClient/XrdClientConn.hh" #include "XrdClient/XrdClientConnMgr.hh" #include #include #include XrdClientEnv *XrdClientEnv::fgInstance = 0; XrdClientEnv *XrdClientEnv::Instance() { // Create unique instance if (!fgInstance) { fgInstance = new XrdClientEnv; if (!fgInstance) { std::cerr << "XrdClientEnv::Instance: fatal - couldn't create XrdClientEnv" << std::endl; abort(); } } return fgInstance; } //_____________________________________________________________________________ XrdClientEnv::XrdClientEnv() { // Constructor fOucEnv = new XrdOucEnv(); fShellEnv = new XrdOucEnv(); PutInt(NAME_CONNECTTIMEOUT, DFLT_CONNECTTIMEOUT); PutInt(NAME_REQUESTTIMEOUT, DFLT_REQUESTTIMEOUT); PutInt(NAME_MAXREDIRECTCOUNT, DFLT_MAXREDIRECTCOUNT); PutInt(NAME_DEBUG, DFLT_DEBUG); PutInt(NAME_RECONNECTWAIT, DFLT_RECONNECTWAIT); PutInt(NAME_REDIRCNTTIMEOUT, DFLT_REDIRCNTTIMEOUT); PutInt(NAME_FIRSTCONNECTMAXCNT, DFLT_FIRSTCONNECTMAXCNT); PutInt(NAME_READCACHESIZE, DFLT_READCACHESIZE); PutInt(NAME_READCACHEBLKREMPOLICY, DFLT_READCACHEBLKREMPOLICY); PutInt(NAME_READAHEADSIZE, DFLT_READAHEADSIZE); PutInt(NAME_MULTISTREAMCNT, DFLT_MULTISTREAMCNT); PutInt(NAME_DFLTTCPWINDOWSIZE, DFLT_DFLTTCPWINDOWSIZE); PutInt(NAME_DATASERVERCONN_TTL, DFLT_DATASERVERCONN_TTL); PutInt(NAME_LBSERVERCONN_TTL, DFLT_LBSERVERCONN_TTL); PutInt(NAME_PURGEWRITTENBLOCKS, DFLT_PURGEWRITTENBLOCKS); PutInt(NAME_READAHEADSTRATEGY, DFLT_READAHEADSTRATEGY); PutInt(NAME_READTRIMBLKSZ, DFLT_READTRIMBLKSZ); PutInt(NAME_TRANSACTIONTIMEOUT, DFLT_TRANSACTIONTIMEOUT); PutInt(NAME_REMUSEDCACHEBLKS, DFLT_REMUSEDCACHEBLKS); PutInt(NAME_ENABLE_FORK_HANDLERS, DFLT_ENABLE_FORK_HANDLERS); PutInt(NAME_ENABLE_TCP_KEEPALIVE, DFLT_ENABLE_TCP_KEEPALIVE); PutInt(NAME_TCP_KEEPALIVE_TIME, DFLT_TCP_KEEPALIVE_TIME); PutInt(NAME_TCP_KEEPALIVE_INTERVAL, DFLT_TCP_KEEPALIVE_INTERVAL); PutInt(NAME_TCP_KEEPALIVE_PROBES, DFLT_TCP_KEEPALIVE_PROBES); PutInt(NAME_XRDCP_SIZE_HINT, DFLT_XRDCP_SIZE_HINT); PutInt(NAME_PRINT_REDIRECTS, DFLT_PRINT_REDIRECTS); ImportInt( NAME_CONNECTTIMEOUT ); ImportInt( NAME_REQUESTTIMEOUT ); ImportInt( NAME_MAXREDIRECTCOUNT ); ImportInt( NAME_DEBUG ); ImportInt( NAME_RECONNECTWAIT ); ImportInt( NAME_REDIRCNTTIMEOUT ); ImportInt( NAME_FIRSTCONNECTMAXCNT ); ImportInt( NAME_READCACHESIZE ); ImportInt( NAME_READCACHEBLKREMPOLICY ); ImportInt( NAME_READAHEADSIZE ); ImportInt( NAME_MULTISTREAMCNT ); ImportInt( NAME_DFLTTCPWINDOWSIZE ); ImportInt( NAME_DATASERVERCONN_TTL ); ImportInt( NAME_LBSERVERCONN_TTL ); ImportInt( NAME_PURGEWRITTENBLOCKS ); ImportInt( NAME_READAHEADSTRATEGY ); ImportInt( NAME_READTRIMBLKSZ ); ImportInt( NAME_TRANSACTIONTIMEOUT ); ImportInt( NAME_REMUSEDCACHEBLKS ); ImportInt( NAME_ENABLE_FORK_HANDLERS ); ImportInt( NAME_ENABLE_TCP_KEEPALIVE ); ImportInt( NAME_TCP_KEEPALIVE_TIME ); ImportInt( NAME_TCP_KEEPALIVE_INTERVAL ); ImportInt( NAME_TCP_KEEPALIVE_PROBES ); ImportInt( NAME_XRDCP_SIZE_HINT ); ImportInt( NAME_PRINT_REDIRECTS ); } //------------------------------------------------------------------------------ // Import a string variable from the shell environment //------------------------------------------------------------------------------ bool XrdClientEnv::ImportStr( const char *varname ) { std::string name = "XRD_"; name += varname; std::transform( name.begin(), name.end(), name.begin(), ::toupper ); char *value; if( !XrdOucEnv::Import( name.c_str(), value ) ) return false; fShellEnv->Put( varname, value ); return true; } //------------------------------------------------------------------------------ // Import an int variable from the shell environment //------------------------------------------------------------------------------ bool XrdClientEnv::ImportInt( const char *varname ) { std::string name = "XRD_"; name += varname; std::transform( name.begin(), name.end(), name.begin(), ::toupper ); long value; if( !XrdOucEnv::Import( name.c_str(), value ) ) return false; fShellEnv->PutInt( varname, value ); return true; } //------------------------------------------------------------------------------ // Get a string from the shell environment //------------------------------------------------------------------------------ const char *XrdClientEnv::ShellGet(const char *varname) { XrdSysMutexHelper m( fMutex ); const char *res = fShellEnv->Get( varname ); if( res ) return res; res = fOucEnv->Get( varname ); return res; } //------------------------------------------------------------------------------ // Get an integer from the shell environment //------------------------------------------------------------------------------ long XrdClientEnv::ShellGetInt(const char *varname) { XrdSysMutexHelper m( fMutex ); const char *res = fShellEnv->Get( varname ); if( res ) return fShellEnv->GetInt( varname ); return fOucEnv->GetInt( varname ); } //_____________________________________________________________________________ XrdClientEnv::~XrdClientEnv() { // Destructor delete fOucEnv; delete fShellEnv; delete fgInstance; fgInstance = 0; } //------------------------------------------------------------------------------ // The fork handlers need to have C linkage (no symbol name mangling) //------------------------------------------------------------------------------ extern "C" { //------------------------------------------------------------------------------ // To be called prior to forking //------------------------------------------------------------------------------ static void prepare() { if( EnvGetLong( NAME_ENABLE_FORK_HANDLERS ) && ConnectionManager ) { ConnectionManager->ShutDown(); XrdClientConn::DelSessionIDRepo(); } XrdClientEnv::Instance()->Lock(); } //------------------------------------------------------------------------------ // To be called in the parent just after forking //------------------------------------------------------------------------------ static void parent() { XrdClientEnv::Instance()->UnLock(); if( EnvGetLong( NAME_ENABLE_FORK_HANDLERS ) && ConnectionManager ) { ConnectionManager->BootUp(); } } //------------------------------------------------------------------------------ // To be called in the child just after forking //------------------------------------------------------------------------------ static void child() { XrdClientEnv::Instance()->ReInitLock(); if( EnvGetLong( NAME_ENABLE_FORK_HANDLERS ) && ConnectionManager ) { ConnectionManager->BootUp(); } } } // extern "C" //------------------------------------------------------------------------------ // Install the fork handlers on application startup and set IPV4 mode //------------------------------------------------------------------------------ namespace { static struct Initializer { Initializer() { //------------------------------------------------------------------------ // Install the fork handlers //------------------------------------------------------------------------ #ifndef WIN32 if( pthread_atfork( prepare, parent, child ) != 0 ) { std::cerr << "Unable to install the fork handlers - safe forking not "; std::cerr << "possible" << std::endl; } #endif } } initializer; }