@@ -120,24 +120,23 @@ void Jrd::Attachment::destroy(Attachment* const attachment)
120120 sAtt ->manualUnlock (attachment->att_flags );
121121 }
122122
123- thread_db* tdbb = JRD_get_thread_data ();
124-
125- jrd_tra* sysTransaction = attachment->getSysTransaction ();
126- if (sysTransaction)
127- {
128- // unwind any active system requests
129- while (sysTransaction->tra_requests )
130- EXE_unwind (tdbb, sysTransaction->tra_requests );
131-
132- jrd_tra::destroy (NULL , sysTransaction);
133- }
134-
135123 Database* const dbb = attachment->att_database ;
136124 {
137125 // context scope is needed here for correct GC of hazard pointers
138126 ThreadContextHolder tdbb (dbb, attachment);
139127
128+ jrd_tra* sysTransaction = attachment->getSysTransaction ();
129+ if (sysTransaction)
130+ {
131+ // unwind any active system requests
132+ while (sysTransaction->tra_requests )
133+ EXE_unwind (tdbb, sysTransaction->tra_requests );
134+
135+ jrd_tra::destroy (NULL , sysTransaction);
136+ }
137+
140138 attachment->att_delayed_delete .garbageCollect (HazardDelayedDelete::GarbageCollectMethod::GC_FORCE);
139+ HZ_DEB (fprintf (stderr, " Attachment::destroy=>delayedDelete to DBB\n " ));
141140 dbb->dbb_delayed_delete .delayedDelete (attachment->att_delayed_delete .getHazardPointers ());
142141 }
143142
@@ -236,6 +235,8 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
236235 att_active_snapshots(*pool),
237236 att_statements(*pool),
238237 att_requests(*pool),
238+ att_internal(*pool),
239+ att_dyn_req(*pool),
239240 att_lock_owner_id(Database::getLockOwnerId()),
240241 att_backup_state_counter(0 ),
241242 att_stats(*pool),
@@ -273,7 +274,10 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
273274 att_initial_options(*pool),
274275 att_provider(provider),
275276 att_delayed_delete(*dbb->dbb_permanent, *pool)
276- { }
277+ {
278+ att_internal.grow (irq_MAX);
279+ att_dyn_req.grow (drq_MAX);
280+ }
277281
278282
279283Jrd::Attachment::~Attachment ()
@@ -624,8 +628,6 @@ void Jrd::Attachment::initLocks(thread_db* tdbb)
624628
625629void Jrd::Attachment::releaseLocks (thread_db* tdbb)
626630{
627- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! to database att_mdc.releaseLocks(tdbb);
628-
629631 // Release the DSQL cache locks
630632
631633 DSqlCache::Accessor accessor (&att_dsql_cache);
@@ -915,3 +917,53 @@ int Attachment::blockingAstReplSet(void* ast_object)
915917
916918 return 0 ;
917919}
920+
921+ void Attachment::cacheRequest (InternalRequest which, USHORT id, Statement* stmt)
922+ {
923+ if (which == IRQ_REQUESTS)
924+ att_internal[id] = stmt;
925+ else if (which == DYN_REQUESTS)
926+ att_dyn_req[id] = stmt;
927+ else
928+ {
929+ fb_assert (false );
930+ }
931+ }
932+
933+ // Find an inactive incarnation of a system request. If necessary, clone it.
934+ Jrd::Request* Attachment::findSystemRequest (thread_db* tdbb, USHORT id, InternalRequest which)
935+ {
936+ static const int MAX_RECURSION = 100 ;
937+
938+ // If the request hasn't been compiled or isn't active, there're nothing to do.
939+
940+ // Database::CheckoutLockGuard guard(this, dbb_cmp_clone_mutex);
941+
942+ fb_assert (which == IRQ_REQUESTS || which == DYN_REQUESTS);
943+
944+ Statement* statement = (which == IRQ_REQUESTS ? att_internal[id] : att_dyn_req[id]);
945+
946+ if (!statement)
947+ return NULL ;
948+
949+ // Look for requests until we find one that is available.
950+
951+ for (int n = 0 ;; ++n)
952+ {
953+ if (n > MAX_RECURSION)
954+ {
955+ ERR_post (Arg::Gds (isc_no_meta_update) <<
956+ Arg::Gds (isc_req_depth_exceeded) << Arg::Num (MAX_RECURSION));
957+ // Msg363 "request depth exceeded. (Recursive definition?)"
958+ }
959+
960+ Request* clone = statement->getRequest (tdbb, n);
961+
962+ if (!(clone->req_flags & (req_active | req_reserved)))
963+ {
964+ clone->req_flags |= req_reserved;
965+ return clone;
966+ }
967+ }
968+ }
969+
0 commit comments