-
Notifications
You must be signed in to change notification settings - Fork 149
/
XrdClRedirectorRegistry.cc
156 lines (134 loc) · 4.51 KB
/
XrdClRedirectorRegistry.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
* XrdClRedirectorRegister.cc
*
* Created on: May 23, 2016
* Author: simonm
*/
#include "XrdClRedirectorRegistry.hh"
#include "XrdCl/XrdClMetalinkRedirector.hh"
#include "XrdCl/XrdClPostMasterInterfaces.hh"
#include "XrdCl/XrdClDefaultEnv.hh"
#include "XrdCl/XrdClConstants.hh"
#include "XrdCl/XrdClLog.hh"
#include <arpa/inet.h>
namespace XrdCl
{
void RedirectJob::Run( void *arg )
{
Message *msg = reinterpret_cast<Message*>( arg );
// this makes sure the handler takes ownership of the new message
if( pHandler->Examine( msg ) != IncomingMsgHandler::Action::Ignore )
pHandler->Process( msg );
delete this;
}
RedirectorRegistry& RedirectorRegistry::Instance()
{
static RedirectorRegistry redirector;
return redirector;
}
RedirectorRegistry::~RedirectorRegistry()
{
RedirectorMap::iterator itr;
for( itr = pRegistry.begin(); itr != pRegistry.end(); ++itr )
delete itr->second.first;
}
XRootDStatus RedirectorRegistry::RegisterImpl( const URL &u, ResponseHandler *handler )
{
URL url = ConvertLocalfile( u );
// we can only create a virtual redirector if
// a path to a metadata file has been provided
if( url.GetPath().empty() ) return XRootDStatus( stError, errNotSupported );
// regarding file protocol we only support localhost
if( url.GetProtocol() == "file" && url.GetHostName() != "localhost" )
return XRootDStatus( stError, errNotSupported );
XrdSysMutexHelper scopedLock( pMutex );
// get the key and check if it is already in the registry
const std::string key = url.GetLocation();
RedirectorMap::iterator itr = pRegistry.find( key );
if( itr != pRegistry.end() )
{
// increment user counter
++itr->second.second;
if( handler ) handler->HandleResponseWithHosts( new XRootDStatus(), 0, 0 );
return XRootDStatus( stOK, suAlreadyDone );
}
// If it is a Metalink create a MetalinkRedirector
if( url.IsMetalink() )
{
MetalinkRedirector *redirector = new MetalinkRedirector( key );
XRootDStatus st = redirector->Load( handler );
if( !st.IsOK() )
delete redirector;
else
pRegistry[key] = std::pair<VirtualRedirector*, size_t>( redirector, 1 );
return st;
}
else
// so far we only support Metalink metadata format
return XRootDStatus( stError, errNotSupported );
}
URL RedirectorRegistry::ConvertLocalfile( const URL &url )
{
int localml = DefaultLocalMetalinkFile;
DefaultEnv::GetEnv()->GetInt( "LocalMetalinkFile", localml );
if( localml && url.GetProtocol() == "root" && url.GetHostName() == "localfile" )
{
Log *log = DefaultEnv::GetLog();
log->Warning( PostMasterMsg,
"Please note that the 'root://localfile//path/filename.meta4' "
"semantic is now deprecated, use 'file://localhost/path/filename.meta4'"
"instead!" );
URL copy( url );
copy.SetHostName( "localhost" );
copy.SetProtocol( "file" );
return copy;
}
return url;
}
XRootDStatus RedirectorRegistry::Register( const URL &url )
{
return RegisterImpl( url, 0 );
}
XRootDStatus RedirectorRegistry::RegisterAndWait( const URL &url )
{
SyncResponseHandler handler;
Status st = RegisterImpl( url, &handler );
if( !st.IsOK() ) return st;
return MessageUtils::WaitForStatus( &handler );
}
VirtualRedirector* RedirectorRegistry::Get( const URL &u ) const
{
URL url = ConvertLocalfile( u );
XrdSysMutexHelper scopedLock( pMutex );
// get the key and return the value if it is in the registry
// offset 24 is where the path has been stored
const std::string key = url.GetLocation();
RedirectorMap::const_iterator itr = pRegistry.find( key );
if( itr != pRegistry.end() )
return itr->second.first;
// otherwise return null
return 0;
}
//----------------------------------------------------------------------------
// Release the virtual redirector associated with the given URL
//----------------------------------------------------------------------------
void RedirectorRegistry::Release( const URL &u )
{
URL url = ConvertLocalfile( u );
XrdSysMutexHelper scopedLock( pMutex );
// get the key and return the value if it is in the registry
// offset 24 is where the path has been stored
const std::string key = url.GetLocation();
RedirectorMap::iterator itr = pRegistry.find( key );
if( itr == pRegistry.end() ) return;
// decrement user counter
--itr->second.second;
// if nobody is using it delete the object
// and remove it from the registry
if( !itr->second.second )
{
delete itr->second.first;
pRegistry.erase( itr );
}
}
} /* namespace XrdCl */