Skip to content

Commit

Permalink
[XrdCl] Fix a very rare segfault when forking under heavy load
Browse files Browse the repository at this point in the history
  • Loading branch information
ljanyst committed Nov 18, 2013
1 parent ec2ca4c commit 429f1c8
Showing 1 changed file with 80 additions and 39 deletions.
119 changes: 80 additions & 39 deletions src/XrdCl/XrdClPollerBuiltIn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ namespace XrdCl

Log *log = DefaultEnv::GetLog();
log->Debug( PollerMsg, "Creating and starting the built-in poller..." );
XrdSysMutexHelper scopedLock( pMutex );
int errNum = 0;
const char *errMsg = 0;
pPoller = IOEvents::Poller::Create( errNum, &errMsg );
Expand All @@ -145,7 +146,6 @@ namespace XrdCl
{
PollerHelper *helper = (PollerHelper*)it->second;
Socket *socket = it->first;
delete helper->channel;
helper->channel = new IOEvents::Channel( pPoller, socket->GetFD(),
helper->callBack );
if( helper->readEnabled )
Expand Down Expand Up @@ -182,8 +182,29 @@ namespace XrdCl
//------------------------------------------------------------------------
bool PollerBuiltIn::Stop()
{
using namespace XrdSys::IOEvents;

Log *log = DefaultEnv::GetLog();
log->Debug( PollerMsg, "Stopping the poller..." );
XrdSysMutexHelper scopedLock( pMutex );

SocketMap::iterator it;
const char *errMsg = 0;

for( it = pSocketMap.begin(); it != pSocketMap.end(); ++it )
{
PollerHelper *helper = (PollerHelper*)it->second;
Socket *socket = it->first;
bool status = helper->channel->Disable( Channel::allEvents, &errMsg );
if( !status )
{
log->Error( PollerMsg, "%s Unable to disable write notifications: %s",
socket->GetName().c_str(), errMsg );
}
delete helper->channel;
helper->channel = 0;
}

if( !pPoller )
{
log->Debug( PollerMsg, "Stopping a poller that has not been started" );
Expand All @@ -194,7 +215,6 @@ namespace XrdCl
delete pPoller;
pPoller = 0;


return true;
}

Expand Down Expand Up @@ -238,9 +258,14 @@ namespace XrdCl
//--------------------------------------------------------------------------
PollerHelper *helper = new PollerHelper();
helper->callBack = new ::SocketCallBack( socket, handler );
helper->channel = new XrdSys::IOEvents::Channel( pPoller,
socket->GetFD(),
helper->callBack );

if( pPoller )
{
helper->channel = new XrdSys::IOEvents::Channel( pPoller,
socket->GetFD(),
helper->callBack );
}

handler->Initialize( this );
pSocketMap[socket] = helper;
return true;
Expand Down Expand Up @@ -269,15 +294,18 @@ namespace XrdCl
// Remove the socket
//--------------------------------------------------------------------------
PollerHelper *helper = (PollerHelper*)it->second;
const char *errMsg;
bool status = helper->channel->Disable( Channel::allEvents, &errMsg );
if( !status )
if( pPoller )
{
log->Error( PollerMsg, "%s Unable to disable write notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
const char *errMsg;
bool status = helper->channel->Disable( Channel::allEvents, &errMsg );
if( !status )
{
log->Error( PollerMsg, "%s Unable to disable write notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
}
delete helper->channel;
}
delete helper->channel;
delete helper->callBack;
delete helper;
pSocketMap.erase( it );
Expand Down Expand Up @@ -325,16 +353,19 @@ namespace XrdCl

log->Dump( PollerMsg, "%s Enable read notifications, timeout: %d",
socket->GetName().c_str(), timeout );
const char *errMsg;
bool status = helper->channel->Enable( Channel::readEvents, timeout,
&errMsg );
if( !status )

if( pPoller )
{
log->Error( PollerMsg, "%s Unable to enable read notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
const char *errMsg;
bool status = helper->channel->Enable( Channel::readEvents, timeout,
&errMsg );
if( !status )
{
log->Error( PollerMsg, "%s Unable to enable read notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
}
}

helper->readEnabled = true;
}

Expand All @@ -348,13 +379,17 @@ namespace XrdCl

log->Dump( PollerMsg, "%s Disable read notifications",
socket->GetName().c_str() );
const char *errMsg;
bool status = helper->channel->Disable( Channel::readEvents, &errMsg );
if( !status )

if( pPoller )
{
log->Error( PollerMsg, "%s Unable to disable read notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
const char *errMsg;
bool status = helper->channel->Disable( Channel::readEvents, &errMsg );
if( !status )
{
log->Error( PollerMsg, "%s Unable to disable read notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
}
}
helper->readEnabled = false;
}
Expand Down Expand Up @@ -404,14 +439,17 @@ namespace XrdCl
log->Dump( PollerMsg, "%s Enable write notifications, timeout: %d",
socket->GetName().c_str(), timeout );

const char *errMsg;
bool status = helper->channel->Enable( Channel::writeEvents, timeout,
&errMsg );
if( !status )
if( pPoller )
{
log->Error( PollerMsg, "%s Unable to enable write notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
const char *errMsg;
bool status = helper->channel->Enable( Channel::writeEvents, timeout,
&errMsg );
if( !status )
{
log->Error( PollerMsg, "%s Unable to enable write notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
}
}
helper->writeEnabled = true;
}
Expand All @@ -426,13 +464,16 @@ namespace XrdCl

log->Dump( PollerMsg, "%s Disable write notifications",
socket->GetName().c_str() );
const char *errMsg;
bool status = helper->channel->Disable( Channel::writeEvents, &errMsg );
if( !status )
if( pPoller )
{
log->Error( PollerMsg, "%s Unable to disable write notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
const char *errMsg;
bool status = helper->channel->Disable( Channel::writeEvents, &errMsg );
if( !status )
{
log->Error( PollerMsg, "%s Unable to disable write notifications: %s",
socket->GetName().c_str(), errMsg );
return false;
}
}
helper->writeEnabled = false;
}
Expand Down

0 comments on commit 429f1c8

Please sign in to comment.