Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/xrootd/xrootd into fix-sy…
Browse files Browse the repository at this point in the history
…mbol-export
  • Loading branch information
djw8605 committed Dec 15, 2020
2 parents e34f07b + d34424c commit 56c4e58
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 31 deletions.
11 changes: 1 addition & 10 deletions src/XrdCl/XrdClCtx.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace XrdCl
//-------------------------------------------------------------------------
//! Default constructor
//-------------------------------------------------------------------------
Ctx()
Ctx() : std::shared_ptr<T*>( std::make_shared<T*>() )
{
}

Expand Down Expand Up @@ -89,15 +89,6 @@ namespace XrdCl
return *this;
}

//-------------------------------------------------------------------------
//! Move assignment operator
//-------------------------------------------------------------------------
Ctx& operator=( Ctx && ctx )
{
swap( ctx );
return *this;
}

//------------------------------------------------------------------------
//! Dereferencing operator. Note if Ctx is a null-reference this will
//! trigger an exception
Expand Down
43 changes: 41 additions & 2 deletions src/XrdCl/XrdClParallelOperation.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "XrdCl/XrdClOperationHandlers.hh"

#include <atomic>
#include <condition_variable>
#include <mutex>

namespace XrdCl
{
Expand Down Expand Up @@ -105,6 +107,10 @@ namespace XrdCl
container.clear(); // there's junk inside so we clear it
}

~ParallelOperation()
{
}

//------------------------------------------------------------------------
//! @return : operation name
//------------------------------------------------------------------------
Expand Down Expand Up @@ -283,6 +289,31 @@ namespace XrdCl
const size_t threshold;
};

//------------------------------------------------------------------------
//! A wait barrier helper class
//------------------------------------------------------------------------
struct barrier_t
{
barrier_t() : on( true ) { }

void wait()
{
std::unique_lock<std::mutex> lck( mtx );
if( on ) cv.wait( lck );
}

void lift()
{
on = false;
cv.notify_all();
}

private:
std::condition_variable cv;
std::mutex mtx;
bool on;
};

//------------------------------------------------------------------------
//! Helper class for handling the PipelineHandler of the
//! ParallelOperation (RAII).
Expand Down Expand Up @@ -331,7 +362,10 @@ namespace XrdCl
{
PipelineHandler* hdlr = handler.exchange( nullptr );
if( hdlr )
{
barrier.wait();
hdlr->HandleResponse( new XRootDStatus( st ), nullptr );
}
}

//----------------------------------------------------------------------
Expand All @@ -343,6 +377,12 @@ namespace XrdCl
//! Policy defining when the user handler should be called
//----------------------------------------------------------------------
std::unique_ptr<PolicyExecutor> policy;

//----------------------------------------------------------------------
//! wait barrier that assures handler is called only after RunImpl
//! started all pipelines
//----------------------------------------------------------------------
barrier_t barrier;
};

//------------------------------------------------------------------------
Expand All @@ -364,10 +404,9 @@ namespace XrdCl
pipelineTimeout : this->timeout;

for( size_t i = 0; i < pipelines.size(); ++i )
{
pipelines[i].Run( timeout, [ctx]( const XRootDStatus &st ){ ctx->Examine( st ); } );
}

ctx->barrier.lift();
return XRootDStatus();
}

Expand Down
39 changes: 20 additions & 19 deletions src/XrdPfc/XrdPfc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -134,46 +134,46 @@ struct TmpConfiguration

struct SplitParser
{
char *str;
const char *delim;
char *state;
bool first;
char *f_str;
const char *f_delim;
char *f_state;
bool f_first;

SplitParser(const std::string &s, const char *d) :
str(strdup(s.c_str())), delim(d), state(0), first(true)
f_str(strdup(s.c_str())), f_delim(d), f_state(0), f_first(true)
{}
~SplitParser() { free(str); }
~SplitParser() { free(f_str); }

char* get_token()
{
if (first) { first = false; return strtok_r(str, delim, &state); }
else { return strtok_r(0, delim, &state); }
if (f_first) { f_first = false; return strtok_r(f_str, f_delim, &f_state); }
else { return strtok_r(0, f_delim, &f_state); }
}

char* get_reminder_with_delim()
{
if (first) { return str; }
else { *(state - 1) = delim[0]; return state - 1; }
if (f_first) { return f_str; }
else { *(f_state - 1) = f_delim[0]; return f_state - 1; }
}

char *get_reminder()
{
return first ? str : state;
return f_first ? f_str : f_state;
}

int fill_argv(std::vector<char*> &argv)
{
if (!first) return 0;
int dcnt = 0; { char *p = str; while (*p) { if (*(p++) == delim[0]) ++dcnt; } }
if (!f_first) return 0;
int dcnt = 0; { char *p = f_str; while (*p) { if (*(p++) == f_delim[0]) ++dcnt; } }
argv.reserve(dcnt + 1);
int argc = 0;
char *i = strtok_r(str, delim, &state);
char *i = strtok_r(f_str, f_delim, &f_state);
while (i)
{
++argc;
argv.push_back(i);
// printf(" arg %d : '%s'\n", argc, i);
i = strtok_r(0, delim, &state);
i = strtok_r(0, f_delim, &f_state);
}
return argc;
}
Expand All @@ -187,10 +187,11 @@ struct PathTokenizer : private SplitParser

PathTokenizer(const std::string &path, int max_depth, bool parse_as_lfn) :
SplitParser(path, "/"),
m_reminder (0)
m_reminder (0),
m_n_dirs (0)
{
// If parse_as_lfn is true store final token into reminder, regardless of maxdepth.
// This assumes the last token is a file name (and full path if lfn, including the file name).
// If parse_as_lfn is true store final token into m_reminder, regardless of maxdepth.
// This assumes the last token is a file name (and full path is lfn, including the file name).

m_dirs.reserve(max_depth);

Expand All @@ -201,7 +202,7 @@ struct PathTokenizer : private SplitParser
if (t == 0) break;
m_dirs.emplace_back(t);
}
if (parse_as_lfn && (t == 0 || * get_reminder() == 0))
if (parse_as_lfn && *get_reminder() == 0 && ! m_dirs.empty())
{
m_reminder = m_dirs.back();
m_dirs.pop_back();
Expand Down

0 comments on commit 56c4e58

Please sign in to comment.