Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify cint root mutex #14

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
7ac7b02
Clean up the way externals are picked up.
ktf Feb 26, 2014
ef0cc3e
Silence roofit banner.
ktf Feb 26, 2014
3cd5017
Specify gnu hash style.
ktf Feb 26, 2014
5b06a25
Correct platform detection on mac.
ktf Feb 26, 2014
606e243
Silence warnings.
ktf Feb 26, 2014
6d13b44
Use correct isnan.
ktf Feb 26, 2014
1b092e4
Fix trampolines for ARM.
ktf Feb 26, 2014
2e422ce
Thread-safe determination of TObject::IsOnHeap()
Dr15Jones Jan 13, 2014
b22c22f
Removed use of TStorage::IsOnHeap
Dr15Jones Jan 13, 2014
e514c79
Made TClass::fgCallingNew a thread_local file scope static
Dr15Jones Jan 20, 2014
f9d1a25
Don't reset global in TClass::New
Dr15Jones Dec 31, 2013
4627669
Support for C++11 in ARM builds
ktf Feb 26, 2014
7925282
Merge pull request #3 from ktf/import-cms-patches
ktf Feb 26, 2014
6001a66
Fast and dirty version of setting special value in TObject::new
Dr15Jones Jan 13, 2014
7d65924
Cleaned up TStorage changes
Dr15Jones Jan 13, 2014
f1f9d3b
Encapsulate check on alloc in TStorage::FilledByObjectAlloc
Dr15Jones Jan 15, 2014
d7e3e1b
Added suppression entries for determining if TObject on heap
Dr15Jones Jan 15, 2014
90ab19a
Make variable used for GUID of TKeys atomic
Dr15Jones Jan 28, 2014
3b1874a
Protect Cintex structure with mutex
Dr15Jones Jan 30, 2014
11b1179
Make zip globals thread local
Dr15Jones Jan 30, 2014
6517b5e
Protect access to TROOT::GetListOfFiles()
Dr15Jones Feb 1, 2014
e2251f6
Protected threaded access to TClass::GetStreamerInfos()
Dr15Jones Feb 1, 2014
bf04e1c
Thread safe caching of TStreamerInfo in TBranchSTL
Dr15Jones Feb 1, 2014
a5752af
Only set TStreamerInfo to unoptimized if it is optimized
Dr15Jones Feb 1, 2014
0f9bbe8
Fix threading issues in TClass
Dr15Jones Feb 1, 2014
bb39bbc
Made TPluginManager thread-safe for I/O
Dr15Jones Feb 3, 2014
c417108
Mutex lock removed from TStorage::ObjectDealloc to avoid deadlocks
Dr15Jones Feb 3, 2014
c9698f7
Use thread_local for statics in TUUID
Dr15Jones Feb 3, 2014
ed8dba6
Fix thread-safety issues with TError
Dr15Jones Feb 3, 2014
8bd0dcb
Use gCINTMutex to protect access to G__getgvp
Dr15Jones Feb 3, 2014
ae1d5e8
Use gCINTMutex to protect access to TBaseClass::Property
Dr15Jones Feb 3, 2014
6f5e0a0
Fix thread-safety problems with cleanup of containers
Dr15Jones Feb 3, 2014
545c70e
Fix thread-safety issues of StreamerInfos
Dr15Jones Feb 3, 2014
ecbe8cc
Made gTree thread_local
Dr15Jones Feb 3, 2014
551a92c
Properly avoid repeated calls to TStreamerInfo::Build*
Dr15Jones Feb 5, 2014
25d5ea5
Added additional locks in TClass to protect CINT data structures
Dr15Jones Feb 5, 2014
8ff03b1
Made TROOT ReadingObject methods thread safe
Dr15Jones Feb 5, 2014
15d51d1
Made global counters in TFile atomic
Dr15Jones Feb 5, 2014
40ebff6
Used std::atomic to protect TStreamerInfo counters
Dr15Jones Feb 5, 2014
fba383e
Use std::atomic to protect access to TClass state
Dr15Jones Feb 5, 2014
6659ee5
Need to reset kBuildOldUsed bit when reading TStreamerInfo
Dr15Jones Feb 7, 2014
8e6ccdd
Need to use CINT mutex in Cintex::Callback::operator()
Dr15Jones Feb 12, 2014
ea025ac
Minimize the time spent holding the Cintex mutex lock
Dr15Jones Feb 12, 2014
865a401
Make last error string in TSystem a thread_local
Dr15Jones Feb 13, 2014
48a6405
Thread safety fixes for TUnixSystem
Dr15Jones Feb 13, 2014
371da00
Use Mutex to protect gObjectVersionRepository
Dr15Jones Feb 13, 2014
7033522
TStreamerElement cached strings changed to thread_local
Dr15Jones Feb 13, 2014
049ebd7
Fix thread-safety issues with string formating
Dr15Jones Feb 13, 2014
dde43fd
fgIsA needs to be thread safe
Dr15Jones Feb 13, 2014
0266347
Fix caching bug in ROOTClassEnhancer::IsA
Dr15Jones Feb 13, 2014
44e5441
Avoid holding gCINTMutex and gROOTMutex simultaneously in TPluginManager
Dr15Jones Feb 13, 2014
7f9948f
Merge pull request #4 from ktf/fix-mt-io
ktf Feb 26, 2014
9524f6c
Worked around ambiguity in C++ for fgIsA and std::atomic<>
Dr15Jones Feb 27, 2014
705062d
Merge pull request #5 from Dr15Jones/fixGenreflexProblemWithfgIsA
ktf Feb 27, 2014
b262c2c
Revert "Fix trampolines for ARM."
ktf Feb 28, 2014
1c5a843
Merge pull request #6 from ktf/remove-arm-fix
ktf Feb 28, 2014
814e69c
Make gCintMutex and gROOTMutex use the same mutex
Dr15Jones Mar 20, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cint/cintex/src/Cintex.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <iostream>

#include "TROOT.h"
#include "TInterpreter.h" //gCINTMutex
#include "TVirtualMutex.h"

using namespace ROOT::Reflex;
using namespace ROOT::Cintex;
Expand Down Expand Up @@ -187,6 +189,7 @@ namespace ROOT {
}

void Callback::operator () ( const Type& t ) {
R__LOCKGUARD2(gCINTMutex);
ArtificialSourceFile asf;
int autoload = G__set_class_autoloading(0); // To avoid recursive loads
if ( t.IsClass() || t.IsStruct() ) {
Expand All @@ -205,6 +208,7 @@ namespace ROOT {
}

void Callback::operator () ( const Member& m ) {
R__LOCKGUARD2(gCINTMutex);
ArtificialSourceFile asf;
int autoload = G__set_class_autoloading(0); // To avoid recursive loads
if ( m.IsFunctionMember() ) {
Expand Down
68 changes: 45 additions & 23 deletions cint/cintex/src/ROOTClassEnhancer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "TClassStreamer.h"
#include "TCollectionProxyInfo.h"
#include "TVirtualCollectionProxy.h"
#include "TVirtualMutex.h"
#include "TMemberInspector.h"
#include "RVersion.h"
#include "Reflex/Reflex.h"
Expand All @@ -35,6 +36,9 @@
#include <sstream>
#include <memory>
#include <string>
#if __cplusplus > 199711L
#include <atomic>
#endif

#if ROOT_VERSION_CODE >= ROOT_VERSION(5,1,1)
#include "TVirtualIsAProxy.h"
Expand All @@ -44,6 +48,8 @@ using namespace ROOT::Reflex;
using namespace ROOT::Cintex;
using namespace std;

static TVirtualMutex* gCintexMutex = 0;

namespace ROOT { namespace Cintex {

class IsAProxy;
Expand All @@ -52,7 +58,11 @@ namespace ROOT { namespace Cintex {

Type fType;
string fName;
#if __cplusplus > 199711L
std::atomic<TClass*> fTclass;
#else
TClass* fTclass;
#endif
TClass* fLastClass;
std::map<const std::type_info*,TClass*> fSub_types;
const std::type_info* fLastType;
Expand Down Expand Up @@ -174,7 +184,10 @@ namespace ROOT { namespace Cintex {
// Constructor.
fType = CleanType(t);
fName = CintName(fType);
rootEnhancerInfos().push_back(this);
{
R__LOCKGUARD2(gCintexMutex);
rootEnhancerInfos().push_back(this);
}
fMyType = &t.TypeInfo();
fIsVirtual = TypeGet().IsVirtual();
fClassInfo = 0;
Expand Down Expand Up @@ -361,37 +374,46 @@ namespace ROOT { namespace Cintex {
if ( ! obj || ! fIsVirtual ) {
return Tclass();
}
else {
// Avoid the case that the first word is a virtual_base_offset_table instead of
// a virtual_function_table
long Offset = **(long**)obj;
if ( Offset == 0 ) return Tclass();

DynamicStruct_t* p = (DynamicStruct_t*)obj;
const std::type_info& typ = typeid(*p);
// Avoid the case that the first word is a virtual_base_offset_table instead of
// a virtual_function_table
long Offset = **(long**)obj;
if ( Offset == 0 ) return Tclass();

if ( &typ == fMyType ) {
return Tclass();
}
else if ( &typ == fLastType ) {
DynamicStruct_t* p = (DynamicStruct_t*)obj;
const std::type_info& typ = typeid(*p);

if ( &typ == fMyType ) {
return Tclass();
}
{
R__LOCKGUARD2(gCintexMutex);
if ( &typ == fLastType ) {
return fLastClass;
}

// Check if TypeNth is already in sub-class cache
else if ( 0 != (fLastClass=fSub_types[&typ]) ) {
TClass* findClass = fSub_types[&typ];
if ( 0 != findClass ) {
fLastClass = findClass;
fLastType = &typ;
return fLastClass;
}
// Last resort: lookup root class
else {
std::string nam;
Type t = Type::ByTypeInfo(typ);
if (t) nam = CintName(t);
else nam = CintName(Tools::Demangle(typ));
fLastClass = ROOT::GetROOT()->GetClass(nam.c_str());
fSub_types[fLastType=&typ] = fLastClass;
}
}
// Last resort: lookup root class
TClass* returnValue;
std::string nam;
Type t = Type::ByTypeInfo(typ);
if (t) nam = CintName(t);
else nam = CintName(Tools::Demangle(typ));
returnValue = ROOT::GetROOT()->GetClass(nam.c_str());
{
R__LOCKGUARD2(gCintexMutex);
fLastClass = returnValue;
fSub_types[fLastType=&typ] = fLastClass;
}
//std::cout << "Cintex: IsA:" << TypeNth.Name(SCOPED) << " dynamic:" << dtype.Name(SCOPED) << std::endl;
return fLastClass;
return returnValue;
}

TClass* ROOTClassEnhancerInfo::Default_CreateClass( Type typ, ROOT::TGenericClassInfo* info) {
Expand Down
15 changes: 12 additions & 3 deletions cint/reflex/python/genreflex/gendict.py
Original file line number Diff line number Diff line change
Expand Up @@ -2654,6 +2654,8 @@ def ClassDefImplementation(selclasses, self) :
returnValue += '#endif\n'
returnValue += '#include "TClass.h"\n'
returnValue += '#include "TMemberInspector.h"\n'
returnValue += '#include "TInterpreter.h"\n'
returnValue += '#include "TVirtualMutex.h"\n'
returnValue += '#include "RtypesImp.h"\n' # for GenericShowMembers etc
returnValue += '#include "TIsAProxy.h"\n'
haveClassDef = 0
Expand Down Expand Up @@ -2725,8 +2727,11 @@ def ClassDefImplementation(selclasses, self) :
specclname = clname

returnValue += template + 'TClass* ' + specclname + '::Class() {\n'
returnValue += ' if (!fgIsA)\n'
returnValue += ' fgIsA = TClass::GetClass("' + clname[2:] + '");\n'
returnValue += ' if (!fgIsA) {\n'
returnValue += ' R__LOCKGUARD2(gCINTMutex);'
returnValue += ' if (!fgIsA)\n'
returnValue += ' fgIsA = TClass::GetClass("' + clname[2:] + '");\n'
returnValue += ' }\n'
returnValue += ' return fgIsA;\n'
returnValue += '}\n'
returnValue += template + 'const char * ' + specclname + '::Class_Name() {return "' + clname[2:] + '";}\n'
Expand Down Expand Up @@ -2814,7 +2819,11 @@ def ClassDefImplementation(selclasses, self) :
returnValue += ' b.WriteClassBuffer(' + clname + '::Class(),this);\n'
returnValue += ' }\n'
returnValue += '}\n'
returnValue += template + 'TClass* ' + specclname + '::fgIsA = 0;\n'
#must strip of leading '::' to avoid ambiguity with embedded type in atomic_TClass_ptr
if len(specclname) > 2:
if specclname[:2] == '::':
specclname = specclname[2:]
returnValue += template + 'atomic_TClass_ptr ' + specclname + '::fgIsA(0);\n'
returnValue += namespacelevel * '}' + '\n'
elif derivesFromTObject :
# no fgIsA etc members but derives from TObject!
Expand Down
2 changes: 1 addition & 1 deletion config/Makefile.linux
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ COMPILER = gnu

# Linker:
LD = g++
LDFLAGS = -m32 $(OPT) $(EXTRA_LDFLAGS) -Wl,--no-undefined -Wl,--as-needed
LDFLAGS = -m32 -Wl,--hash-style=gnu $(OPT) $(EXTRA_LDFLAGS)
SOFLAGS = -shared -Wl,-soname,
SOEXT = so

Expand Down
7 changes: 5 additions & 2 deletions config/Makefile.linuxarm
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ else
OPT = $(OPTFLAGS)
NOOPT =
endif
ifeq ($(CXX11),yes)
CXX11FLAGS = -std=c++11 -Wno-deprecated-declarations
endif

# Compiler:
CXX = g++
CC = gcc
CXXFLAGS = -Wall -fsigned-char -fPIC $(EXTRA_CXXFLAGS)
CXXFLAGS = -Wall -fsigned-char -fPIC $(EXTRA_CXXFLAGS) $(CXX11FLAGS)
CFLAGS = -Wall -fsigned-char -fPIC $(EXTRA_CFLAGS)
CINTCXXFLAGS = -Wall -fsigned-char -fPIC $(EXTRA_CXXFLAGS) \
CINTCXXFLAGS = -Wall -fsigned-char -fPIC $(EXTRA_CXXFLAGS) $(CXX11FLAGS) \
-DG__REGEXP -DG__UNIX -DG__SHAREDLIB \
-DG__OSFDLL -DG__ROOT -DG__REDIRECTIO
CINTCFLAGS = -Wall -fsigned-char -fPIC $(EXTRA_CFLAGS) \
Expand Down
2 changes: 1 addition & 1 deletion config/Makefile.linuxx8664gcc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ COMPILER = gnu

# Linker:
LD = g++
LDFLAGS = -m64 $(OPT) $(EXTRA_LDFLAGS) -Wl,--no-undefined -Wl,--as-needed
LDFLAGS = -m64 -Wl,--hash-style=gnu $(OPT) $(EXTRA_LDFLAGS)
SOFLAGS = -shared -Wl,-soname,
SOEXT = so

Expand Down
21 changes: 12 additions & 9 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -380,14 +380,14 @@ check_libcompat() {

case $arch in
macosx)
logmsg " lipo -info $chklibcompat | grep ' i386'"
if lipo -info $chklibcompat | grep ' i386' > /dev/null 2>& 1 ; then
logmsg " otool -fhv $chklibcompat | grep -i ' i386'"
if otool -fhv $chklibcompat | grep -i ' i386' > /dev/null 2>& 1 ; then
ret=1
fi
;;
macosx64)
logmsg " lipo -info $chklibcompat | grep ' x86_64'"
if lipo -info $chklibcompat | grep ' x86_64' > /dev/null 2>& 1 ; then
logmsg " otool -fhv $chklibcompat | grep -i ' x86_64'"
if otool -fhv $chklibcompat | grep -i ' x86_64' > /dev/null 2>& 1 ; then
ret=1
fi
;;
Expand Down Expand Up @@ -2851,7 +2851,7 @@ result "$enable_builtin_pcre"
#
if test "x$enable_builtin_zlib" = "xno" ; then
check_header "zlib.h" "" \
$ZLIB ${ZLIB:+$ZLIB/include} \
$ZLIB_ROOT/include $ZLIB ${ZLIB:+$ZLIB/include} \
${finkdir:+$finkdir/include} \
/usr/local/include /usr/include/zlib /usr/local/include/zlib \
/opt/zlib/include /usr/include
Expand All @@ -2863,7 +2863,7 @@ if test "x$enable_builtin_zlib" = "xno" ; then
fi

check_library "libz" "$enable_shared" "" \
$ZLIB ${ZLIB:+$ZLIB/lib} \
$ZLIB_ROOT/lib $ZLIB ${ZLIB:+$ZLIB/lib} \
/usr/local/zlib/lib /usr/local/lib \
/usr/lib/zlib /usr/local/lib/zlib /usr/zlib/lib /usr/lib \
/usr/zlib /usr/local/zlib /opt/zlib /opt/zlib/lib
Expand Down Expand Up @@ -4398,20 +4398,20 @@ if test ! "x$enable_asimage" = "xno" ; then
# for a system library, then see if we have various headers needed.
if test "x$enable_builtin_afterimage" = "xyes" && test ! "x$enable_cocoa" = "xyes"; then
check_header "jpeglib.h" "" \
$ASIMAGE ${ASIMAGE:+$ASIMAGE/include} \
$LIBJPG_ROOT/include $ASIMAGE ${ASIMAGE:+$ASIMAGE/include} \
${finkdir:+$finkdir/include} \
/usr/local/include /usr/include /opt/include
asjpegincdir=$found_dir
check_header "png.h" "" \
$ASIMAGE ${ASIMAGE:+$ASIMAGE/include} \
$LIBPNG_ROOT/include $ASIMAGE ${ASIMAGE:+$ASIMAGE/include} \
${ASPNG:+$ASPNG/include} \
${finkdir:+$finkdir/include} \
/usr/local/include /usr/X11/include /usr/include \
/usr/local/include/libpng /opt/include
aspngincdir=$found_dir
if test ! "x$enable_astiff" = "xno" ; then
check_header "tiffio.h" "" \
$ASIMAGE ${ASIMAGE:+$ASIMAGE/include} \
$LIBTIFF_ROOT/include $ASIMAGE ${ASIMAGE:+$ASIMAGE/include} \
${finkdir:+$finkdir/include} \
/usr/local/include /usr/include /opt/include
astiffincdir=$found_dir
Expand All @@ -4427,11 +4427,14 @@ if test ! "x$enable_asimage" = "xno" ; then
# add libpng which needs libz
if test ! "x$enable_astiff" = "xno" ; then
aslibs="libjpeg libtiff libz libpng"
extra_libtiff_path=$LIBTIFF_ROOT/lib
else
aslibs="libjpeg libz libpng"
extra_libtiff_path=
fi
for k in $aslibs ; do
check_library $k "$enable_shared" "" \
$extra_libtiff_path $LIBJPG_ROOT/lib $LIBPNG_ROOT/lib $ZLIB_ROOT/lib \
$ASIMAGE ${ASIMAGE:+$ASIMAGE/lib} ${ASPNG:+$ASPNG/lib} \
${finkdir:+$finkdir/lib} \
/usr/local/lib /usr/X11/lib /usr/lib /opt/lib
Expand Down
13 changes: 10 additions & 3 deletions core/base/inc/Rtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
#include <string.h>
#include <snprintf.h> // part of stdio.h on systems that have it
#include <strlcpy.h> // part of string.h on systems that have it

#if __cplusplus > 199711L
#include <atomic>
#endif


//---- forward declared class types --------------------------------------------
Expand Down Expand Up @@ -268,12 +270,17 @@ namespace ROOT {
#include "TGenericClassInfo.h"
#endif

#if __cplusplus > 199711L
typedef std::atomic<TClass*> atomic_TClass_ptr;
#else
typedef TClass* atomic_TClass_ptr;
#endif
// Common part of ClassDef definition.
// DeclFileLine() is not part of it since CINT uses that as trigger for
// the class comment string.
#define _ClassDef_(name,id) \
private: \
static TClass *fgIsA; \
static atomic_TClass_ptr fgIsA; \
public: \
static TClass *Class(); \
static const char *Class_Name(); \
Expand All @@ -290,7 +297,7 @@ public: \
// Version without any virtual functions.
#define _ClassDefNV_(name,id) \
private: \
static TClass *fgIsA; \
static atomic_TClass_ptr fgIsA; \
public: \
static TClass *Class(); \
static const char *Class_Name(); \
Expand Down
4 changes: 2 additions & 2 deletions core/base/inc/TROOT.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ friend class TCintWithCling;
Long_t ProcessLine(const char *line, Int_t *error = 0);
Long_t ProcessLineSync(const char *line, Int_t *error = 0);
Long_t ProcessLineFast(const char *line, Int_t *error = 0);
Bool_t ReadingObject() const { /* Deprecated (will be removed in next release) */ return fReadingObject; }
Bool_t ReadingObject() const;
void RefreshBrowsers();
void RemoveClass(TClass *);
void Reset(Option_t *option="");
Expand All @@ -258,7 +258,7 @@ friend class TCintWithCling;
void SetEscape(Bool_t flag = kTRUE) { fEscape = flag; }
void SetLineIsProcessing() { fLineIsProcessing++; }
void SetLineHasBeenProcessed() { if (fLineIsProcessing) fLineIsProcessing--; }
void SetReadingObject(Bool_t flag = kTRUE) { fReadingObject = flag; }
void SetReadingObject(Bool_t flag = kTRUE);
void SetMustClean(Bool_t flag = kTRUE) { fMustClean=flag; }
void SetSelectedPrimitive(const TObject *obj) { fPrimitive = obj; }
void SetSelectedPad(TVirtualPad *pad) { fSelectPad = pad; }
Expand Down
13 changes: 5 additions & 8 deletions core/base/inc/TStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ typedef char *(*ReAllocCharFun_t)(char*, size_t, size_t);
class TStorage {

private:
static ULong_t fgHeapBegin; // begin address of heap
static ULong_t fgHeapEnd; // end address of heap
static size_t fgMaxBlockSize; // largest block allocated
static FreeHookFun_t fgFreeHook; // function called on free
static void *fgFreeHookData; // data used by this function
static ReAllocFun_t fgReAllocHook; // custom ReAlloc
static ReAllocCFun_t fgReAllocCHook; // custom ReAlloc with length check
static Bool_t fgHasCustomNewDelete; // true if using ROOT's new/delete
static const UInt_t kObjectAllocMemValue = 0x99999999;
// magic number for ObjectAlloc

public:
virtual ~TStorage() { }
Expand Down Expand Up @@ -77,16 +77,13 @@ class TStorage {
static void AddToHeap(ULong_t begin, ULong_t end);
static Bool_t IsOnHeap(void *p);

static Bool_t FilledByObjectAlloc(UInt_t* member);

ClassDef(TStorage,0) //Storage manager class
};

#ifndef WIN32
inline void TStorage::AddToHeap(ULong_t begin, ULong_t end)
{ if (begin < fgHeapBegin) fgHeapBegin = begin;
if (end > fgHeapEnd) fgHeapEnd = end; }

inline Bool_t TStorage::IsOnHeap(void *p)
{ return (ULong_t)p >= fgHeapBegin && (ULong_t)p < fgHeapEnd; }
inline Bool_t TStorage::FilledByObjectAlloc(UInt_t *member) { return *member == kObjectAllocMemValue; }

inline size_t TStorage::GetMaxBlockSize() { return fgMaxBlockSize; }

Expand Down
Loading