Skip to content

Commit

Permalink
[XrdCl] Ensure DefaultEnv is finalized after last use of the object.
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmichal committed Jul 7, 2016
1 parent 8c6d738 commit 5bc8bb3
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 99 deletions.
203 changes: 104 additions & 99 deletions src/XrdCl/XrdClDefaultEnv.cc
Expand Up @@ -46,6 +46,88 @@

XrdVERSIONINFO( XrdCl, client );

//------------------------------------------------------------------------------
// Forking functions
//------------------------------------------------------------------------------
extern "C"
{
//----------------------------------------------------------------------------
// Prepare for the forking
//----------------------------------------------------------------------------
static void prepare()
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
Env *env = DefaultEnv::GetEnv();
ForkHandler *forkHandler = DefaultEnv::GetForkHandler();

log->Debug( UtilityMsg, "In the prepare fork handler for process %d",
getpid() );

//--------------------------------------------------------------------------
// Run the fork handler if it's enabled
//--------------------------------------------------------------------------
int runForkHandler = DefaultRunForkHandler;
env->GetInt( "RunForkHandler", runForkHandler );
if( runForkHandler )
forkHandler->Prepare();
env->WriteLock();
}

//----------------------------------------------------------------------------
// Parent handler
//----------------------------------------------------------------------------
static void parent()
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
Env *env = DefaultEnv::GetEnv();
ForkHandler *forkHandler = DefaultEnv::GetForkHandler();
env->UnLock();

pid_t pid = getpid();
log->Debug( UtilityMsg, "In the parent fork handler for process %d", pid );

//--------------------------------------------------------------------------
// Run the fork handler if it's enabled
//--------------------------------------------------------------------------
int runForkHandler = DefaultRunForkHandler;
env->GetInt( "RunForkHandler", runForkHandler );
if( runForkHandler )
{
log->SetPid(pid);
forkHandler->Parent();
}
}

//----------------------------------------------------------------------------
// Child handler
//----------------------------------------------------------------------------
static void child()
{
using namespace XrdCl;
DefaultEnv::ReInitializeLogging();
Log *log = DefaultEnv::GetLog();
Env *env = DefaultEnv::GetEnv();
ForkHandler *forkHandler = DefaultEnv::GetForkHandler();
env->ReInitializeLock();

pid_t pid = getpid();
log->Debug( UtilityMsg, "In the child fork handler for process %d", pid );

//--------------------------------------------------------------------------
// Run the fork handler if it's enabled
//--------------------------------------------------------------------------
int runForkHandler = DefaultRunForkHandler;
env->GetInt( "RunForkHandler", runForkHandler );
if( runForkHandler )
{
log->SetPid(pid);
forkHandler->Child();
}
}
}

namespace
{
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -303,6 +385,11 @@ namespace XrdCl
std::transform( name.begin(), name.end(), name.begin(), ::toupper );
ImportString( varsStr[i].name, name );
}

//--------------------------------------------------------------------------
// Register fork handlers
//--------------------------------------------------------------------------
pthread_atfork( prepare, parent, child );
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -728,111 +815,29 @@ namespace XrdCl
}
}


//------------------------------------------------------------------------------
// Forking functions
// Static initialization and finalization
//------------------------------------------------------------------------------
extern "C"
{
//----------------------------------------------------------------------------
// Prepare for the forking
//----------------------------------------------------------------------------
static void prepare()
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
Env *env = DefaultEnv::GetEnv();
ForkHandler *forkHandler = DefaultEnv::GetForkHandler();

log->Debug( UtilityMsg, "In the prepare fork handler for process %d",
getpid() );

//--------------------------------------------------------------------------
// Run the fork handler if it's enabled
//--------------------------------------------------------------------------
int runForkHandler = DefaultRunForkHandler;
env->GetInt( "RunForkHandler", runForkHandler );
if( runForkHandler )
forkHandler->Prepare();
env->WriteLock();
}

//----------------------------------------------------------------------------
// Parent handler
//----------------------------------------------------------------------------
static void parent()
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
Env *env = DefaultEnv::GetEnv();
ForkHandler *forkHandler = DefaultEnv::GetForkHandler();
env->UnLock();

pid_t pid = getpid();
log->Debug( UtilityMsg, "In the parent fork handler for process %d", pid );

//--------------------------------------------------------------------------
// Run the fork handler if it's enabled
//--------------------------------------------------------------------------
int runForkHandler = DefaultRunForkHandler;
env->GetInt( "RunForkHandler", runForkHandler );
if( runForkHandler )
{
log->SetPid(pid);
forkHandler->Parent();
}
}
int EnvInitializer::counter = 0;

//----------------------------------------------------------------------------
// Child handler
//----------------------------------------------------------------------------
static void child()
{
using namespace XrdCl;
DefaultEnv::ReInitializeLogging();
Log *log = DefaultEnv::GetLog();
Env *env = DefaultEnv::GetEnv();
ForkHandler *forkHandler = DefaultEnv::GetForkHandler();
env->ReInitializeLock();

pid_t pid = getpid();
log->Debug( UtilityMsg, "In the child fork handler for process %d", pid );

//--------------------------------------------------------------------------
// Run the fork handler if it's enabled
//--------------------------------------------------------------------------
int runForkHandler = DefaultRunForkHandler;
env->GetInt( "RunForkHandler", runForkHandler );
if( runForkHandler )
{
log->SetPid(pid);
forkHandler->Child();
}
}
//------------------------------------------------------------------------------
// The constructor will be invoked in every translation unit
// that includes XrdClDefaultEnv.hh, but the DefaultEnv will
// be initialized only in the first one
//------------------------------------------------------------------------------
EnvInitializer::EnvInitializer ()
{
if( counter++ == 0 ) XrdCl::DefaultEnv::Initialize();
}

//------------------------------------------------------------------------------
// Static initialization and finalization
// The destructor will be invoked in every translation unit
// that includes XrdClDefaultEnv.hh, but the DefaultEnv will
// be finalized only once in the last one
//------------------------------------------------------------------------------
namespace
EnvInitializer::~EnvInitializer ()
{

static struct EnvInitializer
{
//--------------------------------------------------------------------------
// Initializer
//--------------------------------------------------------------------------
EnvInitializer()
{
XrdCl::DefaultEnv::Initialize();
pthread_atfork( prepare, parent, child );
}

//--------------------------------------------------------------------------
// Finalizer
//--------------------------------------------------------------------------
~EnvInitializer()
{
XrdCl::DefaultEnv::Finalize();
}
} finalizer;
if( --counter == 0 ) XrdCl::DefaultEnv::Finalize();
}

7 changes: 7 additions & 0 deletions src/XrdCl/XrdClDefaultEnv.hh
Expand Up @@ -173,4 +173,11 @@ namespace XrdCl
};
}

static struct EnvInitializer
{
EnvInitializer();
~EnvInitializer();
static int counter;
} initializer;

#endif // __XRD_CL_DEFAULT_ENV_HH__

0 comments on commit 5bc8bb3

Please sign in to comment.