Skip to content

Commit 832a384

Browse files
committed
const-correctness when working with shared formats + better locking logic in getFormat()
1 parent dd17ca6 commit 832a384

11 files changed

Lines changed: 50 additions & 34 deletions

File tree

src/dsql/DdlNodes.epp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9156,7 +9156,7 @@ void RelationNode::getArrayDesc(thread_db* tdbb, const TEXT* field_name, Ods::In
91569156
}
91579157

91589158

9159-
Format* RelationNode::makeFormat(thread_db* tdbb, jrd_tra* transaction, Cached::Relation* relation,
9159+
const Format* RelationNode::makeFormat(thread_db* tdbb, jrd_tra* transaction, Cached::Relation* relation,
91609160
USHORT* version, TemporaryField* stack)
91619161
{
91629162
/**************************************
@@ -9206,6 +9206,8 @@ Format* RelationNode::makeFormat(thread_db* tdbb, jrd_tra* transaction, Cached::
92069206
fb_assert(false);
92079207
}
92089208

9209+
// Single thread write access to formats in relation is guaranteed here by metadata cache
9210+
92099211
Format* format = Format::newFormat(relation->getPool(), count + 1);
92109212
format->fmt_version = version ? *version : 0;
92119213

@@ -9277,10 +9279,10 @@ Format* RelationNode::makeFormat(thread_db* tdbb, jrd_tra* transaction, Cached::
92779279

92789280
format->fmt_length = offset;
92799281

9280-
Format* old_format;
9282+
const Format* old_format;
92819283
if (!(relation->rel_flags & REL_temp_ltt) &&
92829284
format->fmt_version &&
9283-
(old_format = MET_format(tdbb, relation, (format->fmt_version - 1))) &&
9285+
(old_format = relation->getFormat(tdbb, (format->fmt_version - 1))) &&
92849286
(*old_format == *format))
92859287
{
92869288
delete format;

src/dsql/DdlNodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,7 @@ class RelationNode : public DdlNode
17161716
public:
17171717
static void makeVersion(thread_db* tdbb, jrd_tra* transaction, const QualifiedName& relName);
17181718
static void raiseTooManyVersionsError(const int obj_type, const QualifiedName& obj_name);
1719-
static Format* makeFormat(thread_db* tdbb, jrd_tra* transaction, Cached::Relation* relation,
1719+
static const Format* makeFormat(thread_db* tdbb, jrd_tra* transaction, Cached::Relation* relation,
17201720
USHORT* version, TemporaryField* stack);
17211721

17221722
private:

src/jrd/ExtEngineManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1808,7 +1808,7 @@ void ExtEngineManager::makeTrigger(thread_db* tdbb, CompilerScratch* csb, Jrd::T
18081808
MsgMetadata* fieldsMsg = FB_NEW MsgMetadata;
18091809
metadata->triggerFields = fieldsMsg;
18101810

1811-
Format* relFormat = relation->rel_current_format;
1811+
auto* relFormat = relation->rel_current_format;
18121812

18131813
for (FB_SIZE_T i = 0; i < relation->rel_fields->count(); ++i)
18141814
{

src/jrd/Relation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ Lock* RelationPermanent::createLock(thread_db* tdbb, MemoryPool& pool, lck_t lck
765765

766766
void RelationPermanent::addFormat(Format* fmt)
767767
{
768-
MutexLockGuard g(rel_formats_grow, FB_FUNCTION);
768+
MutexLockGuard guard(rel_formats_grow, FB_FUNCTION);
769769

770770
rel_formats.grow(fmt->fmt_version + 1, true);
771771
rel_formats.writeAccessor()->value(fmt->fmt_version) = fmt;
@@ -1153,7 +1153,7 @@ const Format* jrd_rel::currentFormat(thread_db* tdbb)
11531153
if (!tdbb)
11541154
tdbb = JRD_get_thread_data();
11551155

1156-
rel_current_format = MET_format(tdbb, getPermanent(), rel_current_fmt);
1156+
rel_current_format = getPermanent()->getFormat(tdbb, rel_current_fmt);
11571157

11581158
return rel_current_format;
11591159
}

src/jrd/Relation.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ class jrd_rel final : public ObjectBase
645645

646646
public:
647647
USHORT rel_current_fmt; // Current format number
648-
Format* rel_current_format; // Current record format
648+
const Format* rel_current_format; // Current record format
649649
USHORT rel_dbkey_length; // RDB$DBKEY length
650650

651651
vec<jrd_fld*>* rel_fields; // vector of field blocks
@@ -984,7 +984,7 @@ class RelationPermanent : public Firebird::PermanentStorage
984984
typedef SharedReadVector<Format*, 16> Formats;
985985

986986
private:
987-
SharedReadVector<Format*, 16> rel_formats; // Known record formats
987+
Formats rel_formats; // Known record formats
988988
Firebird::Mutex rel_formats_grow; // Mutex to grow rel_formats
989989

990990
public:
@@ -994,6 +994,7 @@ class RelationPermanent : public Firebird::PermanentStorage
994994
}
995995

996996
void addFormat(Format* fmt);
997+
const Format* getFormat(thread_db* tdbb, USHORT );
997998

998999
Indices rel_indices; // Active indices
9991000
QualifiedName rel_name; // ascii relation name

src/jrd/evl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ bool EVL_field(jrd_rel* relation, Record* record, USHORT id, dsc* desc)
426426
break;
427427
}
428428

429-
format = MET_format(tdbb, relation->getPermanent(), format->fmt_version + 1);
429+
format = relation->getPermanent()->getFormat(tdbb, format->fmt_version + 1);
430430
fb_assert(format);
431431
}
432432

src/jrd/met.epp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ void MET_error(const TEXT* string, ...)
949949
Arg::Gds(isc_random) << Arg::Str(s));
950950
}
951951

952-
Format* MET_format(thread_db* tdbb, RelationPermanent* relation, USHORT number)
952+
const Format* RelationPermanent::getFormat(thread_db* tdbb, USHORT number)
953953
{
954954
/**************************************
955955
*
@@ -965,23 +965,30 @@ Format* MET_format(thread_db* tdbb, RelationPermanent* relation, USHORT number)
965965
Attachment* attachment = tdbb->getAttachment();
966966
Database* dbb = tdbb->getDatabase();
967967

968-
Format* format;
969-
auto formats = relation->getFormats();
970-
if ((number < formats->getCount()) && (format = formats->value(number)))
971-
{
972-
return format;
968+
{ // scope
969+
auto formats = getFormats();
970+
if ((number < formats->getCount()) && formats->value(number))
971+
return formats->value(number);
972+
}
973+
974+
MutexLockGuard guard(rel_formats_grow, FB_FUNCTION);
975+
976+
{ // scope
977+
auto formats = getFormats();
978+
if ((number < formats->getCount()) && formats->value(number))
979+
return formats->value(number);
973980
}
974981

975-
// System relations don't have their formats stored inside RDB$FORMATS,
982+
// System relations and LTT don't have their formats stored inside RDB$FORMATS,
976983
// so it's absolutely pointless trying to find one there
977-
fb_assert(!relation->isSystem());
978-
fb_assert(!(relation->rel_flags & REL_temp_ltt));
984+
fb_assert(!isSystem());
985+
fb_assert(!(rel_flags & REL_temp_ltt));
979986

980-
format = NULL;
987+
Format* format = NULL;
981988
AutoCacheRequest request(tdbb, irq_r_format, IRQ_REQUESTS);
982989

983990
FOR(REQUEST_HANDLE request)
984-
X IN RDB$FORMATS WITH X.RDB$RELATION_ID EQ relation->getId() AND
991+
X IN RDB$FORMATS WITH X.RDB$RELATION_ID EQ getId() AND
985992
X.RDB$FORMAT EQ number
986993
{
987994
blb* blob = blb::open(tdbb, attachment->getSysTransaction(), &X.RDB$DESCRIPTOR);
@@ -993,7 +1000,7 @@ Format* MET_format(thread_db* tdbb, RelationPermanent* relation, USHORT number)
9931000
unsigned bufferPos = 2;
9941001
USHORT count = buffer[0] | (buffer[1] << 8);
9951002

996-
format = Format::newFormat(relation->getPool(), count);
1003+
format = Format::newFormat(getPool(), count);
9971004

9981005
Array<Ods::Descriptor> odsDescs;
9991006
Ods::Descriptor* odsDesc = odsDescs.getBuffer(count);
@@ -1025,20 +1032,20 @@ Format* MET_format(thread_db* tdbb, RelationPermanent* relation, USHORT number)
10251032

10261033
desc.dsc_address = tmpArray.getBuffer(desc.dsc_length, false);
10271034
memcpy(desc.dsc_address, p, desc.dsc_length);
1028-
EVL_make_value(tdbb, &desc, &format->fmt_defaults[offset], &relation->getPool());
1035+
EVL_make_value(tdbb, &desc, &format->fmt_defaults[offset], &getPool());
10291036

10301037
p += desc.dsc_length;
10311038
}
10321039
}
10331040
END_FOR
10341041

1035-
if (!format)
1036-
format = Format::newFormat(relation->getPool());
1037-
1038-
format->fmt_version = number;
1042+
if (format)
1043+
{
1044+
format->fmt_version = number;
10391045

1040-
// Link the format block into the world
1041-
relation->addFormat(format);
1046+
// Link the format block into the world
1047+
addFormat(format);
1048+
}
10421049

10431050
return format;
10441051
}
@@ -3396,7 +3403,7 @@ ScanResult jrd_rel::scan(thread_db* tdbb, ObjectBase::Flag& flags)
33963403

33973404
delete csb;
33983405

3399-
rel_current_format = MET_format(tdbb, rel_perm, rel_current_fmt);
3406+
rel_current_format = rel_perm->getFormat(tdbb, rel_current_fmt);
34003407
dependencies = false;
34013408

34023409
if (rel_fields)

src/jrd/met_proto.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ Jrd::Cached::Relation* MET_change_fields(Jrd::thread_db*, Jrd::jrd_tra*, const d
9090
void MET_delete_dependencies(Jrd::thread_db*, const Jrd::QualifiedName&, int);
9191
void MET_delete_shadow(Jrd::thread_db*, USHORT);
9292
void MET_error(const TEXT*, ...);
93-
Jrd::Format* MET_format(Jrd::thread_db*, Jrd::RelationPermanent*, USHORT);
9493
bool MET_get_char_coll_subtype_info(Jrd::thread_db*, USHORT, Jrd::SubtypeInfo* info);
9594
Jrd::DmlNode* MET_get_dependencies(Jrd::thread_db*, Jrd::jrd_rel*, const UCHAR*, const ULONG,
9695
Jrd::CompilerScratch*, Jrd::bid*, Jrd::Statement**,

src/jrd/replication/Applier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ const Format* Applier::findFormat(thread_db* tdbb, jrd_rel* relation, ULONG leng
12031203
auto format = relation->currentFormat(tdbb);
12041204

12051205
while (format->fmt_length != length && format->fmt_version)
1206-
format = MET_format(tdbb, relation->getPermanent(), format->fmt_version - 1);
1206+
format = relation->getPermanent()->getFormat(tdbb, format->fmt_version - 1);
12071207

12081208
if (format->fmt_length != length)
12091209
{

src/jrd/validation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2791,7 +2791,7 @@ Validation::RTN Validation::walk_record(jrd_rel* relation, const rhd* header, US
27912791
length -= RHD_SIZE;
27922792
}
27932793

2794-
const auto format = MET_format(vdr_tdbb, getPermanent(relation), header->rhd_format);
2794+
const auto format = relation->getPermanent()->getFormat(vdr_tdbb, header->rhd_format);
27952795
auto remainingLength = format->fmt_length;
27962796

27972797
auto calculateLength = [remainingLength](ULONG length, const UCHAR* data, bool notPacked)

0 commit comments

Comments
 (0)